diff --git a/.github/workflows/csv-coverage-pr-artifacts.yml b/.github/workflows/csv-coverage-pr-artifacts.yml index 201eea5c073..8b89b9b22c1 100644 --- a/.github/workflows/csv-coverage-pr-artifacts.yml +++ b/.github/workflows/csv-coverage-pr-artifacts.yml @@ -6,6 +6,8 @@ on: - '.github/workflows/csv-coverage-pr-comment.yml' - '*/ql/src/**/*.ql' - '*/ql/src/**/*.qll' + - '*/ql/lib/**/*.ql' + - '*/ql/lib/**/*.qll' - 'misc/scripts/library-coverage/*.py' # input data files - '*/documentation/library-coverage/cwe-sink.csv' diff --git a/.github/workflows/csv-coverage-update.yml b/.github/workflows/csv-coverage-update.yml index 10834bdd36a..eb227ec844f 100644 --- a/.github/workflows/csv-coverage-update.yml +++ b/.github/workflows/csv-coverage-update.yml @@ -8,7 +8,7 @@ on: jobs: update: name: Update framework coverage report - if: github.event.repository.fork == false + if: github.repository == 'github/codeql' runs-on: ubuntu-latest steps: diff --git a/.gitignore b/.gitignore index 0951496d45c..bf37ce08333 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,6 @@ /codeql/ csharp/extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json + +# Avoid committing cached package components +.codeql diff --git a/README.md b/README.md index 9012e83f10d..b1d5b82cb31 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ This open source repository contains the standard CodeQL libraries and queries t ## How do I learn CodeQL and run queries? -There is [extensive documentation](https://help.semmle.com/QL/learn-ql/) on getting started with writing CodeQL. -You can use the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com or the [CodeQL for Visual Studio Code](https://help.semmle.com/codeql/codeql-for-vscode.html) extension to try out your queries on any open source project that's currently being analyzed. +There is [extensive documentation](https://codeql.github.com/docs/) on getting started with writing CodeQL. +You can use the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com or the [CodeQL for Visual Studio Code](https://codeql.github.com/docs/codeql-for-visual-studio-code/) extension to try out your queries on any open source project that's currently being analyzed. ## Contributing diff --git a/cpp/change-notes/2021-06-10-cleartext-transmission.md b/cpp/change-notes/2021-06-10-cleartext-transmission.md new file mode 100644 index 00000000000..ce6debf1407 --- /dev/null +++ b/cpp/change-notes/2021-06-10-cleartext-transmission.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* A new query (`cpp/cleartext-transmission`) has been added. This is similar to the `cpp/cleartext-storage-file`, `cpp/cleartext-storage-buffer` and `cpp/cleartext-storage-database` queries but looks for cases where sensitive information is most likely transmitted over a network. diff --git a/cpp/change-notes/2021-06-22-sql-tainted.md b/cpp/change-notes/2021-06-22-sql-tainted.md new file mode 100644 index 00000000000..004f96ce25b --- /dev/null +++ b/cpp/change-notes/2021-06-22-sql-tainted.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The 'Uncontrolled data in SQL query' (cpp/sql-injection) query now supports the `libpqxx` library. \ No newline at end of file diff --git a/cpp/change-notes/2021-08-31-range-analysis-upper-bound.md b/cpp/change-notes/2021-08-31-range-analysis-upper-bound.md new file mode 100644 index 00000000000..f7ea800f719 --- /dev/null +++ b/cpp/change-notes/2021-08-31-range-analysis-upper-bound.md @@ -0,0 +1,4 @@ +lgtm,codescanning +* The `SimpleRangeAnalysis` library includes information from the + immediate guard for determining the upper bound of a stack + variable for improved accuracy. diff --git a/cpp/change-notes/2021-09-13-overflow-static.md b/cpp/change-notes/2021-09-13-overflow-static.md new file mode 100644 index 00000000000..5a9ef395815 --- /dev/null +++ b/cpp/change-notes/2021-09-13-overflow-static.md @@ -0,0 +1,4 @@ +lgtm,codescanning +* The `memberMayBeVarSize` predicate considers more fields to be variable size. + As a result, the "Static buffer overflow" query (cpp/static-buffer-overflow) + produces fewer false positives. diff --git a/cpp/change-notes/2021-09-27-command-line-injection.md b/cpp/change-notes/2021-09-27-command-line-injection.md new file mode 100644 index 00000000000..53ce1fd1dbe --- /dev/null +++ b/cpp/change-notes/2021-09-27-command-line-injection.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The "Uncontrolled data used in OS command" (`cpp/command-line-injection`) query has been enhanced to reduce false positive results and its `@precision` increased to `high` \ No newline at end of file diff --git a/cpp/change-notes/2021-09-27-overflow-static.md b/cpp/change-notes/2021-09-27-overflow-static.md new file mode 100644 index 00000000000..e28ba4970ce --- /dev/null +++ b/cpp/change-notes/2021-09-27-overflow-static.md @@ -0,0 +1,3 @@ +lgtm,codescanning +* Increase precision to high for the "Static buffer overflow" query + (`cpp/static-buffer-overflow`). This means the query is run and displayed by default on Code Scanning and LGTM. diff --git a/cpp/ql/lib/semmle/code/cpp/File.qll b/cpp/ql/lib/semmle/code/cpp/File.qll index b2d933686d7..f486dd8d3c5 100644 --- a/cpp/ql/lib/semmle/code/cpp/File.qll +++ b/cpp/ql/lib/semmle/code/cpp/File.qll @@ -38,7 +38,7 @@ class Container extends Locatable, @container { * DEPRECATED: Use `getLocation` instead. * Gets a URL representing the location of this container. * - * For more information see [Providing URLs](https://help.semmle.com/QL/learn-ql/ql/locations.html#providing-urls). + * For more information see [Providing URLs](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/#providing-urls). */ deprecated string getURL() { none() } // overridden by subclasses @@ -171,7 +171,7 @@ class Container extends Locatable, @container { * To get the full path, use `getAbsolutePath`. */ class Folder extends Container, @folder { - override string getAbsolutePath() { folders(underlyingElement(this), result, _) } + override string getAbsolutePath() { folders(underlyingElement(this), result) } override Location getLocation() { result.getContainer() = this and @@ -190,7 +190,7 @@ class Folder extends Container, @folder { * DEPRECATED: use `getAbsolutePath` instead. * Gets the name of this folder. */ - deprecated string getName() { folders(underlyingElement(this), result, _) } + deprecated string getName() { folders(underlyingElement(this), result) } /** * DEPRECATED: use `getAbsolutePath` instead. @@ -208,17 +208,7 @@ class Folder extends Container, @folder { * DEPRECATED: use `getBaseName` instead. * Gets the last part of the folder name. */ - deprecated string getShortName() { - exists(string longnameRaw, string longname | - folders(underlyingElement(this), _, longnameRaw) and - longname = longnameRaw.replaceAll("\\", "/") - | - exists(int index | - result = longname.splitAt("/", index) and - not exists(longname.splitAt("/", index + 1)) - ) - ) - } + deprecated string getShortName() { result = this.getBaseName() } /** * DEPRECATED: use `getParentContainer` instead. @@ -242,7 +232,7 @@ class Folder extends Container, @folder { * `getStem` and `getExtension`. To get the full path, use `getAbsolutePath`. */ class File extends Container, @file { - override string getAbsolutePath() { files(underlyingElement(this), result, _, _, _) } + override string getAbsolutePath() { files(underlyingElement(this), result) } override string toString() { result = Container.super.toString() } @@ -336,7 +326,13 @@ class File extends Container, @file { * for example, for "file.tar.gz", this predicate will have the result * "tar.gz", while `getExtension` will have the result "gz". */ - string getExtensions() { files(underlyingElement(this), _, _, result, _) } + string getExtensions() { + exists(string name, int firstDotPos | + name = this.getBaseName() and + firstDotPos = min([name.indexOf("."), name.length() - 1]) and + result = name.suffix(firstDotPos + 1) + ) + } /** * Gets the short name of this file, that is, the prefix of its base name up @@ -351,7 +347,16 @@ class File extends Container, @file { * for example, for "file.tar.gz", this predicate will have the result * "file", while `getStem` will have the result "file.tar". */ - string getShortName() { files(underlyingElement(this), _, result, _, _) } + string getShortName() { + exists(string name, int firstDotPos | + name = this.getBaseName() and + firstDotPos = min([name.indexOf("."), name.length()]) and + result = name.prefix(firstDotPos) + ) + or + this.getAbsolutePath() = "" and + result = "" + } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/Location.qll b/cpp/ql/lib/semmle/code/cpp/Location.qll index 2a730ea5768..15ae2121255 100644 --- a/cpp/ql/lib/semmle/code/cpp/Location.qll +++ b/cpp/ql/lib/semmle/code/cpp/Location.qll @@ -61,7 +61,7 @@ class Location extends @location { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/cpp/ql/lib/semmle/code/cpp/XML.qll b/cpp/ql/lib/semmle/code/cpp/XML.qll index 5871fed0ddd..4c762f4bf65 100755 --- a/cpp/ql/lib/semmle/code/cpp/XML.qll +++ b/cpp/ql/lib/semmle/code/cpp/XML.qll @@ -24,7 +24,7 @@ class XMLLocatable extends @xmllocatable, TXMLLocatable { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll b/cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll index 88e6a48ff55..2328476d525 100644 --- a/cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll +++ b/cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll @@ -2,53 +2,19 @@ import cpp import semmle.code.cpp.dataflow.DataFlow /** - * Holds if `v` is a member variable of `c` that looks like it might be variable sized in practice. For - * example: + * Holds if `v` is a member variable of `c` that looks like it might be variable sized + * in practice. For example: * ``` * struct myStruct { // c * int amount; * char data[1]; // v * }; * ``` - * This requires that `v` is an array of size 0 or 1, and `v` is the last member of `c`. In addition, - * there must be at least one instance where a `c` pointer is allocated with additional space. For - * example, holds for `c` if it occurs as - * ``` - * malloc(sizeof(c) + 100 * sizeof(char)) - * ``` - * but not if it only ever occurs as - * ``` - * malloc(sizeof(c)) - * ``` + * This requires that `v` is an array of size 0 or 1. */ predicate memberMayBeVarSize(Class c, MemberVariable v) { - exists(int i | - // `v` is the last field in `c` - i = max(int j | c.getCanonicalMember(j) instanceof Field | j) and - v = c.getCanonicalMember(i) and - // v is an array of size at most 1 - v.getUnspecifiedType().(ArrayType).getArraySize() <= 1 - ) and - ( - exists(SizeofOperator so | - // `sizeof(c)` is taken - so.(SizeofTypeOperator).getTypeOperand().getUnspecifiedType() = c or - so.(SizeofExprOperator).getExprOperand().getUnspecifiedType() = c - | - // arithmetic is performed on the result - so.getParent*() instanceof AddExpr - ) - or - exists(AddressOfExpr aoe | - // `&(c.v)` is taken - aoe.getAddressable() = v - ) - or - exists(BuiltInOperationBuiltInOffsetOf oo | - // `offsetof(c, v)` using a builtin - oo.getAChild().(VariableAccess).getTarget() = v - ) - ) + c = v.getDeclaringType() and + v.getUnspecifiedType().(ArrayType).getArraySize() <= 1 } /** diff --git a/cpp/ql/lib/semmle/code/cpp/commons/NullTermination.qll b/cpp/ql/lib/semmle/code/cpp/commons/NullTermination.qll index 6cb366d46ee..ee072fb0ed3 100644 --- a/cpp/ql/lib/semmle/code/cpp/commons/NullTermination.qll +++ b/cpp/ql/lib/semmle/code/cpp/commons/NullTermination.qll @@ -93,6 +93,15 @@ predicate variableMustBeNullTerminated(VariableAccess va) { fc.getArgument(i) = va ) or + // String argument to a formatting function (such as `printf`) + exists(int n, FormatLiteral fl | + fc.(FormattingFunctionCall).getConversionArgument(n) = va and + fl = fc.(FormattingFunctionCall).getFormat() and + fl.getConversionType(n) instanceof PointerType and // `%s`, `%ws` etc + not fl.getConversionType(n) instanceof VoidPointerType and // exclude: `%p` + not fl.hasPrecision(n) // exclude: `%.*s` + ) + or // Call to a wrapper function that requires null termination // (not itself adding a null terminator) exists(Function wrapper, int i, Parameter p, VariableAccess use | diff --git a/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll b/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll index ef5f5511f6d..46ca9ccf009 100644 --- a/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll @@ -253,6 +253,21 @@ class FormattingFunctionCall extends Expr { // format arguments must be known exists(getTarget().(FormattingFunction).getFirstFormatArgumentIndex()) } + + /** + * Gets the argument, if any, to which the output is written. If `isStream` is + * `true`, the output argument is a stream (that is, this call behaves like + * `fprintf`). If `isStream` is `false`, the output argument is a buffer (that + * is, this call behaves like `sprintf`) + */ + Expr getOutputArgument(boolean isStream) { + result = + this.(Call) + .getArgument(this.(Call) + .getTarget() + .(FormattingFunction) + .getOutputParameterIndex(isStream)) + } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/BasicBlocks.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/BasicBlocks.qll index 16947019f54..e235eba355b 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/BasicBlocks.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/BasicBlocks.qll @@ -194,7 +194,7 @@ class BasicBlock extends ControlFlowNodeBase { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). * * Yields no result if this basic block spans multiple source files. */ diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index 5c2dbb30084..4ca06c93362 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index 5c2dbb30084..4ca06c93362 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index 5c2dbb30084..4ca06c93362 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index 5c2dbb30084..4ca06c93362 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll index 728f7b56c42..f43a550af57 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll @@ -786,13 +786,18 @@ private module Cached { } /** - * Holds if the call context `call` either improves virtual dispatch in - * `callable` or if it allows us to prune unreachable nodes in `callable`. + * Holds if the call context `call` improves virtual dispatch in `callable`. */ cached - predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) { + predicate recordDataFlowCallSiteDispatch(DataFlowCall call, DataFlowCallable callable) { reducedViableImplInCallContext(_, callable, call) - or + } + + /** + * Holds if the call context `call` allows us to prune unreachable nodes in `callable`. + */ + cached + predicate recordDataFlowCallSiteUnreachable(DataFlowCall call, DataFlowCallable callable) { exists(Node n | getNodeEnclosingCallable(n) = callable | isUnreachableInCallCached(n, call)) } @@ -846,6 +851,15 @@ private module Cached { TAccessPathFrontSome(AccessPathFront apf) } +/** + * Holds if the call context `call` either improves virtual dispatch in + * `callable` or if it allows us to prune unreachable nodes in `callable`. + */ +predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) { + recordDataFlowCallSiteDispatch(call, callable) or + recordDataFlowCallSiteUnreachable(call, callable) +} + /** * A `Node` at which a cast can occur such that the type should be checked. */ @@ -1222,6 +1236,13 @@ class TypedContent extends MkTypedContent { /** Gets a textual representation of this content. */ string toString() { result = c.toString() } + + /** + * Holds if access paths with this `TypedContent` at their head always should + * be tracked at high precision. This disables adaptive access path precision + * for such access paths. + */ + predicate forceHighPrecision() { forceHighPrecision(c) } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index 5c2dbb30084..4ca06c93362 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll index e64f8277528..986197bb0ce 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll @@ -240,6 +240,12 @@ predicate isUnreachableInCall(Node n, DataFlowCall call) { none() } // stub impl int accessPathLimit() { result = 5 } +/** + * Holds if access paths with `c` at their head always should be tracked at high + * precision. This disables adaptive access path precision for such access paths. + */ +predicate forceHighPrecision(Content c) { none() } + /** The unit type. */ private newtype TUnit = TMkUnit() diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll index 01338eaeff4..2dfd02d14ef 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll @@ -101,7 +101,7 @@ class Node extends TNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll index 49d11a7e3cc..ece55d181bf 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll @@ -4,7 +4,7 @@ private import semmle.code.cpp.ir.dataflow.DataFlow private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil private import semmle.code.cpp.ir.dataflow.DataFlow3 private import semmle.code.cpp.ir.IR -private import semmle.code.cpp.ir.dataflow.internal.DataFlowDispatch as Dispatch +private import semmle.code.cpp.ir.dataflow.ResolveCall private import semmle.code.cpp.controlflow.IRGuards private import semmle.code.cpp.models.interfaces.Taint private import semmle.code.cpp.models.interfaces.DataFlow @@ -355,20 +355,6 @@ predicate taintedIncludingGlobalVars(Expr source, Element tainted, string global */ GlobalOrNamespaceVariable globalVarFromId(string id) { id = result.getQualifiedName() } -/** - * Resolve potential target function(s) for `call`. - * - * If `call` is a call through a function pointer (`ExprCall`) or - * targets a virtual method, simple data flow analysis is performed - * in order to identify target(s). - */ -Function resolveCall(Call call) { - exists(CallInstruction callInstruction | - callInstruction.getAST() = call and - result = Dispatch::viableCallable(callInstruction) - ) -} - /** * Provides definitions for augmenting source/sink pairs with data-flow paths * between them. From a `@kind path-problem` query, import this module in the @@ -479,7 +465,7 @@ module TaintedWithPath { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -550,6 +536,39 @@ module TaintedWithPath { ) } + /** + * Holds if there is flow from `arg` to `out` across a call that can by summarized by the flow + * from `par` to `ret` within it, in the graph of data flow path explanations. + */ + query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) { + DataFlow3::PathGraph::subpaths(arg.(WrapPathNode).inner(), par.(WrapPathNode).inner(), + ret.(WrapPathNode).inner(), out.(WrapPathNode).inner()) + or + // To avoid showing trivial-looking steps, we _replace_ the last node instead + // of adding an edge out of it. + exists(WrapPathNode sinkNode | + DataFlow3::PathGraph::subpaths(arg.(WrapPathNode).inner(), par.(WrapPathNode).inner(), + ret.(WrapPathNode).inner(), sinkNode.inner()) and + out.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode()) + ) + or + // Same for the first node + exists(WrapPathNode sourceNode | + DataFlow3::PathGraph::subpaths(sourceNode.inner(), par.(WrapPathNode).inner(), + ret.(WrapPathNode).inner(), out.(WrapPathNode).inner()) and + sourceNode.inner().getNode() = getNodeForExpr(arg.(InitialPathNode).inner()) + ) + or + // Finally, handle the case where the path goes directly from a source to a + // sink, meaning that they both need to be translated. + exists(WrapPathNode sinkNode, WrapPathNode sourceNode | + DataFlow3::PathGraph::subpaths(sourceNode.inner(), par.(WrapPathNode).inner(), + ret.(WrapPathNode).inner(), sinkNode.inner()) and + sourceNode.inner().getNode() = getNodeForExpr(arg.(InitialPathNode).inner()) and + out.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode()) + ) + } + /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { key = "semmle.label" and val = n.toString() diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/ResolveCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/ResolveCall.qll new file mode 100644 index 00000000000..f25386d3ba8 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/ResolveCall.qll @@ -0,0 +1,23 @@ +/** + * Provides a predicate for non-contextual virtual dispatch and function + * pointer resolution. + */ + +import cpp +private import semmle.code.cpp.ir.ValueNumbering +private import internal.DataFlowDispatch +private import semmle.code.cpp.ir.IR + +/** + * Resolve potential target function(s) for `call`. + * + * If `call` is a call through a function pointer (`ExprCall`) or its target is + * a virtual member function, simple data flow analysis is performed in order + * to identify the possible target(s). + */ +Function resolveCall(Call call) { + exists(CallInstruction callInstruction | + callInstruction.getAST() = call and + result = viableCallable(callInstruction) + ) +} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 5c2dbb30084..4ca06c93362 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index 5c2dbb30084..4ca06c93362 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index 5c2dbb30084..4ca06c93362 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index 5c2dbb30084..4ca06c93362 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll index 728f7b56c42..f43a550af57 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll @@ -786,13 +786,18 @@ private module Cached { } /** - * Holds if the call context `call` either improves virtual dispatch in - * `callable` or if it allows us to prune unreachable nodes in `callable`. + * Holds if the call context `call` improves virtual dispatch in `callable`. */ cached - predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) { + predicate recordDataFlowCallSiteDispatch(DataFlowCall call, DataFlowCallable callable) { reducedViableImplInCallContext(_, callable, call) - or + } + + /** + * Holds if the call context `call` allows us to prune unreachable nodes in `callable`. + */ + cached + predicate recordDataFlowCallSiteUnreachable(DataFlowCall call, DataFlowCallable callable) { exists(Node n | getNodeEnclosingCallable(n) = callable | isUnreachableInCallCached(n, call)) } @@ -846,6 +851,15 @@ private module Cached { TAccessPathFrontSome(AccessPathFront apf) } +/** + * Holds if the call context `call` either improves virtual dispatch in + * `callable` or if it allows us to prune unreachable nodes in `callable`. + */ +predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) { + recordDataFlowCallSiteDispatch(call, callable) or + recordDataFlowCallSiteUnreachable(call, callable) +} + /** * A `Node` at which a cast can occur such that the type should be checked. */ @@ -1222,6 +1236,13 @@ class TypedContent extends MkTypedContent { /** Gets a textual representation of this content. */ string toString() { result = c.toString() } + + /** + * Holds if access paths with this `TypedContent` at their head always should + * be tracked at high precision. This disables adaptive access path precision + * for such access paths. + */ + predicate forceHighPrecision() { forceHighPrecision(c) } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 73bf72a3643..00996a6ebfc 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -466,6 +466,12 @@ predicate isUnreachableInCall(Node n, DataFlowCall call) { none() } // stub impl int accessPathLimit() { result = 5 } +/** + * Holds if access paths with `c` at their head always should be tracked at high + * precision. This disables adaptive access path precision for such access paths. + */ +predicate forceHighPrecision(Content c) { none() } + /** The unit type. */ private newtype TUnit = TMkUnit() diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index bf21249d4ca..9e7a95e010d 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -120,7 +120,7 @@ class Node extends TIRDataFlowNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll index 2f4037d4ec8..c7e61ea2e33 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll @@ -38,5 +38,8 @@ Instruction callOutput(CallInstruction call, FunctionOutput output) { effect.getPrimaryInstruction() = call and output.isParameterDerefOrQualifierObject(effect.getIndex()) ) - // TODO: return value dereference + or + // TODO: modify this when we get return value dereferences + result = call and + output.isReturnValueDeref() } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll index 453838215ff..6f471d8a7e8 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll @@ -821,7 +821,7 @@ class ReturnIndirectionInstruction extends VariableInstruction { * * There are several different copy instructions, depending on the source and destination of the * copy operation: - * - `CopyInstruction` - Copies a register operand to a register result. + * - `CopyValueInstruction` - Copies a register operand to a register result. * - `LoadInstruction` - Copies a memory operand to a register result. * - `StoreInstruction` - Copies a register operand to a memory result. */ @@ -1856,12 +1856,12 @@ class InitializeDynamicAllocationInstruction extends SideEffectInstruction { } /** - * Gets the address of the allocation this instruction is initializing. + * Gets the operand that represents the address of the allocation this instruction is initializing. */ final AddressOperand getAllocationAddressOperand() { result = getAnOperand() } /** - * Gets the operand for the allocation this instruction is initializing. + * Gets the address for the allocation this instruction is initializing. */ final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll index 453838215ff..6f471d8a7e8 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll @@ -821,7 +821,7 @@ class ReturnIndirectionInstruction extends VariableInstruction { * * There are several different copy instructions, depending on the source and destination of the * copy operation: - * - `CopyInstruction` - Copies a register operand to a register result. + * - `CopyValueInstruction` - Copies a register operand to a register result. * - `LoadInstruction` - Copies a memory operand to a register result. * - `StoreInstruction` - Copies a register operand to a memory result. */ @@ -1856,12 +1856,12 @@ class InitializeDynamicAllocationInstruction extends SideEffectInstruction { } /** - * Gets the address of the allocation this instruction is initializing. + * Gets the operand that represents the address of the allocation this instruction is initializing. */ final AddressOperand getAllocationAddressOperand() { result = getAnOperand() } /** - * Gets the operand for the allocation this instruction is initializing. + * Gets the address for the allocation this instruction is initializing. */ final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll index 453838215ff..6f471d8a7e8 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll @@ -821,7 +821,7 @@ class ReturnIndirectionInstruction extends VariableInstruction { * * There are several different copy instructions, depending on the source and destination of the * copy operation: - * - `CopyInstruction` - Copies a register operand to a register result. + * - `CopyValueInstruction` - Copies a register operand to a register result. * - `LoadInstruction` - Copies a memory operand to a register result. * - `StoreInstruction` - Copies a register operand to a memory result. */ @@ -1856,12 +1856,12 @@ class InitializeDynamicAllocationInstruction extends SideEffectInstruction { } /** - * Gets the address of the allocation this instruction is initializing. + * Gets the operand that represents the address of the allocation this instruction is initializing. */ final AddressOperand getAllocationAddressOperand() { result = getAnOperand() } /** - * Gets the operand for the allocation this instruction is initializing. + * Gets the address for the allocation this instruction is initializing. */ final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/Models.qll b/cpp/ql/lib/semmle/code/cpp/models/Models.qll index d5c7f50dde1..3eed4341cce 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/Models.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/Models.qll @@ -33,3 +33,7 @@ private import implementations.Recv private import implementations.Accept private import implementations.Poll private import implementations.Select +private import implementations.MySql +private import implementations.SqLite3 +private import implementations.PostgreSql +private import implementations.System diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/MySql.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/MySql.qll new file mode 100644 index 00000000000..ca5d7020158 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/MySql.qll @@ -0,0 +1,32 @@ +/** + * Provides implementation classes modeling the MySql C API. + * See `semmle.code.cpp.models.Models` for usage information. + */ + +private import semmle.code.cpp.models.interfaces.Sql +private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs + +/** + * The `mysql_query` family of functions from the MySQL C API. + */ +private class MySqlExecutionFunction extends SqlExecutionFunction { + MySqlExecutionFunction() { + this.hasName(["mysql_query", "mysql_real_query", "mysql_real_query_nonblocking"]) + } + + override predicate hasSqlArgument(FunctionInput input) { input.isParameterDeref(1) } +} + +/** + * The `mysql_real_escape_string` family of functions from the MySQL C API. + */ +private class MySqlBarrierFunction extends SqlBarrierFunction { + MySqlBarrierFunction() { + this.hasName(["mysql_real_escape_string", "mysql_real_escape_string_quote"]) + } + + override predicate barrierSqlArgument(FunctionInput input, FunctionOutput output) { + input.isParameterDeref(2) and + output.isParameterDeref(1) + } +} diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/PostgreSql.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/PostgreSql.qll new file mode 100644 index 00000000000..595805f176f --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/PostgreSql.qll @@ -0,0 +1,94 @@ +private import semmle.code.cpp.models.interfaces.Sql +private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs + +private predicate pqxxTransactionSqlArgument(string function, int arg) { + function = "exec" and arg = 0 + or + function = "exec0" and arg = 0 + or + function = "exec1" and arg = 0 + or + function = "exec_n" and arg = 1 + or + function = "exec_params" and arg = 0 + or + function = "exec_params0" and arg = 0 + or + function = "exec_params1" and arg = 0 + or + function = "exec_params_n" and arg = 1 + or + function = "query_value" and arg = 0 + or + function = "stream" and arg = 0 +} + +private predicate pqxxConnectionSqlArgument(string function, int arg) { + function = "prepare" and arg = 1 +} + +private predicate pqxxTransationClassNames(string className, string namespace) { + namespace = "pqxx" and + className in [ + "dbtransaction", "nontransaction", "basic_robusttransaction", "robusttransaction", + "subtransaction", "transaction", "basic_transaction", "transaction_base", "work" + ] +} + +private predicate pqxxConnectionClassNames(string className, string namespace) { + namespace = "pqxx" and + className in ["connection_base", "basic_connection", "connection"] +} + +private predicate pqxxEscapeArgument(string function, int arg) { + arg = 0 and + function in ["esc", "esc_raw", "quote", "quote_raw", "quote_name", "quote_table", "esc_like"] +} + +private class PostgreSqlExecutionFunction extends SqlExecutionFunction { + PostgreSqlExecutionFunction() { + exists(Class c | + this.getDeclaringType() = c and + // transaction exec and connection prepare variations + ( + pqxxTransationClassNames(c.getName(), c.getNamespace().getName()) and + pqxxTransactionSqlArgument(this.getName(), _) + or + pqxxConnectionSqlArgument(this.getName(), _) and + pqxxConnectionClassNames(c.getName(), c.getNamespace().getName()) + ) + ) + } + + override predicate hasSqlArgument(FunctionInput input) { + exists(int argIndex | + pqxxTransactionSqlArgument(this.getName(), argIndex) + or + pqxxConnectionSqlArgument(this.getName(), argIndex) + | + input.isParameterDeref(argIndex) + ) + } +} + +private class PostgreSqlBarrierFunction extends SqlBarrierFunction { + PostgreSqlBarrierFunction() { + exists(Class c | + this.getDeclaringType() = c and + // transaction and connection escape functions + ( + pqxxTransationClassNames(c.getName(), c.getNamespace().getName()) or + pqxxConnectionClassNames(c.getName(), c.getNamespace().getName()) + ) and + pqxxEscapeArgument(this.getName(), _) + ) + } + + override predicate barrierSqlArgument(FunctionInput input, FunctionOutput output) { + exists(int argIndex | + input.isParameterDeref(argIndex) and + output.isReturnValueDeref() and + pqxxEscapeArgument(this.getName(), argIndex) + ) + } +} diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Recv.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Recv.qll index 691ba528f42..0551185ba14 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Recv.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Recv.qll @@ -85,4 +85,6 @@ private class Recv extends AliasFunction, ArrayFunction, SideEffectFunction, ) and description = "Buffer read by " + this.getName() } + + override predicate hasSocketInput(FunctionInput input) { input.isParameter(0) } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Send.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Send.qll index 6086bc7748f..d871bad68af 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Send.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Send.qll @@ -60,4 +60,6 @@ private class Send extends AliasFunction, ArrayFunction, SideEffectFunction, Rem override predicate hasRemoteFlowSink(FunctionInput input, string description) { input.isParameterDeref(1) and description = "Buffer sent by " + this.getName() } + + override predicate hasSocketInput(FunctionInput input) { input.isParameter(0) } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/SqLite3.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/SqLite3.qll new file mode 100644 index 00000000000..d65df9a27ed --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/SqLite3.qll @@ -0,0 +1,21 @@ +/** + * Provides implementation classes modeling the SQLite C API. + * See `semmle.code.cpp.models.Models` for usage information. + */ + +private import semmle.code.cpp.models.interfaces.Sql +private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs + +/** + * The `sqlite3_exec` and `sqlite3_prepare` families of functions from the SQLite C API. + */ +private class SqLite3ExecutionFunction extends SqlExecutionFunction { + SqLite3ExecutionFunction() { + this.hasName([ + "sqlite3_exec", "sqlite3_prepare", "sqlite3_prepare_v2", "sqlite3_prepare_v3", + "sqlite3_prepare16", "sqlite3_prepare16_v2", "sqlite3_prepare16_v3" + ]) + } + + override predicate hasSqlArgument(FunctionInput input) { input.isParameterDeref(1) } +} diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/System.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/System.qll new file mode 100644 index 00000000000..02a9d0d6744 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/System.qll @@ -0,0 +1,43 @@ +import cpp +import semmle.code.cpp.models.interfaces.SideEffect +import semmle.code.cpp.models.interfaces.Alias +import semmle.code.cpp.models.interfaces.CommandExecution + +/** + * A function for running a command using a command interpreter. + */ +private class SystemFunction extends CommandExecutionFunction, ArrayFunction, AliasFunction, + SideEffectFunction { + SystemFunction() { + hasGlobalOrStdName("system") or // system(command) + hasGlobalName("popen") or // popen(command, mode) + // Windows variants + hasGlobalName("_popen") or // _popen(command, mode) + hasGlobalName("_wpopen") or // _wpopen(command, mode) + hasGlobalName("_wsystem") // _wsystem(command) + } + + override predicate hasCommandArgument(FunctionInput input) { input.isParameterDeref(0) } + + override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = 0 or bufParam = 1 } + + override predicate hasArrayInput(int bufParam) { bufParam = 0 or bufParam = 1 } + + override predicate parameterNeverEscapes(int index) { index = 0 or index = 1 } + + override predicate parameterEscapesOnlyViaReturn(int index) { none() } + + override predicate parameterIsAlwaysReturned(int index) { none() } + + override predicate hasOnlySpecificReadSideEffects() { any() } + + override predicate hasOnlySpecificWriteSideEffects() { + hasGlobalOrStdName("system") or + hasGlobalName("_wsystem") + } + + override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { + (i = 0 or i = 1) and + buffer = true + } +} diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/CommandExecution.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/CommandExecution.qll new file mode 100644 index 00000000000..a6e32341140 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/CommandExecution.qll @@ -0,0 +1,23 @@ +/** + * Provides classes for modeling functions that execute new programs by + * interpreting string data as shell commands. To use this QL library, create + * a QL class extending `CommandExecutionFunction` with a characteristic + * predicate that selects the function or set of functions you are modeling. + * Within that class, override the `hasCommandArgument` predicate to indicate + * which parameters are interpreted as shell commands. + */ + +import cpp +import FunctionInputsAndOutputs +import semmle.code.cpp.models.Models + +/** + * A function, such as `exec` or `popen` that starts a new process by + * interpreting a string as a shell command. + */ +abstract class CommandExecutionFunction extends Function { + /** + * Holds if `input` is interpreted as a shell command. + */ + abstract predicate hasCommandArgument(FunctionInput input); +} diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/FlowSource.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/FlowSource.qll index 8c80377c8ec..d454257ea86 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/FlowSource.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/FlowSource.qll @@ -18,6 +18,12 @@ abstract class RemoteFlowSourceFunction extends Function { * Holds if remote data described by `description` flows from `output` of a call to this function. */ abstract predicate hasRemoteFlowSource(FunctionOutput output, string description); + + /** + * Holds if remote data from this source comes from a socket described by + * `input`. There is no result if a socket is not specified. + */ + predicate hasSocketInput(FunctionInput input) { none() } } /** @@ -51,4 +57,10 @@ abstract class RemoteFlowSinkFunction extends Function { * send over a network connection. */ abstract predicate hasRemoteFlowSink(FunctionInput input, string description); + + /** + * Holds if data put into this sink is transmitted through a socket described + * by `input`. There is no result if a socket is not specified. + */ + predicate hasSocketInput(FunctionInput input) { none() } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Sql.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Sql.qll new file mode 100644 index 00000000000..7d5111c2488 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Sql.qll @@ -0,0 +1,30 @@ +/** + * Provides abstract classes for modeling functions that execute and escape SQL query strings. + * To extend this QL library, create a QL class extending `SqlExecutionFunction` or `SqlEscapeFunction` + * with a characteristic predicate that selects the function or set of functions you are modeling. + * Within that class, override the predicates provided by the class to match the way a + * parameter flows into the function and, in the case of `SqlEscapeFunction`, out of the function. + */ + +private import cpp + +/** + * An abstract class that represents a function that executes an SQL query. + */ +abstract class SqlExecutionFunction extends Function { + /** + * Holds if `input` to this function represents SQL code to be executed. + */ + abstract predicate hasSqlArgument(FunctionInput input); +} + +/** + * An abstract class that represents a function that is a barrier to an SQL query string. + */ +abstract class SqlBarrierFunction extends Function { + /** + * Holds if the `output` is a barrier to the SQL input `input` such that is it safe to pass to + * an `SqlExecutionFunction`. + */ + abstract predicate barrierSqlArgument(FunctionInput input, FunctionOutput output); +} diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/NanAnalysis.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/NanAnalysis.qll index e402b672cbc..d3042a4edc9 100644 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/NanAnalysis.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/NanAnalysis.qll @@ -29,8 +29,7 @@ predicate nanExcludingComparison(ComparisonOperation guard, boolean polarity) { */ private predicate excludesNan(RangeSsaDefinition def, VariableAccess v) { exists(VariableAccess inCond, ComparisonOperation guard, boolean branch, StackVariable lsv | - def.isGuardPhi(inCond, guard, branch) and - inCond.getTarget() = lsv and + def.isGuardPhi(lsv, inCond, guard, branch) and v = def.getAUse(lsv) and guard.getAnOperand() = inCond and nanExcludingComparison(guard, branch) diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeSSA.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeSSA.qll index 93dcf989590..bc66d9b2dd0 100644 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeSSA.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeSSA.qll @@ -94,11 +94,21 @@ class RangeSsaDefinition extends ControlFlowNodeBase { predicate isPhiNode(StackVariable v) { exists(RangeSSA x | x.phi_node(v, this.(BasicBlock))) } /** + * DEPRECATED: Use isGuardPhi/4 instead * If this definition is a phi node corresponding to a guard, - * then return the variable and the guard. + * then return the variable access and the guard. */ - predicate isGuardPhi(VariableAccess v, Expr guard, boolean branch) { - guard_defn(v, guard, this, branch) + deprecated predicate isGuardPhi(VariableAccess va, Expr guard, boolean branch) { + guard_defn(va, guard, this, branch) + } + + /** + * If this definition is a phi node corresponding to a guard, + * then return the variable guarded, the variable access and the guard. + */ + predicate isGuardPhi(StackVariable v, VariableAccess va, Expr guard, boolean branch) { + guard_defn(va, guard, this, branch) and + va.getTarget() = v } /** Gets the primary location of this definition. */ @@ -133,9 +143,8 @@ class RangeSsaDefinition extends ControlFlowNodeBase { // below excludes definitions which can only reach guard phi // nodes by going through the corresponding guard. not exists(VariableAccess access | - v = access.getTarget() and pred.contains(access) and - this.isGuardPhi(access, _, _) + this.isGuardPhi(v, access, _, _) ) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll index 187641559f4..289187d4301 100644 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll @@ -433,10 +433,7 @@ private predicate exprDependsOnDef(Expr e, RangeSsaDefinition srcDef, StackVaria private predicate phiDependsOnDef( RangeSsaDefinition phi, StackVariable v, RangeSsaDefinition srcDef, StackVariable srcVar ) { - exists(VariableAccess access, Expr guard | - access = v.getAnAccess() and - phi.isGuardPhi(access, guard, _) - | + exists(VariableAccess access, Expr guard | phi.isGuardPhi(v, access, guard, _) | exprDependsOnDef(guard.(ComparisonOperation).getAnOperand(), srcDef, srcVar) or exprDependsOnDef(access, srcDef, srcVar) ) @@ -1204,8 +1201,7 @@ private float boolConversionUpperBound(Expr expr) { */ private float getPhiLowerBounds(StackVariable v, RangeSsaDefinition phi) { exists(VariableAccess access, Expr guard, boolean branch, float defLB, float guardLB | - access = v.getAnAccess() and - phi.isGuardPhi(access, guard, branch) and + phi.isGuardPhi(v, access, guard, branch) and lowerBoundFromGuard(guard, access, guardLB, branch) and defLB = getFullyConvertedLowerBounds(access) | @@ -1230,8 +1226,7 @@ private float getPhiLowerBounds(StackVariable v, RangeSsaDefinition phi) { /** See comment for `getPhiLowerBounds`, above. */ private float getPhiUpperBounds(StackVariable v, RangeSsaDefinition phi) { exists(VariableAccess access, Expr guard, boolean branch, float defUB, float guardUB | - access = v.getAnAccess() and - phi.isGuardPhi(access, guard, branch) and + phi.isGuardPhi(v, access, guard, branch) and upperBoundFromGuard(guard, access, guardUB, branch) and defUB = getFullyConvertedUpperBounds(access) | @@ -1493,8 +1488,7 @@ private predicate isNEPhi( exists( ComparisonOperation cmp, boolean branch, Expr linearExpr, Expr rExpr, float p, float q, float r | - access.getTarget() = v and - phi.isGuardPhi(access, cmp, branch) and + phi.isGuardPhi(v, access, cmp, branch) and eqOpWithSwapAndNegate(cmp, linearExpr, rExpr, false, branch) and v.getUnspecifiedType() instanceof IntegralOrEnumType and // Float `!=` is too imprecise r = getValue(rExpr).toFloat() and @@ -1503,8 +1497,7 @@ private predicate isNEPhi( ) or exists(Expr op, boolean branch, Expr linearExpr, float p, float q | - access.getTarget() = v and - phi.isGuardPhi(access, op, branch) and + phi.isGuardPhi(v, access, op, branch) and eqZeroWithNegate(op, linearExpr, false, branch) and v.getUnspecifiedType() instanceof IntegralOrEnumType and // Float `!` is too imprecise linearAccess(linearExpr, access, p, q) and @@ -1524,12 +1517,35 @@ private predicate isUnsupportedGuardPhi(Variable v, RangeSsaDefinition phi, Vari or eqZeroWithNegate(cmp, _, false, branch) | - access.getTarget() = v and - phi.isGuardPhi(access, cmp, branch) and + phi.isGuardPhi(v, access, cmp, branch) and not isNEPhi(v, phi, access, _) ) } +/** + * Gets the upper bound of the expression, if the expression is guarded. + * An upper bound can only be found, if a guard phi node can be found, and the + * expression has only one immediate predecessor. + */ +private float getGuardedUpperBound(VariableAccess guardedAccess) { + exists( + RangeSsaDefinition def, StackVariable v, VariableAccess guardVa, Expr guard, boolean branch + | + def.isGuardPhi(v, guardVa, guard, branch) and + // If the basic block for the variable access being examined has + // more than one predecessor, the guard phi node could originate + // from one of the predecessors. This is because the guard phi + // node is attached to the block at the end of the edge and not on + // the actual edge. It is therefore not possible to determine which + // edge the guard phi node belongs to. The predicate below ensures + // that there is one predecessor, albeit somewhat conservative. + exists(unique(BasicBlock b | b = def.(BasicBlock).getAPredecessor())) and + guardedAccess = def.getAUse(v) and + result = max(float ub | upperBoundFromGuard(guard, guardVa, ub, branch)) and + not convertedExprMightOverflow(guard.getAChild+()) + ) +} + cached private module SimpleRangeAnalysisCached { /** @@ -1565,9 +1581,18 @@ private module SimpleRangeAnalysisCached { */ cached float upperBound(Expr expr) { - // Combine the upper bounds returned by getTruncatedUpperBounds into a - // single maximum value. - result = max(float ub | ub = getTruncatedUpperBounds(expr) | ub) + // Combine the upper bounds returned by getTruncatedUpperBounds and + // getGuardedUpperBound into a single maximum value + result = min([max(getTruncatedUpperBounds(expr)), getGuardedUpperBound(expr)]) + } + + /** Holds if the upper bound of `expr` may have been widened. This means the the upper bound is in practice likely to be overly wide. */ + cached + predicate upperBoundMayBeWidened(Expr e) { + isRecursiveExpr(e) and + // Widening is not a problem if the post-analysis in `getGuardedUpperBound` has overridden the widening. + // Note that the RHS of `<` may be multi-valued. + not getGuardedUpperBound(e) < getTruncatedUpperBounds(e) } /** diff --git a/cpp/ql/lib/semmle/code/cpp/security/CommandExecution.qll b/cpp/ql/lib/semmle/code/cpp/security/CommandExecution.qll index d9bb701be58..f8f7c6c476f 100644 --- a/cpp/ql/lib/semmle/code/cpp/security/CommandExecution.qll +++ b/cpp/ql/lib/semmle/code/cpp/security/CommandExecution.qll @@ -4,42 +4,20 @@ import cpp import semmle.code.cpp.security.FunctionWithWrappers import semmle.code.cpp.models.interfaces.SideEffect import semmle.code.cpp.models.interfaces.Alias +import semmle.code.cpp.models.interfaces.CommandExecution /** * A function for running a command using a command interpreter. */ -class SystemFunction extends FunctionWithWrappers, ArrayFunction, AliasFunction, SideEffectFunction { - SystemFunction() { - hasGlobalOrStdName("system") or // system(command) - hasGlobalName("popen") or // popen(command, mode) - // Windows variants - hasGlobalName("_popen") or // _popen(command, mode) - hasGlobalName("_wpopen") or // _wpopen(command, mode) - hasGlobalName("_wsystem") // _wsystem(command) - } - - override predicate interestingArg(int arg) { arg = 0 } - - override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = 0 or bufParam = 1 } - - override predicate hasArrayInput(int bufParam) { bufParam = 0 or bufParam = 1 } - - override predicate parameterNeverEscapes(int index) { index = 0 or index = 1 } - - override predicate parameterEscapesOnlyViaReturn(int index) { none() } - - override predicate parameterIsAlwaysReturned(int index) { none() } - - override predicate hasOnlySpecificReadSideEffects() { any() } - - override predicate hasOnlySpecificWriteSideEffects() { - hasGlobalOrStdName("system") or - hasGlobalName("_wsystem") - } - - override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { - (i = 0 or i = 1) and - buffer = true +class SystemFunction extends FunctionWithWrappers instanceof CommandExecutionFunction { + override predicate interestingArg(int arg) { + exists(FunctionInput input | + this.(CommandExecutionFunction).hasCommandArgument(input) and + ( + input.isParameterDerefOrQualifierObject(arg) or + input.isParameterOrQualifierAddress(arg) + ) + ) } } diff --git a/cpp/ql/lib/semmle/code/cpp/security/FunctionWithWrappers.qll b/cpp/ql/lib/semmle/code/cpp/security/FunctionWithWrappers.qll index 5451011b351..654e9d92451 100644 --- a/cpp/ql/lib/semmle/code/cpp/security/FunctionWithWrappers.qll +++ b/cpp/ql/lib/semmle/code/cpp/security/FunctionWithWrappers.qll @@ -17,7 +17,7 @@ import cpp import PrintfLike -private import TaintTracking +private import semmle.code.cpp.ir.dataflow.ResolveCall bindingset[index] private string toCause(Function func, int index) { diff --git a/cpp/ql/lib/semmle/code/cpp/security/Security.qll b/cpp/ql/lib/semmle/code/cpp/security/Security.qll index d39c13a25a0..da808592b3e 100644 --- a/cpp/ql/lib/semmle/code/cpp/security/Security.qll +++ b/cpp/ql/lib/semmle/code/cpp/security/Security.qll @@ -7,6 +7,7 @@ import semmle.code.cpp.exprs.Expr import semmle.code.cpp.commons.Environment import semmle.code.cpp.security.SecurityOptions import semmle.code.cpp.models.interfaces.FlowSource +import semmle.code.cpp.models.interfaces.Sql /** * Extend this class to customize the security queries for @@ -34,13 +35,11 @@ class SecurityOptions extends string { * An argument to a function that is passed to a SQL server. */ predicate sqlArgument(string function, int arg) { - // MySQL C API - function = "mysql_query" and arg = 1 - or - function = "mysql_real_query" and arg = 1 - or - // SQLite3 C API - function = "sqlite3_exec" and arg = 1 + exists(FunctionInput input, SqlExecutionFunction sql | + sql.hasName(function) and + input.isParameterDeref(arg) and + sql.hasSqlArgument(input) + ) } /** diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index ddd31fd02e5..018f430097e 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -245,7 +245,7 @@ svnchurn( * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `file`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ locations_default( /** The location of an element that is not an expression or a statement. */ @@ -262,7 +262,7 @@ locations_default( * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `file`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ locations_stmt( /** The location of a statement. */ @@ -279,7 +279,7 @@ locations_stmt( * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `file`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ locations_expr( /** The location of an expression. */ @@ -310,23 +310,14 @@ diagnostics( int location: @location_default ref ); -/* - fromSource(0) = unknown, - fromSource(1) = from source, - fromSource(2) = from library -*/ files( unique int id: @file, - string name: string ref, - string simple: string ref, - string ext: string ref, - int fromSource: int ref + string name: string ref ); folders( unique int id: @folder, - string name: string ref, - string simple: string ref + string name: string ref ); @container = @folder | @file diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats index 61a31212bfa..c9aaf043a7a 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats @@ -12875,18 +12875,6 @@ name 59320 - -simple -40580 - - -ext -97 - - -fromSource -10 - @@ -12906,54 +12894,6 @@ -id -simple - - -12 - - -1 -2 -59320 - - - - - - -id -ext - - -12 - - -1 -2 -59320 - - - - - - -id -fromSource - - -12 - - -1 -2 -59320 - - - - - - name id @@ -12969,406 +12909,6 @@ - -name -simple - - -12 - - -1 -2 -59320 - - - - - - -name -ext - - -12 - - -1 -2 -59320 - - - - - - -name -fromSource - - -12 - - -1 -2 -59320 - - - - - - -simple -id - - -12 - - -1 -2 -30814 - - -2 -3 -6123 - - -3 -7 -3197 - - -7 -42 -444 - - - - - - -simple -name - - -12 - - -1 -2 -30814 - - -2 -3 -6123 - - -3 -7 -3197 - - -7 -42 -444 - - - - - - -simple -ext - - -12 - - -1 -2 -36277 - - -2 -3 -3739 - - -3 -6 -563 - - - - - - -simple -fromSource - - -12 - - -1 -2 -40580 - - - - - - -ext -id - - -12 - - -1 -2 -10 - - -3 -4 -10 - - -15 -16 -10 - - -38 -39 -10 - - -80 -81 -10 - - -114 -115 -10 - - -441 -442 -10 - - -768 -769 -10 - - -4013 -4014 -10 - - - - - - -ext -name - - -12 - - -1 -2 -10 - - -3 -4 -10 - - -15 -16 -10 - - -38 -39 -10 - - -80 -81 -10 - - -114 -115 -10 - - -441 -442 -10 - - -768 -769 -10 - - -4013 -4014 -10 - - - - - - -ext -simple - - -12 - - -1 -2 -10 - - -3 -4 -10 - - -15 -16 -10 - - -38 -39 -10 - - -75 -76 -10 - - -112 -113 -10 - - -428 -429 -10 - - -688 -689 -10 - - -2838 -2839 -10 - - - - - - -ext -fromSource - - -12 - - -1 -2 -97 - - - - - - -fromSource -id - - -12 - - -5473 -5474 -10 - - - - - - -fromSource -name - - -12 - - -5473 -5474 -10 - - - - - - -fromSource -simple - - -12 - - -3744 -3745 -10 - - - - - - -fromSource -ext - - -12 - - -9 -10 -10 - - - - - @@ -13383,10 +12923,6 @@ name 10817 - -simple -3099 - @@ -13406,22 +12942,6 @@ -id -simple - - -12 - - -1 -2 -10817 - - - - - - name id @@ -13437,94 +12957,6 @@ - -name -simple - - -12 - - -1 -2 -10817 - - - - - - -simple -id - - -12 - - -1 -2 -1669 - - -2 -3 -661 - - -3 -4 -433 - - -4 -17 -238 - - -27 -121 -97 - - - - - - -simple -name - - -12 - - -1 -2 -1669 - - -2 -3 -661 - - -3 -4 -433 - - -4 -17 -238 - - -27 -121 -97 - - - - - diff --git a/cpp/ql/src/AlertSuppression.ql b/cpp/ql/src/AlertSuppression.ql index 6258e8f7818..7239398e8c1 100644 --- a/cpp/ql/src/AlertSuppression.ql +++ b/cpp/ql/src/AlertSuppression.ql @@ -68,7 +68,7 @@ class SuppressionScope extends ElementBase { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/cpp/ql/src/Critical/OverflowStatic.ql b/cpp/ql/src/Critical/OverflowStatic.ql index 7c447c12323..8b09931cd4a 100644 --- a/cpp/ql/src/Critical/OverflowStatic.ql +++ b/cpp/ql/src/Critical/OverflowStatic.ql @@ -5,7 +5,7 @@ * @kind problem * @problem.severity warning * @security-severity 9.3 - * @precision medium + * @precision high * @id cpp/static-buffer-overflow * @tags reliability * security @@ -55,6 +55,8 @@ predicate overflowOffsetInLoop(BufferAccess bufaccess, string msg) { loop.counter().getAnAccess() = bufaccess.getArrayOffset() and // Ensure that we don't have an upper bound on the array index that's less than the buffer size. not upperBound(bufaccess.getArrayOffset().getFullyConverted()) < bufaccess.bufferSize() and + // The upper bounds analysis must not have been widended + not upperBoundMayBeWidened(bufaccess.getArrayOffset().getFullyConverted()) and msg = "Potential buffer-overflow: counter '" + loop.counter().toString() + "' <= " + loop.limit().toString() + " but '" + bufaccess.buffer().getName() + "' has " + @@ -130,11 +132,13 @@ predicate outOfBounds(BufferAccess bufaccess, string msg) { ( access > size or - access = size and not exists(AddressOfExpr addof | bufaccess = addof.getOperand()) + access = size and + not exists(AddressOfExpr addof | bufaccess = addof.getOperand()) and + not exists(BuiltInOperationBuiltInOffsetOf offsetof | offsetof.getAChild() = bufaccess) ) and msg = "Potential buffer-overflow: '" + buf + "' has size " + size.toString() + " but '" + buf + "[" + - access.toString() + "]' is accessed here." + access.toString() + "]' may be accessed here." ) } diff --git a/cpp/ql/src/Documentation/CommentedOutCode.qll b/cpp/ql/src/Documentation/CommentedOutCode.qll index 172474bbe29..a4e5b948630 100644 --- a/cpp/ql/src/Documentation/CommentedOutCode.qll +++ b/cpp/ql/src/Documentation/CommentedOutCode.qll @@ -198,7 +198,7 @@ class CommentBlock extends Comment { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/cpp/ql/src/Metrics/Internal/CallableExtents.ql b/cpp/ql/src/Metrics/Internal/CallableExtents.ql index 80c798b19ff..7a376c6da72 100644 --- a/cpp/ql/src/Metrics/Internal/CallableExtents.ql +++ b/cpp/ql/src/Metrics/Internal/CallableExtents.ql @@ -18,7 +18,7 @@ class RangeFunction extends Function { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { super.getLocation().hasLocationInfo(path, sl, sc, _, _) and diff --git a/cpp/ql/src/Metrics/Internal/DiagnosticsSumElapsedTimes.ql b/cpp/ql/src/Metrics/Internal/DiagnosticsSumElapsedTimes.ql new file mode 100644 index 00000000000..530811c0801 --- /dev/null +++ b/cpp/ql/src/Metrics/Internal/DiagnosticsSumElapsedTimes.ql @@ -0,0 +1,12 @@ +/** + * @name Sum of frontend and extractor time + * @description The sum of elapsed frontend time, and the sum of elapsed extractor time. + * This query is for internal use only and may change without notice. + * @kind table + * @id cpp/frontend-and-extractor-time + */ + +import cpp + +select sum(Compilation c, float seconds | compilation_time(c, _, 2, seconds) | seconds) as sum_frontend_elapsed_seconds, + sum(Compilation c, float seconds | compilation_time(c, _, 4, seconds) | seconds) as sum_extractor_elapsed_seconds diff --git a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.c b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.c index da5950c5fe5..c61adeee651 100644 --- a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.c +++ b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.c @@ -9,7 +9,7 @@ int main(int argc, char** argv) { system(command1); } - { + { // GOOD: the user string is encoded by a library routine. char userNameQuoted[1000] = {0}; encodeShellString(userNameQuoted, 1000, userName); diff --git a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql index 5f516eec83b..26652d9c1da 100644 --- a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql @@ -3,10 +3,10 @@ * @description Using user-supplied data in an OS command, without * neutralizing special elements, can make code vulnerable * to command injection. - * @kind problem + * @kind path-problem * @problem.severity error * @security-severity 9.8 - * @precision low + * @precision high * @id cpp/command-line-injection * @tags security * external/cwe/cwe-078 @@ -16,13 +16,204 @@ import cpp import semmle.code.cpp.security.CommandExecution import semmle.code.cpp.security.Security -import semmle.code.cpp.security.TaintTracking +import semmle.code.cpp.valuenumbering.GlobalValueNumbering +import semmle.code.cpp.ir.IR +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.ir.dataflow.TaintTracking2 +import semmle.code.cpp.security.FlowSources +import semmle.code.cpp.models.implementations.Strcat -from Expr taintedArg, Expr taintSource, string taintCause, string callChain +Expr sinkAsArgumentIndirection(DataFlow::Node sink) { + result = + sink.asOperand() + .(SideEffectOperand) + .getAddressOperand() + .getAnyDef() + .getUnconvertedResultExpression() +} + +/** + * Holds if `fst` is a string that is used in a format or concatenation function resulting in `snd`, + * and is *not* placed at the start of the resulting string. This indicates that the author did not + * expect `fst` to control what program is run if the resulting string is eventually interpreted as + * a command line, for example as an argument to `system`. + */ +predicate interestingConcatenation(DataFlow::Node fst, DataFlow::Node snd) { + exists(FormattingFunctionCall call, int index, FormatLiteral literal | + sinkAsArgumentIndirection(fst) = call.getConversionArgument(index) and + snd.asDefiningArgument() = call.getOutputArgument(false) and + literal = call.getFormat() and + not literal.getConvSpecOffset(index) = 0 and + literal.getConversionChar(index) = ["s", "S"] + ) + or + // strcat and friends + exists(StrcatFunction strcatFunc, CallInstruction call, ReadSideEffectInstruction rse | + call.getStaticCallTarget() = strcatFunc and + rse.getArgumentDef() = call.getArgument(strcatFunc.getParamSrc()) and + fst.asOperand() = rse.getSideEffectOperand() and + snd.asInstruction().(WriteSideEffectInstruction).getDestinationAddress() = + call.getArgument(strcatFunc.getParamDest()) + ) + or + exists(CallInstruction call, Operator op, ReadSideEffectInstruction rse | + call.getStaticCallTarget() = op and + op.hasQualifiedName("std", "operator+") and + op.getType().(UserType).hasQualifiedName("std", "basic_string") and + call.getArgument(1) = rse.getArgumentOperand().getAnyDef() and // left operand + fst.asOperand() = rse.getSideEffectOperand() and + call = snd.asInstruction() + ) +} + +class TaintToConcatenationConfiguration extends TaintTracking::Configuration { + TaintToConcatenationConfiguration() { this = "TaintToConcatenationConfiguration" } + + override predicate isSource(DataFlow::Node source) { source instanceof FlowSource } + + override predicate isSink(DataFlow::Node sink) { interestingConcatenation(sink, _) } + + override predicate isSanitizer(DataFlow::Node node) { + node.asInstruction().getResultType() instanceof IntegralType + or + node.asInstruction().getResultType() instanceof FloatingPointType + } +} + +class ExecTaintConfiguration extends TaintTracking2::Configuration { + ExecTaintConfiguration() { this = "ExecTaintConfiguration" } + + override predicate isSource(DataFlow::Node source) { + exists(DataFlow::Node prevSink, TaintToConcatenationConfiguration conf | + conf.hasFlow(_, prevSink) and + interestingConcatenation(prevSink, source) + ) + } + + override predicate isSink(DataFlow::Node sink) { + shellCommand(sinkAsArgumentIndirection(sink), _) + } + + override predicate isSanitizerOut(DataFlow::Node node) { + isSink(node) // Prevent duplicates along a call chain, since `shellCommand` will include wrappers + } +} + +module StitchedPathGraph { + // There's a different PathNode class for each DataFlowImplN.qll, so we can't simply combine the + // PathGraph predicates directly. Instead, we use a newtype so there's a single type that + // contains both sets of PathNodes. + newtype TMergedPathNode = + TPathNode1(DataFlow::PathNode node) or + TPathNode2(DataFlow2::PathNode node) + + // this wraps the toString and location predicates so we can use the merged node type in a + // selection + class MergedPathNode extends TMergedPathNode { + string toString() { + exists(DataFlow::PathNode n | + this = TPathNode1(n) and + result = n.toString() + ) + or + exists(DataFlow2::PathNode n | + this = TPathNode2(n) and + result = n.toString() + ) + } + + DataFlow::Node getNode() { + exists(DataFlow::PathNode n | + this = TPathNode1(n) and + result = n.getNode() + ) + or + exists(DataFlow2::PathNode n | + this = TPathNode2(n) and + result = n.getNode() + ) + } + + DataFlow::PathNode getPathNode1() { this = TPathNode1(result) } + + DataFlow2::PathNode getPathNode2() { this = TPathNode2(result) } + + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + exists(DataFlow::PathNode n | + this = TPathNode1(n) and + n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + ) + or + exists(DataFlow2::PathNode n | + this = TPathNode2(n) and + n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + ) + } + } + + query predicate edges(MergedPathNode a, MergedPathNode b) { + exists(DataFlow::PathNode an, DataFlow::PathNode bn | + a = TPathNode1(an) and + b = TPathNode1(bn) and + DataFlow::PathGraph::edges(an, bn) + ) + or + exists(DataFlow2::PathNode an, DataFlow2::PathNode bn | + a = TPathNode2(an) and + b = TPathNode2(bn) and + DataFlow2::PathGraph::edges(an, bn) + ) + or + // This is where paths from the two configurations are connected. `interestingConcatenation` + // is the only thing in this module that's actually specific to the query - everything else is + // just using types and predicates from the DataFlow library. + interestingConcatenation(a.getNode(), b.getNode()) and + a instanceof TPathNode1 and + b instanceof TPathNode2 + } + + query predicate nodes(MergedPathNode mpn, string key, string val) { + // here we just need the union of the underlying `nodes` predicates + exists(DataFlow::PathNode n | + mpn = TPathNode1(n) and + DataFlow::PathGraph::nodes(n, key, val) + ) + or + exists(DataFlow2::PathNode n | + mpn = TPathNode2(n) and + DataFlow2::PathGraph::nodes(n, key, val) + ) + } + + query predicate subpaths( + MergedPathNode arg, MergedPathNode par, MergedPathNode ret, MergedPathNode out + ) { + // just forward subpaths from the underlying libraries. This might be slightly awkward when + // the concatenation is deep in a call chain. + DataFlow::PathGraph::subpaths(arg.getPathNode1(), par.getPathNode1(), ret.getPathNode1(), + out.getPathNode1()) + or + DataFlow2::PathGraph::subpaths(arg.getPathNode2(), par.getPathNode2(), ret.getPathNode2(), + out.getPathNode2()) + } +} + +import StitchedPathGraph + +from + DataFlow::PathNode sourceNode, DataFlow::PathNode concatSink, DataFlow2::PathNode concatSource, + DataFlow2::PathNode sinkNode, string taintCause, string callChain, + TaintToConcatenationConfiguration conf1, ExecTaintConfiguration conf2 where - shellCommand(taintedArg, callChain) and - tainted(taintSource, taintedArg) and - isUserInput(taintSource, taintCause) -select taintedArg, - "This argument to an OS command is derived from $@ and then passed to " + callChain, taintSource, - "user input (" + taintCause + ")" + taintCause = sourceNode.getNode().(FlowSource).getSourceType() and + conf1.hasFlowPath(sourceNode, concatSink) and + interestingConcatenation(concatSink.getNode(), concatSource.getNode()) and // this loses call context + conf2.hasFlowPath(concatSource, sinkNode) and + shellCommand(sinkAsArgumentIndirection(sinkNode.getNode()), callChain) +select sinkAsArgumentIndirection(sinkNode.getNode()), TPathNode1(sourceNode).(MergedPathNode), + TPathNode2(sinkNode).(MergedPathNode), + "This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to " + + callChain, sourceNode, "user input (" + taintCause + ")", concatSource, + concatSource.toString() diff --git a/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql b/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql index a3f935170d7..92c8b9a2bd5 100644 --- a/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql @@ -30,7 +30,15 @@ class Configuration extends TaintTrackingConfiguration { } override predicate isBarrier(Expr e) { - super.isBarrier(e) or e.getUnspecifiedType() instanceof IntegralType + super.isBarrier(e) + or + e.getUnspecifiedType() instanceof IntegralType + or + exists(SqlBarrierFunction sql, int arg, FunctionInput input | + e = sql.getACallToThisFunction().getArgument(arg) and + input.isParameterDeref(arg) and + sql.barrierSqlArgument(input, _) + ) } } diff --git a/cpp/ql/src/Security/CWE/CWE-311/CleartextStorage.inc.qhelp b/cpp/ql/src/Security/CWE/CWE-311/CleartextStorage.inc.qhelp index eb9a6f8adce..f5e978e05cb 100644 --- a/cpp/ql/src/Security/CWE/CWE-311/CleartextStorage.inc.qhelp +++ b/cpp/ql/src/Security/CWE/CWE-311/CleartextStorage.inc.qhelp @@ -9,7 +9,7 @@ storage.

-

Ensure that sensitive information is always encrypted before being stored, especially before writing to a file. +

Ensure that sensitive information is always encrypted before being stored to a file or transmitted over the network. It may be wise to encrypt information before it is put into a buffer that may be readable in memory.

In general, decrypt sensitive information only at the point where it is necessary for it to be used in diff --git a/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.qhelp b/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.qhelp new file mode 100644 index 00000000000..d715abca84c --- /dev/null +++ b/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.qhelp @@ -0,0 +1,5 @@ + + + diff --git a/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql b/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql new file mode 100644 index 00000000000..d7e5343d6dc --- /dev/null +++ b/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql @@ -0,0 +1,124 @@ +/** + * @name Cleartext transmission of sensitive information + * @description Transmitting sensitive information across a network in + * cleartext can expose it to an attacker. + * @kind path-problem + * @problem.severity warning + * @security-severity 7.5 + * @precision medium + * @id cpp/cleartext-transmission + * @tags security + * external/cwe/cwe-319 + */ + +import cpp +import semmle.code.cpp.security.SensitiveExprs +import semmle.code.cpp.dataflow.TaintTracking +import semmle.code.cpp.models.interfaces.FlowSource +import DataFlow::PathGraph + +/** + * A function call that sends or receives data over a network. + */ +abstract class NetworkSendRecv extends FunctionCall { + /** + * Gets the expression for the socket or similar object used for sending or + * receiving data (if any). + */ + abstract Expr getSocketExpr(); + + /** + * Gets the expression for the buffer to be sent from / received into. + */ + abstract Expr getDataExpr(); +} + +/** + * A function call that sends data over a network. + * + * note: functions such as `write` may be writing to a network source or a file. We could attempt to determine which, and sort results into `cpp/cleartext-transmission` and perhaps `cpp/cleartext-storage-file`. In practice it usually isn't very important which query reports a result as long as its reported exactly once. + */ +class NetworkSend extends NetworkSendRecv { + RemoteFlowSinkFunction target; + + NetworkSend() { target = this.getTarget() } + + override Expr getSocketExpr() { + exists(FunctionInput input, int arg | + target.hasSocketInput(input) and + input.isParameter(arg) and + result = this.getArgument(arg) + ) + } + + override Expr getDataExpr() { + exists(FunctionInput input, int arg | + target.hasRemoteFlowSink(input, _) and + input.isParameterDeref(arg) and + result = this.getArgument(arg) + ) + } +} + +/** + * A function call that receives data over a network. + */ +class NetworkRecv extends NetworkSendRecv { + RemoteFlowSourceFunction target; + + NetworkRecv() { target = this.getTarget() } + + override Expr getSocketExpr() { + exists(FunctionInput input, int arg | + target.hasSocketInput(input) and + input.isParameter(arg) and + result = this.getArgument(arg) + ) + } + + override Expr getDataExpr() { + exists(FunctionOutput output, int arg | + target.hasRemoteFlowSource(output, _) and + output.isParameterDeref(arg) and + result = this.getArgument(arg) + ) + } +} + +/** + * Taint flow from a sensitive expression to a network operation with data + * tainted by that expression. + */ +class SensitiveSendRecvConfiguration extends TaintTracking::Configuration { + SensitiveSendRecvConfiguration() { this = "SensitiveSendRecvConfiguration" } + + override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof SensitiveExpr } + + override predicate isSink(DataFlow::Node sink) { + exists(NetworkSendRecv transmission | + sink.asExpr() = transmission.getDataExpr() and + // a zero socket descriptor is standard input, which is not interesting for this query. + not exists(Zero zero | + DataFlow::localFlow(DataFlow::exprNode(zero), + DataFlow::exprNode(transmission.getSocketExpr())) + ) + ) + } +} + +from + SensitiveSendRecvConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink, + NetworkSendRecv transmission, string msg +where + config.hasFlowPath(source, sink) and + sink.getNode().asExpr() = transmission.getDataExpr() and + if transmission instanceof NetworkSend + then + msg = + "This operation transmits '" + sink.toString() + + "', which may contain unencrypted sensitive data from $@" + else + msg = + "This operation receives into '" + sink.toString() + + "', which may put unencrypted sensitive data into $@" +select transmission, source, sink, msg, source, source.getNode().asExpr().toString() diff --git a/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql b/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql index 28e7295dcdc..357e6375570 100644 --- a/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql +++ b/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql @@ -4,10 +4,13 @@ * @kind problem * @id cpp/incorrect-allocation-error-handling * @problem.severity warning + * @security-severity 7.5 * @precision medium * @tags correctness * security * external/cwe/cwe-570 + * external/cwe/cwe-252 + * external/cwe/cwe-755 */ import cpp diff --git a/cpp/ql/src/definitions.qll b/cpp/ql/src/definitions.qll index eac03ce7082..cb229d66ef1 100644 --- a/cpp/ql/src/definitions.qll +++ b/cpp/ql/src/definitions.qll @@ -24,7 +24,7 @@ class Top extends Element { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ pragma[noopt] final predicate hasLocationInfo( diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-089/SqlPqxxTainted.cpp b/cpp/ql/src/experimental/Security/CWE/CWE-089/SqlPqxxTainted.cpp deleted file mode 100644 index 3b85835fff9..00000000000 --- a/cpp/ql/src/experimental/Security/CWE/CWE-089/SqlPqxxTainted.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include - -int main(int argc, char ** argv) { - - if (argc != 2) { - throw std::runtime_error("Give me a string!"); - } - - pqxx::connection c; - pqxx::work w(c); - - // BAD - char *userName = argv[1]; - char query1[1000] = {0}; - sprintf(query1, "SELECT UID FROM USERS where name = \"%s\"", userName); - pqxx::row r = w.exec1(query1); - w.commit(); - std::cout << r[0].as() << std::endl; - - // GOOD - pqxx::result r2 = w.exec("SELECT " + w.quote(argv[1])); - w.commit(); - std::cout << r2[0][0].c_str() << std::endl; - - return 0; -} diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-089/SqlPqxxTainted.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-089/SqlPqxxTainted.qhelp deleted file mode 100644 index 1c01b3e4f3a..00000000000 --- a/cpp/ql/src/experimental/Security/CWE/CWE-089/SqlPqxxTainted.qhelp +++ /dev/null @@ -1,31 +0,0 @@ - - - -

The code passes user input as part of a SQL query without escaping special elements. -It generates a SQL query to Postgres using sprintf, -with the user-supplied data directly passed as an argument -to sprintf. This leaves the code vulnerable to attack by SQL Injection.

- - - - -

Use a library routine to escape characters in the user-supplied -string before converting it to SQL. Use esc and quote pqxx library functions.

- -
- - - - - - -
  • MSDN Library: SQL Injection.
  • - - - - -
    - diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-089/SqlPqxxTainted.ql b/cpp/ql/src/experimental/Security/CWE/CWE-089/SqlPqxxTainted.ql deleted file mode 100644 index 8de55953b15..00000000000 --- a/cpp/ql/src/experimental/Security/CWE/CWE-089/SqlPqxxTainted.ql +++ /dev/null @@ -1,113 +0,0 @@ -/** - * @name Uncontrolled data in SQL query to Postgres - * @description Including user-supplied data in a SQL query to Postgres - * without neutralizing special elements can make code - * vulnerable to SQL Injection. - * @kind path-problem - * @problem.severity error - * @precision high - * @id cpp/sql-injection-via-pqxx - * @tags security - * external/cwe/cwe-089 - */ - -import cpp -import semmle.code.cpp.security.Security -import semmle.code.cpp.dataflow.TaintTracking -import DataFlow::PathGraph - -predicate pqxxTransationClassNames(string className, string namespace) { - namespace = "pqxx" and - className in [ - "dbtransaction", "nontransaction", "basic_robusttransaction", "robusttransaction", - "subtransaction", "transaction", "basic_transaction", "transaction_base", "work" - ] -} - -predicate pqxxConnectionClassNames(string className, string namespace) { - namespace = "pqxx" and - className in ["connection_base", "basic_connection", "connection"] -} - -predicate pqxxTransactionSqlArgument(string function, int arg) { - function = "exec" and arg = 0 - or - function = "exec0" and arg = 0 - or - function = "exec1" and arg = 0 - or - function = "exec_n" and arg = 1 - or - function = "exec_params" and arg = 0 - or - function = "exec_params0" and arg = 0 - or - function = "exec_params1" and arg = 0 - or - function = "exec_params_n" and arg = 1 - or - function = "query_value" and arg = 0 - or - function = "stream" and arg = 0 -} - -predicate pqxxConnectionSqlArgument(string function, int arg) { function = "prepare" and arg = 1 } - -Expr getPqxxSqlArgument() { - exists(FunctionCall fc, Expr e, int argIndex, UserType t | - // examples: 'work' for 'work.exec(...)'; '->' for 'tx->exec()'. - e = fc.getQualifier() and - // to find ConnectionHandle/TransationHandle and similar classes which override '->' operator behavior - // and return pointer to a connection/transation object - e.getType().refersTo(t) and - // transaction exec and connection prepare variations - ( - pqxxTransationClassNames(t.getName(), t.getNamespace().getName()) and - pqxxTransactionSqlArgument(fc.getTarget().getName(), argIndex) - or - pqxxConnectionClassNames(t.getName(), t.getNamespace().getName()) and - pqxxConnectionSqlArgument(fc.getTarget().getName(), argIndex) - ) and - result = fc.getArgument(argIndex) - ) -} - -predicate pqxxEscapeArgument(string function, int arg) { - arg = 0 and - function in ["esc", "esc_raw", "quote", "quote_raw", "quote_name", "quote_table", "esc_like"] -} - -predicate isEscapedPqxxArgument(Expr argExpr) { - exists(FunctionCall fc, Expr e, int argIndex, UserType t | - // examples: 'work' for 'work.exec(...)'; '->' for 'tx->exec()'. - e = fc.getQualifier() and - // to find ConnectionHandle/TransationHandle and similar classes which override '->' operator behavior - // and return pointer to a connection/transation object - e.getType().refersTo(t) and - // transaction and connection escape functions - ( - pqxxTransationClassNames(t.getName(), t.getNamespace().getName()) or - pqxxConnectionClassNames(t.getName(), t.getNamespace().getName()) - ) and - pqxxEscapeArgument(fc.getTarget().getName(), argIndex) and - // is escaped arg == argExpr - argExpr = fc.getArgument(argIndex) - ) -} - -class Configuration extends TaintTracking::Configuration { - Configuration() { this = "SqlPqxxTainted" } - - override predicate isSource(DataFlow::Node source) { isUserInput(source.asExpr(), _) } - - override predicate isSink(DataFlow::Node sink) { sink.asExpr() = getPqxxSqlArgument() } - - override predicate isSanitizer(DataFlow::Node node) { isEscapedPqxxArgument(node.asExpr()) } -} - -from DataFlow::PathNode source, DataFlow::PathNode sink, Configuration config, string taintCause -where - config.hasFlowPath(source, sink) and - isUserInput(source.getNode().asExpr(), taintCause) -select sink, source, sink, "This argument to a SQL query function is derived from $@", source, - "user input (" + taintCause + ")" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-675/DoubleRelease.c b/cpp/ql/src/experimental/Security/CWE/CWE-675/DoubleRelease.c new file mode 100644 index 00000000000..22de8d4dde4 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-675/DoubleRelease.c @@ -0,0 +1,13 @@ +... + fs = socket(AF_UNIX, SOCK_STREAM, 0) +... + close(fs); + fs = -1; // GOOD +... + +... + fs = socket(AF_UNIX, SOCK_STREAM, 0) +... + close(fs); + if(fs) close(fs); // BAD +... diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-675/DoubleRelease.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-675/DoubleRelease.qhelp new file mode 100644 index 00000000000..2b590e025b8 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-675/DoubleRelease.qhelp @@ -0,0 +1,26 @@ + + + +

    Double release of the descriptor can lead to a crash of the program. Requires the attention of developers.

    + +
    + +

    We recommend that you exclude situations of possible double release.

    + +
    + +

    The following example demonstrates an erroneous and corrected use of descriptor deallocation.

    + + +
    + + +
  • + CERT C Coding Standard: + FIO46-C. Do not access a closed file. +
  • + +
    +
    diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-675/DoubleRelease.ql b/cpp/ql/src/experimental/Security/CWE/CWE-675/DoubleRelease.ql new file mode 100644 index 00000000000..474f00acc55 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-675/DoubleRelease.ql @@ -0,0 +1,142 @@ +/** + * @name Errors When Double Release + * @description Double release of the descriptor can lead to a crash of the program. + * @kind problem + * @id cpp/double-release + * @problem.severity warning + * @precision medium + * @tags security + * external/cwe/cwe-675 + * external/cwe/cwe-666 + */ + +import cpp +import semmle.code.cpp.commons.File +import semmle.code.cpp.valuenumbering.GlobalValueNumbering +import semmle.code.cpp.valuenumbering.HashCons + +/** + * A function call that potentially does not return (such as `exit`). + */ +class CallMayNotReturn extends FunctionCall { + CallMayNotReturn() { + // call that is known to not return + not exists(this.(ControlFlowNode).getASuccessor()) + or + // call to another function that may not return + exists(CallMayNotReturn exit | getTarget() = exit.getEnclosingFunction()) + or + exists(ThrowExpr tex | tex = this.(ControlFlowNode).getASuccessor()) + } +} + +/** Holds if there are no assignment expressions to the function argument. */ +pragma[inline] +predicate checkChangeVariable(FunctionCall fc0, ControlFlowNode fc1, ControlFlowNode fc2) { + not exists(Expr exptmp | + ( + exptmp = fc0.getArgument(0).(VariableAccess).getTarget().getAnAssignedValue() or + exptmp.(AddressOfExpr).getOperand() = + fc0.getArgument(0).(VariableAccess).getTarget().getAnAccess() + ) and + exptmp = fc1.getASuccessor*() and + exptmp = fc2.getAPredecessor*() + ) and + ( + ( + not fc0.getArgument(0) instanceof PointerFieldAccess and + not fc0.getArgument(0) instanceof ValueFieldAccess + or + fc0.getArgument(0).(VariableAccess).getQualifier() instanceof ThisExpr + ) + or + not exists(Expr exptmp | + ( + exptmp = + fc0.getArgument(0) + .(VariableAccess) + .getQualifier() + .(VariableAccess) + .getTarget() + .getAnAssignedValue() or + exptmp.(AddressOfExpr).getOperand() = + fc0.getArgument(0) + .(VariableAccess) + .getQualifier() + .(VariableAccess) + .getTarget() + .getAnAccess() + ) and + exptmp = fc1.getASuccessor*() and + exptmp = fc2.getAPredecessor*() + ) + ) +} + +/** Holds if the underlying expression is a call to the close function. Provided that the function parameter does not change after the call. */ +predicate closeReturn(FunctionCall fc) { + fcloseCall(fc, _) and + checkChangeVariable(fc, fc, fc.getEnclosingFunction()) +} + +/** Holds if the underlying expression is a call to the close function. Provided that the function parameter does not change before the call. */ +predicate closeWithoutChangeBefore(FunctionCall fc) { + fcloseCall(fc, _) and + checkChangeVariable(fc, fc.getEnclosingFunction().getEntryPoint(), fc) +} + +/** Holds, if a sequential call of the specified functions is possible, via a higher-level function call. */ +predicate callInOtherFunctions(FunctionCall fc, FunctionCall fc1) { + exists(FunctionCall fec1, FunctionCall fec2 | + fc.getEnclosingFunction() != fc1.getEnclosingFunction() and + fec1 = fc.getEnclosingFunction().getACallToThisFunction() and + fec2 = fc1.getEnclosingFunction().getACallToThisFunction() and + fec1.getASuccessor*() = fec2 and + checkChangeVariable(fc, fec1, fec2) + ) +} + +/** Holds if successive calls to close functions are possible. */ +predicate interDoubleCloseFunctions(FunctionCall fc, FunctionCall fc1) { + fcloseCall(fc, _) and + fcloseCall(fc1, _) and + fc != fc1 and + fc.getASuccessor*() = fc1 and + checkChangeVariable(fc, fc, fc1) +} + +/** Holds if the first arguments of the two functions are similar. */ +predicate similarArguments(FunctionCall fc, FunctionCall fc1) { + globalValueNumber(fc.getArgument(0)) = globalValueNumber(fc1.getArgument(0)) + or + fc.getArgument(0).(VariableAccess).getTarget() = fc1.getArgument(0).(VariableAccess).getTarget() and + ( + not fc.getArgument(0) instanceof PointerFieldAccess and + not fc.getArgument(0) instanceof ValueFieldAccess + or + fc.getArgument(0).(VariableAccess).getQualifier() instanceof ThisExpr + ) + or + fc.getArgument(0).(VariableAccess).getTarget() = fc1.getArgument(0).(VariableAccess).getTarget() and + ( + fc.getArgument(0) instanceof PointerFieldAccess or + fc.getArgument(0) instanceof ValueFieldAccess + ) and + hashCons(fc.getArgument(0)) = hashCons(fc1.getArgument(0)) +} + +from FunctionCall fc, FunctionCall fc1 +where + not exists(CallMayNotReturn fctmp | fctmp = fc.getASuccessor*()) and + not exists(IfStmt ifs | ifs.getCondition().getAChild*() = fc) and + ( + // detecting a repeated call situation within one function + closeReturn(fc) and + closeWithoutChangeBefore(fc1) and + callInOtherFunctions(fc, fc1) + or + // detection of repeated call in different functions + interDoubleCloseFunctions(fc, fc1) + ) and + similarArguments(fc, fc1) +select fc, "Second call to the $@ function is possible.", fc1, fc1.getTarget().getName() diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-787/UnsignedToSignedPointerArith.ql b/cpp/ql/src/experimental/Security/CWE/CWE-787/UnsignedToSignedPointerArith.ql new file mode 100644 index 00000000000..1fe82c9cc51 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-787/UnsignedToSignedPointerArith.ql @@ -0,0 +1,30 @@ +/** + * @name unsigned to signed used in pointer arithmetic + * @description finds unsigned to signed conversions used in pointer arithmetic, potentially causing an out-of-bound access + * @id cpp/sign-conversion-pointer-arithmetic + * @kind problem + * @problem.severity warning + * @tags reliability + * security + * external/cwe/cwe-787 + */ + +import cpp +import semmle.code.cpp.dataflow.DataFlow +import semmle.code.cpp.security.Overflow + +from FunctionCall call, Function f, Parameter p, DataFlow::Node sink, PointerArithmeticOperation pao +where + f = call.getTarget() and + p = f.getAParameter() and + p.getUnspecifiedType().(IntegralType).isSigned() and + call.getArgument(p.getIndex()).getUnspecifiedType().(IntegralType).isUnsigned() and + pao.getAnOperand() = sink.asExpr() and + not exists(Operation a | guardedLesser(a, sink.asExpr())) and + not exists(Operation b | guardedGreater(b, call.getArgument(p.getIndex()))) and + not call.getArgument(p.getIndex()).isConstant() and + DataFlow::localFlow(DataFlow::parameterNode(p), sink) and + p.getUnspecifiedType().getSize() < 8 +select call, + "This call: $@ passes an unsigned int to a function that requires a signed int: $@. And then used in pointer arithmetic: $@", + call, call.toString(), f, f.toString(), sink, sink.toString() diff --git a/cpp/ql/src/external/CodeDuplication.qll b/cpp/ql/src/external/CodeDuplication.qll index 8cc56d12e19..1550ca697a3 100644 --- a/cpp/ql/src/external/CodeDuplication.qll +++ b/cpp/ql/src/external/CodeDuplication.qll @@ -61,7 +61,7 @@ class Copy extends @duplication_or_similarity { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/cpp/ql/src/external/DefectFilter.qll b/cpp/ql/src/external/DefectFilter.qll index 675f3b25faa..b932ffd0470 100644 --- a/cpp/ql/src/external/DefectFilter.qll +++ b/cpp/ql/src/external/DefectFilter.qll @@ -8,7 +8,7 @@ import cpp * column `startcolumn` of line `startline` to column `endcolumn` of line `endline` * in file `filepath`. * - * For more information, see [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * For more information, see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ external predicate defectResults( int id, string queryPath, string file, int startline, int startcol, int endline, int endcol, diff --git a/cpp/ql/src/external/MetricFilter.qll b/cpp/ql/src/external/MetricFilter.qll index dd9cece78ce..58e8bf154e9 100644 --- a/cpp/ql/src/external/MetricFilter.qll +++ b/cpp/ql/src/external/MetricFilter.qll @@ -8,7 +8,7 @@ import cpp * column `startcolumn` of line `startline` to column `endcolumn` of line `endline` * in file `filepath`. * - * For more information, see [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * For more information, see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ external predicate metricResults( int id, string queryPath, string file, int startline, int startcol, int endline, int endcol, diff --git a/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql b/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql index 0e021ca7575..ac5db25ea6b 100644 --- a/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql +++ b/cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql @@ -63,6 +63,7 @@ where functionsMissingReturnStmt(f, blame) and reachable(blame) and not functionImperfectlyExtracted(f) and + not f.isFromUninstantiatedTemplate(_) and (blame = stmt or blame.(Expr).getEnclosingStmt() = stmt) and msg = "Function " + f.getName() + " should return a value of type " + f.getType().getName() + diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/AllocMultiplicationOverflow/AllocMultiplicationOverflow.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/AllocMultiplicationOverflow/AllocMultiplicationOverflow.expected index b8428a43d11..03a070f3c91 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/AllocMultiplicationOverflow/AllocMultiplicationOverflow.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/AllocMultiplicationOverflow/AllocMultiplicationOverflow.expected @@ -8,6 +8,7 @@ nodes | test.cpp:23:33:23:37 | size1 | semmle.label | size1 | | test.cpp:30:27:30:31 | ... * ... | semmle.label | ... * ... | | test.cpp:31:27:31:31 | ... * ... | semmle.label | ... * ... | +subpaths #select | test.cpp:13:33:13:37 | ... * ... | test.cpp:13:33:13:37 | ... * ... | test.cpp:13:33:13:37 | ... * ... | Potentially overflowing value from $@ is used in the size of this allocation. | test.cpp:13:33:13:37 | ... * ... | multiplication | | test.cpp:15:31:15:35 | ... * ... | test.cpp:15:31:15:35 | ... * ... | test.cpp:15:31:15:35 | ... * ... | Potentially overflowing value from $@ is used in the size of this allocation. | test.cpp:15:31:15:35 | ... * ... | multiplication | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-359/semmle/tests/PrivateCleartextWrite.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-359/semmle/tests/PrivateCleartextWrite.expected index 887547f2c2e..d4ab9ad5e11 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-359/semmle/tests/PrivateCleartextWrite.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-359/semmle/tests/PrivateCleartextWrite.expected @@ -1,8 +1,12 @@ edges +| test.cpp:45:18:45:23 | buffer | test.cpp:47:10:47:15 | buffer | | test.cpp:77:16:77:22 | medical | test.cpp:78:24:78:27 | temp | | test.cpp:81:17:81:20 | call to func | test.cpp:82:24:82:28 | buff5 | +| test.cpp:81:22:81:28 | medical | test.cpp:45:18:45:23 | buffer | | test.cpp:81:22:81:28 | medical | test.cpp:81:17:81:20 | call to func | nodes +| test.cpp:45:18:45:23 | buffer | semmle.label | buffer | +| test.cpp:47:10:47:15 | buffer | semmle.label | buffer | | test.cpp:57:9:57:18 | theZipcode | semmle.label | theZipcode | | test.cpp:74:24:74:30 | medical | semmle.label | medical | | test.cpp:77:16:77:22 | medical | semmle.label | medical | @@ -12,6 +16,8 @@ nodes | test.cpp:82:24:82:28 | buff5 | semmle.label | buff5 | | test.cpp:96:37:96:46 | theZipcode | semmle.label | theZipcode | | test.cpp:99:42:99:51 | theZipcode | semmle.label | theZipcode | +subpaths +| test.cpp:81:22:81:28 | medical | test.cpp:45:18:45:23 | buffer | test.cpp:47:10:47:15 | buffer | test.cpp:81:17:81:20 | call to func | #select | test.cpp:57:9:57:18 | theZipcode | test.cpp:57:9:57:18 | theZipcode | test.cpp:57:9:57:18 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@ | test.cpp:57:9:57:18 | theZipcode | this source. | | test.cpp:74:24:74:30 | medical | test.cpp:74:24:74:30 | medical | test.cpp:74:24:74:30 | medical | This write into the external location 'medical' may contain unencrypted data from $@ | test.cpp:74:24:74:30 | medical | this source. | diff --git a/cpp/ql/test/include/iterator.h b/cpp/ql/test/include/iterator.h new file mode 100644 index 00000000000..77758bfa8da --- /dev/null +++ b/cpp/ql/test/include/iterator.h @@ -0,0 +1,97 @@ +#if !defined(CODEQL_ITERATOR_H) +#define CODEQL_ITERATOR_H + +typedef unsigned long size_t; + +#include "type_traits.h" + +namespace std { + struct ptrdiff_t; + + template struct iterator_traits; + + template + struct iterator { + typedef Category iterator_category; + + iterator(); + iterator(iterator > const &other); // non-const -> const conversion constructor + + iterator &operator++(); + iterator operator++(int); + iterator &operator--(); + iterator operator--(int); + bool operator==(iterator other) const; + bool operator!=(iterator other) const; + reference_type operator*() const; + pointer_type operator->() const; + iterator operator+(int); + iterator operator-(int); + iterator &operator+=(int); + iterator &operator-=(int); + int operator-(iterator); + reference_type operator[](int); + }; + + struct input_iterator_tag {}; + struct forward_iterator_tag : public input_iterator_tag {}; + struct bidirectional_iterator_tag : public forward_iterator_tag {}; + struct random_access_iterator_tag : public bidirectional_iterator_tag {}; + + struct output_iterator_tag {}; + + template + class back_insert_iterator { + protected: + Container* container = nullptr; + public: + using iterator_category = output_iterator_tag; + using value_type = void; + using difference_type = ptrdiff_t; + using pointer = void; + using reference = void; + using container_type = Container; + constexpr back_insert_iterator() noexcept = default; + constexpr explicit back_insert_iterator(Container& x); + back_insert_iterator& operator=(const typename Container::value_type& value); + back_insert_iterator& operator=(typename Container::value_type&& value); + back_insert_iterator& operator*(); + back_insert_iterator& operator++(); + back_insert_iterator operator++(int); + }; + + template + constexpr back_insert_iterator back_inserter(Container& x) { + return back_insert_iterator(x); + } + + template + class front_insert_iterator { + protected: + Container* container = nullptr; + public: + using iterator_category = output_iterator_tag; + using value_type = void; + using difference_type = ptrdiff_t; + using pointer = void; + using reference = void; + using container_type = Container; + constexpr front_insert_iterator() noexcept = default; + constexpr explicit front_insert_iterator(Container& x); + constexpr front_insert_iterator& operator=(const typename Container::value_type& value); + constexpr front_insert_iterator& operator=(typename Container::value_type&& value); + constexpr front_insert_iterator& operator*(); + constexpr front_insert_iterator& operator++(); + constexpr front_insert_iterator operator++(int); + }; + template + constexpr front_insert_iterator front_inserter(Container& x) { + return front_insert_iterator(x); + } +} + +#endif \ No newline at end of file diff --git a/cpp/ql/test/include/string.h b/cpp/ql/test/include/string.h new file mode 100644 index 00000000000..8d577c350f9 --- /dev/null +++ b/cpp/ql/test/include/string.h @@ -0,0 +1,85 @@ +#if !defined(CODEQL_STRING_H) +#define CODEQL_STRING_H + +#include "iterator.h" + +namespace std +{ + template struct char_traits; + + typedef size_t streamsize; + + template class allocator { + public: + allocator() throw(); + typedef size_t size_type; + }; + + template, class Allocator = allocator > + class basic_string { + public: + using value_type = charT; + using reference = value_type&; + using const_reference = const value_type&; + typedef typename Allocator::size_type size_type; + static const size_type npos = -1; + + explicit basic_string(const Allocator& a = Allocator()); + basic_string(const charT* s, const Allocator& a = Allocator()); + template basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator()); + + const charT* c_str() const; + charT* data() noexcept; + size_t length() const; + + typedef std::iterator iterator; + typedef std::iterator const_iterator; + + iterator begin(); + iterator end(); + const_iterator begin() const; + const_iterator end() const; + const_iterator cbegin() const; + const_iterator cend() const; + + void push_back(charT c); + + const charT& front() const; + charT& front(); + const charT& back() const; + charT& back(); + + const_reference operator[](size_type pos) const; + reference operator[](size_type pos); + const_reference at(size_type n) const; + reference at(size_type n); + template basic_string& operator+=(const T& t); + basic_string& operator+=(const charT* s); + basic_string& append(const basic_string& str); + basic_string& append(const charT* s); + basic_string& append(size_type n, charT c); + template basic_string& append(InputIterator first, InputIterator last); + basic_string& assign(const basic_string& str); + basic_string& assign(size_type n, charT c); + template basic_string& assign(InputIterator first, InputIterator last); + basic_string& insert(size_type pos, const basic_string& str); + basic_string& insert(size_type pos, size_type n, charT c); + basic_string& insert(size_type pos, const charT* s); + iterator insert(const_iterator p, size_type n, charT c); + template iterator insert(const_iterator p, InputIterator first, InputIterator last); + basic_string& replace(size_type pos1, size_type n1, const basic_string& str); + basic_string& replace(size_type pos1, size_type n1, size_type n2, charT c); + size_type copy(charT* s, size_type n, size_type pos = 0) const; + void clear() noexcept; + basic_string substr(size_type pos = 0, size_type n = npos) const; + void swap(basic_string& s) noexcept/*(allocator_traits::propagate_on_container_swap::value || allocator_traits::is_always_equal::value)*/; + }; + + template basic_string operator+(const basic_string& lhs, const basic_string& rhs); + template basic_string operator+(const basic_string& lhs, const charT* rhs); + template basic_string operator+(const charT* lhs, const basic_string& rhs); + + typedef basic_string string; +} + +#endif \ No newline at end of file diff --git a/cpp/ql/test/include/type_traits.h b/cpp/ql/test/include/type_traits.h index 19bdd46906b..dba04f36cad 100644 --- a/cpp/ql/test/include/type_traits.h +++ b/cpp/ql/test/include/type_traits.h @@ -1,21 +1,44 @@ #if !defined(CODEQL_TYPE_TRAITS_H) #define CODEQL_TYPE_TRAITS_H +typedef unsigned long size_t; + namespace std { - template - struct remove_reference { + template + struct remove_const { typedef T type; }; + + template + struct remove_const { typedef T type; }; + + // `remove_const_t` removes any `const` specifier from `T` + template + using remove_const_t = typename remove_const::type; + + template + struct remove_reference { typedef T type; }; + + template + struct remove_reference { typedef T type; }; + + template + struct remove_reference { typedef T type; }; + + // `remove_reference_t` removes any `&` from `T` + template + using remove_reference_t = typename remove_reference::type; + + template + struct decay_impl { typedef T type; }; - template - struct remove_reference { - typedef T type; + template + struct decay_impl { + typedef T* type; }; - template - struct remove_reference { - typedef T type; - }; + template + using decay_t = typename decay_impl>::type; } #endif diff --git a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected index 2736cdcd9e1..897d2e72fe5 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected @@ -1,11 +1,18 @@ edges +| A.cpp:23:10:23:10 | c | A.cpp:25:7:25:17 | Chi [c] | +| A.cpp:27:17:27:17 | c | A.cpp:27:22:27:32 | Chi [c] | +| A.cpp:28:8:28:10 | *#this [c] | A.cpp:28:29:28:29 | Store | | A.cpp:55:5:55:5 | set output argument [c] | A.cpp:56:10:56:10 | b indirection [c] | +| A.cpp:55:8:55:10 | new | A.cpp:27:17:27:17 | c | | A.cpp:55:8:55:10 | new | A.cpp:55:5:55:5 | set output argument [c] | | A.cpp:55:12:55:19 | (C *)... | A.cpp:55:8:55:10 | new | | A.cpp:55:12:55:19 | new | A.cpp:55:8:55:10 | new | +| A.cpp:56:10:56:10 | b indirection [c] | A.cpp:28:8:28:10 | *#this [c] | | A.cpp:56:10:56:10 | b indirection [c] | A.cpp:56:13:56:15 | call to get | +| A.cpp:57:10:57:25 | new indirection [c] | A.cpp:28:8:28:10 | *#this [c] | | A.cpp:57:10:57:25 | new indirection [c] | A.cpp:57:28:57:30 | call to get | | A.cpp:57:11:57:24 | B output argument [c] | A.cpp:57:10:57:25 | new indirection [c] | +| A.cpp:57:11:57:24 | new | A.cpp:23:10:23:10 | c | | A.cpp:57:11:57:24 | new | A.cpp:57:11:57:24 | B output argument [c] | | A.cpp:57:17:57:23 | new | A.cpp:57:11:57:24 | new | | A.cpp:98:12:98:18 | new | A.cpp:100:5:100:13 | Chi [a] | @@ -14,10 +21,12 @@ edges | A.cpp:103:14:103:14 | *c [a] | A.cpp:107:16:107:16 | a | | A.cpp:126:5:126:5 | Chi [c] | A.cpp:131:8:131:8 | f7 output argument [c] | | A.cpp:126:5:126:5 | set output argument [c] | A.cpp:126:5:126:5 | Chi [c] | +| A.cpp:126:8:126:10 | new | A.cpp:27:17:27:17 | c | | A.cpp:126:8:126:10 | new | A.cpp:126:5:126:5 | set output argument [c] | | A.cpp:126:12:126:18 | new | A.cpp:126:8:126:10 | new | | A.cpp:131:8:131:8 | Chi [c] | A.cpp:132:13:132:13 | c | | A.cpp:131:8:131:8 | f7 output argument [c] | A.cpp:131:8:131:8 | Chi [c] | +| A.cpp:140:13:140:13 | b | A.cpp:143:7:143:31 | Chi [b] | | A.cpp:142:7:142:20 | Chi [c] | A.cpp:151:18:151:18 | D output argument [c] | | A.cpp:142:14:142:20 | new | A.cpp:142:7:142:20 | Chi [c] | | A.cpp:143:7:143:31 | Chi [b] | A.cpp:151:12:151:24 | D output argument [b] | @@ -25,6 +34,7 @@ edges | A.cpp:150:12:150:18 | new | A.cpp:151:12:151:24 | b | | A.cpp:151:12:151:24 | Chi [b] | A.cpp:152:13:152:13 | b | | A.cpp:151:12:151:24 | D output argument [b] | A.cpp:151:12:151:24 | Chi [b] | +| A.cpp:151:12:151:24 | b | A.cpp:140:13:140:13 | b | | A.cpp:151:12:151:24 | b | A.cpp:151:12:151:24 | D output argument [b] | | A.cpp:151:18:151:18 | Chi [c] | A.cpp:154:13:154:13 | c | | A.cpp:151:18:151:18 | D output argument [c] | A.cpp:151:18:151:18 | Chi [c] | @@ -86,21 +96,49 @@ edges | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:10:8:10:15 | * ... | | arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:16:8:16:13 | access to array | | arrays.cpp:36:26:36:35 | call to user_input | arrays.cpp:37:24:37:27 | data | +| by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:16 | Chi [a] | +| by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:19 | Chi [a] | +| by_reference.cpp:19:28:19:32 | value | by_reference.cpp:20:11:20:21 | value | +| by_reference.cpp:20:5:20:8 | setDirectly output argument [a] | by_reference.cpp:20:5:20:8 | Chi [a] | +| by_reference.cpp:20:11:20:21 | value | by_reference.cpp:15:26:15:30 | value | +| by_reference.cpp:20:11:20:21 | value | by_reference.cpp:20:5:20:8 | setDirectly output argument [a] | +| by_reference.cpp:23:34:23:38 | value | by_reference.cpp:24:5:24:17 | value | +| by_reference.cpp:24:5:24:17 | value | by_reference.cpp:11:48:11:52 | value | +| by_reference.cpp:24:5:24:17 | value | by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] | +| by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] | by_reference.cpp:24:19:24:22 | Chi [a] | +| by_reference.cpp:31:46:31:46 | *s [a] | by_reference.cpp:32:15:32:15 | Store | +| by_reference.cpp:35:9:35:19 | *#this [a] | by_reference.cpp:36:18:36:18 | Store | +| by_reference.cpp:39:9:39:21 | *#this [a] | by_reference.cpp:40:12:40:15 | this indirection [a] | +| by_reference.cpp:40:12:40:15 | this indirection [a] | by_reference.cpp:35:9:35:19 | *#this [a] | +| by_reference.cpp:40:12:40:15 | this indirection [a] | by_reference.cpp:40:18:40:28 | call to getDirectly | +| by_reference.cpp:40:18:40:28 | call to getDirectly | by_reference.cpp:40:18:40:28 | Store | +| by_reference.cpp:43:9:43:27 | *#this [a] | by_reference.cpp:44:26:44:29 | this indirection [a] | +| by_reference.cpp:44:12:44:24 | call to nonMemberGetA | by_reference.cpp:44:12:44:24 | Store | +| by_reference.cpp:44:26:44:29 | this indirection [a] | by_reference.cpp:31:46:31:46 | *s [a] | +| by_reference.cpp:44:26:44:29 | this indirection [a] | by_reference.cpp:44:12:44:24 | call to nonMemberGetA | | by_reference.cpp:50:3:50:3 | setDirectly output argument [a] | by_reference.cpp:51:8:51:8 | s indirection [a] | +| by_reference.cpp:50:5:50:15 | call to user_input | by_reference.cpp:15:26:15:30 | value | | by_reference.cpp:50:5:50:15 | call to user_input | by_reference.cpp:50:3:50:3 | setDirectly output argument [a] | | by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:50:5:50:15 | call to user_input | +| by_reference.cpp:51:8:51:8 | s indirection [a] | by_reference.cpp:35:9:35:19 | *#this [a] | | by_reference.cpp:51:8:51:8 | s indirection [a] | by_reference.cpp:51:10:51:20 | call to getDirectly | | by_reference.cpp:56:3:56:3 | setIndirectly output argument [a] | by_reference.cpp:57:8:57:8 | s indirection [a] | +| by_reference.cpp:56:5:56:17 | call to user_input | by_reference.cpp:19:28:19:32 | value | | by_reference.cpp:56:5:56:17 | call to user_input | by_reference.cpp:56:3:56:3 | setIndirectly output argument [a] | | by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:56:5:56:17 | call to user_input | +| by_reference.cpp:57:8:57:8 | s indirection [a] | by_reference.cpp:39:9:39:21 | *#this [a] | | by_reference.cpp:57:8:57:8 | s indirection [a] | by_reference.cpp:57:10:57:22 | call to getIndirectly | | by_reference.cpp:62:3:62:3 | setThroughNonMember output argument [a] | by_reference.cpp:63:8:63:8 | s indirection [a] | +| by_reference.cpp:62:5:62:23 | call to user_input | by_reference.cpp:23:34:23:38 | value | | by_reference.cpp:62:5:62:23 | call to user_input | by_reference.cpp:62:3:62:3 | setThroughNonMember output argument [a] | | by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:62:5:62:23 | call to user_input | +| by_reference.cpp:63:8:63:8 | s indirection [a] | by_reference.cpp:43:9:43:27 | *#this [a] | | by_reference.cpp:63:8:63:8 | s indirection [a] | by_reference.cpp:63:10:63:28 | call to getThroughNonMember | +| by_reference.cpp:68:3:68:15 | call to user_input | by_reference.cpp:11:48:11:52 | value | | by_reference.cpp:68:3:68:15 | call to user_input | by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] | | by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] | by_reference.cpp:69:22:69:23 | & ... indirection [a] | | by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:68:3:68:15 | call to user_input | +| by_reference.cpp:69:22:69:23 | & ... indirection [a] | by_reference.cpp:31:46:31:46 | *s [a] | | by_reference.cpp:69:22:69:23 | & ... indirection [a] | by_reference.cpp:69:8:69:20 | call to nonMemberGetA | | by_reference.cpp:84:3:84:25 | Chi [a] | by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | | by_reference.cpp:84:3:84:25 | Chi [a] | by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] | @@ -134,48 +172,73 @@ edges | by_reference.cpp:128:15:128:23 | Chi | by_reference.cpp:128:15:128:23 | Chi [a] | | by_reference.cpp:128:15:128:23 | Chi [a] | by_reference.cpp:136:16:136:16 | a | | by_reference.cpp:128:15:128:23 | taint_a_ref output argument [[]] | by_reference.cpp:128:15:128:23 | Chi | +| complex.cpp:9:7:9:7 | *#this [a_] | complex.cpp:9:20:9:21 | Store | +| complex.cpp:10:7:10:7 | *#this [b_] | complex.cpp:10:20:10:21 | Store | +| complex.cpp:11:17:11:17 | a | complex.cpp:11:22:11:27 | Chi [a_] | +| complex.cpp:12:8:12:11 | *#this [a_] | complex.cpp:12:22:12:27 | Chi [a_] | +| complex.cpp:12:17:12:17 | b | complex.cpp:12:22:12:27 | Chi [b_] | | complex.cpp:40:17:40:17 | *b [a_] | complex.cpp:42:16:42:16 | f indirection [a_] | | complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:42:16:42:16 | f indirection [b_] | | complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:43:16:43:16 | f indirection [b_] | | complex.cpp:42:16:42:16 | a output argument [b_] | complex.cpp:43:16:43:16 | f indirection [b_] | +| complex.cpp:42:16:42:16 | f indirection [a_] | complex.cpp:9:7:9:7 | *#this [a_] | | complex.cpp:42:16:42:16 | f indirection [a_] | complex.cpp:42:18:42:18 | call to a | +| complex.cpp:42:16:42:16 | f indirection [b_] | complex.cpp:9:7:9:7 | *#this [b_] | | complex.cpp:42:16:42:16 | f indirection [b_] | complex.cpp:42:16:42:16 | a output argument [b_] | +| complex.cpp:43:16:43:16 | f indirection [b_] | complex.cpp:10:7:10:7 | *#this [b_] | | complex.cpp:43:16:43:16 | f indirection [b_] | complex.cpp:43:18:43:18 | call to b | | complex.cpp:53:12:53:12 | setA output argument [a_] | complex.cpp:59:7:59:8 | b1 indirection [a_] | +| complex.cpp:53:14:53:17 | call to user_input | complex.cpp:11:17:11:17 | a | | complex.cpp:53:14:53:17 | call to user_input | complex.cpp:53:12:53:12 | setA output argument [a_] | | complex.cpp:53:19:53:28 | call to user_input | complex.cpp:53:14:53:17 | call to user_input | | complex.cpp:54:12:54:12 | setB output argument [b_] | complex.cpp:62:7:62:8 | b2 indirection [b_] | +| complex.cpp:54:14:54:17 | call to user_input | complex.cpp:12:17:12:17 | b | | complex.cpp:54:14:54:17 | call to user_input | complex.cpp:54:12:54:12 | setB output argument [b_] | | complex.cpp:54:19:54:28 | call to user_input | complex.cpp:54:14:54:17 | call to user_input | | complex.cpp:55:12:55:12 | setA output argument [a_] | complex.cpp:56:12:56:12 | f indirection [a_] | | complex.cpp:55:12:55:12 | setA output argument [a_] | complex.cpp:65:7:65:8 | b3 indirection [a_] | +| complex.cpp:55:14:55:17 | call to user_input | complex.cpp:11:17:11:17 | a | | complex.cpp:55:14:55:17 | call to user_input | complex.cpp:55:12:55:12 | setA output argument [a_] | | complex.cpp:55:19:55:28 | call to user_input | complex.cpp:55:14:55:17 | call to user_input | +| complex.cpp:56:12:56:12 | f indirection [a_] | complex.cpp:12:8:12:11 | *#this [a_] | | complex.cpp:56:12:56:12 | f indirection [a_] | complex.cpp:56:12:56:12 | setB output argument [a_] | | complex.cpp:56:12:56:12 | setB output argument [a_] | complex.cpp:65:7:65:8 | b3 indirection [a_] | | complex.cpp:56:12:56:12 | setB output argument [b_] | complex.cpp:65:7:65:8 | b3 indirection [b_] | +| complex.cpp:56:14:56:17 | call to user_input | complex.cpp:12:17:12:17 | b | | complex.cpp:56:14:56:17 | call to user_input | complex.cpp:56:12:56:12 | setB output argument [b_] | | complex.cpp:56:19:56:28 | call to user_input | complex.cpp:56:14:56:17 | call to user_input | | complex.cpp:59:7:59:8 | b1 indirection [a_] | complex.cpp:40:17:40:17 | *b [a_] | | complex.cpp:62:7:62:8 | b2 indirection [b_] | complex.cpp:40:17:40:17 | *b [b_] | | complex.cpp:65:7:65:8 | b3 indirection [a_] | complex.cpp:40:17:40:17 | *b [a_] | | complex.cpp:65:7:65:8 | b3 indirection [b_] | complex.cpp:40:17:40:17 | *b [b_] | +| constructors.cpp:18:9:18:9 | *#this [a_] | constructors.cpp:18:22:18:23 | Store | +| constructors.cpp:19:9:19:9 | *#this [b_] | constructors.cpp:19:22:19:23 | Store | +| constructors.cpp:23:13:23:13 | a | constructors.cpp:23:28:23:28 | Chi [a_] | +| constructors.cpp:23:20:23:20 | b | constructors.cpp:23:35:23:35 | Chi [b_] | +| constructors.cpp:23:28:23:28 | Chi [a_] | constructors.cpp:23:35:23:35 | Chi [a_] | | constructors.cpp:26:15:26:15 | *f [a_] | constructors.cpp:28:10:28:10 | f indirection [a_] | | constructors.cpp:26:15:26:15 | *f [b_] | constructors.cpp:28:10:28:10 | f indirection [b_] | | constructors.cpp:26:15:26:15 | *f [b_] | constructors.cpp:29:10:29:10 | f indirection [b_] | | constructors.cpp:28:10:28:10 | a output argument [b_] | constructors.cpp:29:10:29:10 | f indirection [b_] | +| constructors.cpp:28:10:28:10 | f indirection [a_] | constructors.cpp:18:9:18:9 | *#this [a_] | | constructors.cpp:28:10:28:10 | f indirection [a_] | constructors.cpp:28:12:28:12 | call to a | +| constructors.cpp:28:10:28:10 | f indirection [b_] | constructors.cpp:18:9:18:9 | *#this [b_] | | constructors.cpp:28:10:28:10 | f indirection [b_] | constructors.cpp:28:10:28:10 | a output argument [b_] | +| constructors.cpp:29:10:29:10 | f indirection [b_] | constructors.cpp:19:9:19:9 | *#this [b_] | | constructors.cpp:29:10:29:10 | f indirection [b_] | constructors.cpp:29:12:29:12 | call to b | | constructors.cpp:34:11:34:20 | call to user_input | constructors.cpp:34:11:34:26 | call to user_input | | constructors.cpp:34:11:34:26 | Foo output argument [a_] | constructors.cpp:40:9:40:9 | f indirection [a_] | +| constructors.cpp:34:11:34:26 | call to user_input | constructors.cpp:23:13:23:13 | a | | constructors.cpp:34:11:34:26 | call to user_input | constructors.cpp:34:11:34:26 | Foo output argument [a_] | | constructors.cpp:35:11:35:26 | Foo output argument [b_] | constructors.cpp:43:9:43:9 | g indirection [b_] | +| constructors.cpp:35:11:35:26 | call to user_input | constructors.cpp:23:20:23:20 | b | | constructors.cpp:35:11:35:26 | call to user_input | constructors.cpp:35:11:35:26 | Foo output argument [b_] | | constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:35:11:35:26 | call to user_input | | constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:36:11:36:37 | call to user_input | | constructors.cpp:36:11:36:37 | Foo output argument [a_] | constructors.cpp:46:9:46:9 | h indirection [a_] | | constructors.cpp:36:11:36:37 | Foo output argument [b_] | constructors.cpp:46:9:46:9 | h indirection [b_] | +| constructors.cpp:36:11:36:37 | call to user_input | constructors.cpp:23:13:23:13 | a | +| constructors.cpp:36:11:36:37 | call to user_input | constructors.cpp:23:20:23:20 | b | | constructors.cpp:36:11:36:37 | call to user_input | constructors.cpp:36:11:36:37 | Foo output argument [a_] | | constructors.cpp:36:11:36:37 | call to user_input | constructors.cpp:36:11:36:37 | Foo output argument [b_] | | constructors.cpp:36:25:36:34 | call to user_input | constructors.cpp:36:11:36:37 | call to user_input | @@ -183,26 +246,39 @@ edges | constructors.cpp:43:9:43:9 | g indirection [b_] | constructors.cpp:26:15:26:15 | *f [b_] | | constructors.cpp:46:9:46:9 | h indirection [a_] | constructors.cpp:26:15:26:15 | *f [a_] | | constructors.cpp:46:9:46:9 | h indirection [b_] | constructors.cpp:26:15:26:15 | *f [b_] | +| simple.cpp:18:9:18:9 | *#this [a_] | simple.cpp:18:22:18:23 | Store | +| simple.cpp:19:9:19:9 | *#this [b_] | simple.cpp:19:22:19:23 | Store | +| simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:29 | Chi [a_] | +| simple.cpp:21:10:21:13 | *#this [a_] | simple.cpp:21:24:21:29 | Chi [a_] | +| simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:29 | Chi [b_] | | simple.cpp:26:15:26:15 | *f [a_] | simple.cpp:28:10:28:10 | f indirection [a_] | | simple.cpp:26:15:26:15 | *f [b_] | simple.cpp:28:10:28:10 | f indirection [b_] | | simple.cpp:26:15:26:15 | *f [b_] | simple.cpp:29:10:29:10 | f indirection [b_] | | simple.cpp:28:10:28:10 | a output argument [b_] | simple.cpp:29:10:29:10 | f indirection [b_] | +| simple.cpp:28:10:28:10 | f indirection [a_] | simple.cpp:18:9:18:9 | *#this [a_] | | simple.cpp:28:10:28:10 | f indirection [a_] | simple.cpp:28:12:28:12 | call to a | +| simple.cpp:28:10:28:10 | f indirection [b_] | simple.cpp:18:9:18:9 | *#this [b_] | | simple.cpp:28:10:28:10 | f indirection [b_] | simple.cpp:28:10:28:10 | a output argument [b_] | +| simple.cpp:29:10:29:10 | f indirection [b_] | simple.cpp:19:9:19:9 | *#this [b_] | | simple.cpp:29:10:29:10 | f indirection [b_] | simple.cpp:29:12:29:12 | call to b | | simple.cpp:39:5:39:5 | setA output argument [a_] | simple.cpp:45:9:45:9 | f indirection [a_] | +| simple.cpp:39:7:39:10 | call to user_input | simple.cpp:20:19:20:19 | a | | simple.cpp:39:7:39:10 | call to user_input | simple.cpp:39:5:39:5 | setA output argument [a_] | | simple.cpp:39:12:39:21 | call to user_input | simple.cpp:39:7:39:10 | call to user_input | | simple.cpp:40:5:40:5 | setB output argument [b_] | simple.cpp:48:9:48:9 | g indirection [b_] | +| simple.cpp:40:7:40:10 | call to user_input | simple.cpp:21:19:21:19 | b | | simple.cpp:40:7:40:10 | call to user_input | simple.cpp:40:5:40:5 | setB output argument [b_] | | simple.cpp:40:12:40:21 | call to user_input | simple.cpp:40:7:40:10 | call to user_input | | simple.cpp:41:5:41:5 | setA output argument [a_] | simple.cpp:42:5:42:5 | h indirection [a_] | | simple.cpp:41:5:41:5 | setA output argument [a_] | simple.cpp:51:9:51:9 | h indirection [a_] | +| simple.cpp:41:7:41:10 | call to user_input | simple.cpp:20:19:20:19 | a | | simple.cpp:41:7:41:10 | call to user_input | simple.cpp:41:5:41:5 | setA output argument [a_] | | simple.cpp:41:12:41:21 | call to user_input | simple.cpp:41:7:41:10 | call to user_input | +| simple.cpp:42:5:42:5 | h indirection [a_] | simple.cpp:21:10:21:13 | *#this [a_] | | simple.cpp:42:5:42:5 | h indirection [a_] | simple.cpp:42:5:42:5 | setB output argument [a_] | | simple.cpp:42:5:42:5 | setB output argument [a_] | simple.cpp:51:9:51:9 | h indirection [a_] | | simple.cpp:42:5:42:5 | setB output argument [b_] | simple.cpp:51:9:51:9 | h indirection [b_] | +| simple.cpp:42:7:42:10 | call to user_input | simple.cpp:21:19:21:19 | b | | simple.cpp:42:7:42:10 | call to user_input | simple.cpp:42:5:42:5 | setB output argument [b_] | | simple.cpp:42:12:42:21 | call to user_input | simple.cpp:42:7:42:10 | call to user_input | | simple.cpp:45:9:45:9 | f indirection [a_] | simple.cpp:26:15:26:15 | *f [a_] | @@ -212,8 +288,10 @@ edges | simple.cpp:65:5:65:22 | Store [i] | simple.cpp:66:12:66:12 | Store [i] | | simple.cpp:65:11:65:20 | call to user_input | simple.cpp:65:5:65:22 | Store [i] | | simple.cpp:66:12:66:12 | Store [i] | simple.cpp:67:13:67:13 | i | +| simple.cpp:78:9:78:15 | *#this [f1] | simple.cpp:79:19:79:20 | Store | | simple.cpp:83:9:83:28 | Store [f1] | simple.cpp:84:14:84:20 | this indirection [f1] | | simple.cpp:83:17:83:26 | call to user_input | simple.cpp:83:9:83:28 | Store [f1] | +| simple.cpp:84:14:84:20 | this indirection [f1] | simple.cpp:78:9:78:15 | *#this [f1] | | simple.cpp:84:14:84:20 | this indirection [f1] | simple.cpp:84:14:84:20 | call to getf2f1 | | simple.cpp:92:5:92:22 | Store [i] | simple.cpp:93:20:93:20 | Store [i] | | simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:5:92:22 | Store [i] | @@ -228,6 +306,12 @@ edges | struct_init.c:27:7:27:16 | call to user_input | struct_init.c:31:23:31:23 | a | | struct_init.c:36:10:36:24 | & ... indirection [a] | struct_init.c:14:24:14:25 | *ab [a] | nodes +| A.cpp:23:10:23:10 | c | semmle.label | c | +| A.cpp:25:7:25:17 | Chi [c] | semmle.label | Chi [c] | +| A.cpp:27:17:27:17 | c | semmle.label | c | +| A.cpp:27:22:27:32 | Chi [c] | semmle.label | Chi [c] | +| A.cpp:28:8:28:10 | *#this [c] | semmle.label | *#this [c] | +| A.cpp:28:29:28:29 | Store | semmle.label | Store | | A.cpp:55:5:55:5 | set output argument [c] | semmle.label | set output argument [c] | | A.cpp:55:8:55:10 | new | semmle.label | new | | A.cpp:55:12:55:19 | (C *)... | semmle.label | (C *)... | @@ -251,9 +335,11 @@ nodes | A.cpp:131:8:131:8 | Chi [c] | semmle.label | Chi [c] | | A.cpp:131:8:131:8 | f7 output argument [c] | semmle.label | f7 output argument [c] | | A.cpp:132:13:132:13 | c | semmle.label | c | +| A.cpp:140:13:140:13 | b | semmle.label | b | | A.cpp:142:7:142:20 | Chi [c] | semmle.label | Chi [c] | | A.cpp:142:14:142:20 | new | semmle.label | new | | A.cpp:143:7:143:31 | Chi [b] | semmle.label | Chi [b] | +| A.cpp:143:7:143:31 | Chi [b] | semmle.label | Chi [b] | | A.cpp:143:25:143:31 | new | semmle.label | new | | A.cpp:150:12:150:18 | new | semmle.label | new | | A.cpp:151:12:151:24 | Chi [b] | semmle.label | Chi [b] | @@ -336,6 +422,30 @@ nodes | arrays.cpp:16:8:16:13 | access to array | semmle.label | access to array | | arrays.cpp:36:26:36:35 | call to user_input | semmle.label | call to user_input | | arrays.cpp:37:24:37:27 | data | semmle.label | data | +| by_reference.cpp:11:48:11:52 | value | semmle.label | value | +| by_reference.cpp:12:5:12:16 | Chi [a] | semmle.label | Chi [a] | +| by_reference.cpp:15:26:15:30 | value | semmle.label | value | +| by_reference.cpp:16:5:16:19 | Chi [a] | semmle.label | Chi [a] | +| by_reference.cpp:19:28:19:32 | value | semmle.label | value | +| by_reference.cpp:20:5:20:8 | Chi [a] | semmle.label | Chi [a] | +| by_reference.cpp:20:5:20:8 | setDirectly output argument [a] | semmle.label | setDirectly output argument [a] | +| by_reference.cpp:20:11:20:21 | value | semmle.label | value | +| by_reference.cpp:23:34:23:38 | value | semmle.label | value | +| by_reference.cpp:24:5:24:17 | value | semmle.label | value | +| by_reference.cpp:24:19:24:22 | Chi [a] | semmle.label | Chi [a] | +| by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] | semmle.label | nonMemberSetA output argument [a] | +| by_reference.cpp:31:46:31:46 | *s [a] | semmle.label | *s [a] | +| by_reference.cpp:32:15:32:15 | Store | semmle.label | Store | +| by_reference.cpp:35:9:35:19 | *#this [a] | semmle.label | *#this [a] | +| by_reference.cpp:36:18:36:18 | Store | semmle.label | Store | +| by_reference.cpp:39:9:39:21 | *#this [a] | semmle.label | *#this [a] | +| by_reference.cpp:40:12:40:15 | this indirection [a] | semmle.label | this indirection [a] | +| by_reference.cpp:40:18:40:28 | Store | semmle.label | Store | +| by_reference.cpp:40:18:40:28 | call to getDirectly | semmle.label | call to getDirectly | +| by_reference.cpp:43:9:43:27 | *#this [a] | semmle.label | *#this [a] | +| by_reference.cpp:44:12:44:24 | Store | semmle.label | Store | +| by_reference.cpp:44:12:44:24 | call to nonMemberGetA | semmle.label | call to nonMemberGetA | +| by_reference.cpp:44:26:44:29 | this indirection [a] | semmle.label | this indirection [a] | | by_reference.cpp:50:3:50:3 | setDirectly output argument [a] | semmle.label | setDirectly output argument [a] | | by_reference.cpp:50:5:50:15 | call to user_input | semmle.label | call to user_input | | by_reference.cpp:50:17:50:26 | call to user_input | semmle.label | call to user_input | @@ -392,6 +502,17 @@ nodes | by_reference.cpp:132:14:132:14 | a | semmle.label | a | | by_reference.cpp:134:29:134:29 | a | semmle.label | a | | by_reference.cpp:136:16:136:16 | a | semmle.label | a | +| complex.cpp:9:7:9:7 | *#this [a_] | semmle.label | *#this [a_] | +| complex.cpp:9:7:9:7 | *#this [b_] | semmle.label | *#this [b_] | +| complex.cpp:9:20:9:21 | Store | semmle.label | Store | +| complex.cpp:10:7:10:7 | *#this [b_] | semmle.label | *#this [b_] | +| complex.cpp:10:20:10:21 | Store | semmle.label | Store | +| complex.cpp:11:17:11:17 | a | semmle.label | a | +| complex.cpp:11:22:11:27 | Chi [a_] | semmle.label | Chi [a_] | +| complex.cpp:12:8:12:11 | *#this [a_] | semmle.label | *#this [a_] | +| complex.cpp:12:17:12:17 | b | semmle.label | b | +| complex.cpp:12:22:12:27 | Chi [a_] | semmle.label | Chi [a_] | +| complex.cpp:12:22:12:27 | Chi [b_] | semmle.label | Chi [b_] | | complex.cpp:40:17:40:17 | *b [a_] | semmle.label | *b [a_] | | complex.cpp:40:17:40:17 | *b [b_] | semmle.label | *b [b_] | | complex.cpp:42:16:42:16 | a output argument [b_] | semmle.label | a output argument [b_] | @@ -418,6 +539,16 @@ nodes | complex.cpp:62:7:62:8 | b2 indirection [b_] | semmle.label | b2 indirection [b_] | | complex.cpp:65:7:65:8 | b3 indirection [a_] | semmle.label | b3 indirection [a_] | | complex.cpp:65:7:65:8 | b3 indirection [b_] | semmle.label | b3 indirection [b_] | +| constructors.cpp:18:9:18:9 | *#this [a_] | semmle.label | *#this [a_] | +| constructors.cpp:18:9:18:9 | *#this [b_] | semmle.label | *#this [b_] | +| constructors.cpp:18:22:18:23 | Store | semmle.label | Store | +| constructors.cpp:19:9:19:9 | *#this [b_] | semmle.label | *#this [b_] | +| constructors.cpp:19:22:19:23 | Store | semmle.label | Store | +| constructors.cpp:23:13:23:13 | a | semmle.label | a | +| constructors.cpp:23:20:23:20 | b | semmle.label | b | +| constructors.cpp:23:28:23:28 | Chi [a_] | semmle.label | Chi [a_] | +| constructors.cpp:23:35:23:35 | Chi [a_] | semmle.label | Chi [a_] | +| constructors.cpp:23:35:23:35 | Chi [b_] | semmle.label | Chi [b_] | | constructors.cpp:26:15:26:15 | *f [a_] | semmle.label | *f [a_] | | constructors.cpp:26:15:26:15 | *f [b_] | semmle.label | *f [b_] | | constructors.cpp:28:10:28:10 | a output argument [b_] | semmle.label | a output argument [b_] | @@ -442,6 +573,17 @@ nodes | constructors.cpp:43:9:43:9 | g indirection [b_] | semmle.label | g indirection [b_] | | constructors.cpp:46:9:46:9 | h indirection [a_] | semmle.label | h indirection [a_] | | constructors.cpp:46:9:46:9 | h indirection [b_] | semmle.label | h indirection [b_] | +| simple.cpp:18:9:18:9 | *#this [a_] | semmle.label | *#this [a_] | +| simple.cpp:18:9:18:9 | *#this [b_] | semmle.label | *#this [b_] | +| simple.cpp:18:22:18:23 | Store | semmle.label | Store | +| simple.cpp:19:9:19:9 | *#this [b_] | semmle.label | *#this [b_] | +| simple.cpp:19:22:19:23 | Store | semmle.label | Store | +| simple.cpp:20:19:20:19 | a | semmle.label | a | +| simple.cpp:20:24:20:29 | Chi [a_] | semmle.label | Chi [a_] | +| simple.cpp:21:10:21:13 | *#this [a_] | semmle.label | *#this [a_] | +| simple.cpp:21:19:21:19 | b | semmle.label | b | +| simple.cpp:21:24:21:29 | Chi [a_] | semmle.label | Chi [a_] | +| simple.cpp:21:24:21:29 | Chi [b_] | semmle.label | Chi [b_] | | simple.cpp:26:15:26:15 | *f [a_] | semmle.label | *f [a_] | | simple.cpp:26:15:26:15 | *f [b_] | semmle.label | *f [b_] | | simple.cpp:28:10:28:10 | a output argument [b_] | semmle.label | a output argument [b_] | @@ -472,6 +614,8 @@ nodes | simple.cpp:65:11:65:20 | call to user_input | semmle.label | call to user_input | | simple.cpp:66:12:66:12 | Store [i] | semmle.label | Store [i] | | simple.cpp:67:13:67:13 | i | semmle.label | i | +| simple.cpp:78:9:78:15 | *#this [f1] | semmle.label | *#this [f1] | +| simple.cpp:79:19:79:20 | Store | semmle.label | Store | | simple.cpp:83:9:83:28 | Store [f1] | semmle.label | Store [f1] | | simple.cpp:83:17:83:26 | call to user_input | semmle.label | call to user_input | | simple.cpp:84:14:84:20 | call to getf2f1 | semmle.label | call to getf2f1 | @@ -490,6 +634,49 @@ nodes | struct_init.c:27:7:27:16 | call to user_input | semmle.label | call to user_input | | struct_init.c:31:23:31:23 | a | semmle.label | a | | struct_init.c:36:10:36:24 | & ... indirection [a] | semmle.label | & ... indirection [a] | +subpaths +| A.cpp:55:8:55:10 | new | A.cpp:27:17:27:17 | c | A.cpp:27:22:27:32 | Chi [c] | A.cpp:55:5:55:5 | set output argument [c] | +| A.cpp:56:10:56:10 | b indirection [c] | A.cpp:28:8:28:10 | *#this [c] | A.cpp:28:29:28:29 | Store | A.cpp:56:13:56:15 | call to get | +| A.cpp:57:10:57:25 | new indirection [c] | A.cpp:28:8:28:10 | *#this [c] | A.cpp:28:29:28:29 | Store | A.cpp:57:28:57:30 | call to get | +| A.cpp:57:11:57:24 | new | A.cpp:23:10:23:10 | c | A.cpp:25:7:25:17 | Chi [c] | A.cpp:57:11:57:24 | B output argument [c] | +| A.cpp:126:8:126:10 | new | A.cpp:27:17:27:17 | c | A.cpp:27:22:27:32 | Chi [c] | A.cpp:126:5:126:5 | set output argument [c] | +| A.cpp:151:12:151:24 | b | A.cpp:140:13:140:13 | b | A.cpp:143:7:143:31 | Chi [b] | A.cpp:151:12:151:24 | D output argument [b] | +| by_reference.cpp:20:11:20:21 | value | by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:19 | Chi [a] | by_reference.cpp:20:5:20:8 | setDirectly output argument [a] | +| by_reference.cpp:24:5:24:17 | value | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:16 | Chi [a] | by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] | +| by_reference.cpp:40:12:40:15 | this indirection [a] | by_reference.cpp:35:9:35:19 | *#this [a] | by_reference.cpp:36:18:36:18 | Store | by_reference.cpp:40:18:40:28 | call to getDirectly | +| by_reference.cpp:44:26:44:29 | this indirection [a] | by_reference.cpp:31:46:31:46 | *s [a] | by_reference.cpp:32:15:32:15 | Store | by_reference.cpp:44:12:44:24 | call to nonMemberGetA | +| by_reference.cpp:50:5:50:15 | call to user_input | by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:19 | Chi [a] | by_reference.cpp:50:3:50:3 | setDirectly output argument [a] | +| by_reference.cpp:51:8:51:8 | s indirection [a] | by_reference.cpp:35:9:35:19 | *#this [a] | by_reference.cpp:36:18:36:18 | Store | by_reference.cpp:51:10:51:20 | call to getDirectly | +| by_reference.cpp:56:5:56:17 | call to user_input | by_reference.cpp:19:28:19:32 | value | by_reference.cpp:20:5:20:8 | Chi [a] | by_reference.cpp:56:3:56:3 | setIndirectly output argument [a] | +| by_reference.cpp:57:8:57:8 | s indirection [a] | by_reference.cpp:39:9:39:21 | *#this [a] | by_reference.cpp:40:18:40:28 | Store | by_reference.cpp:57:10:57:22 | call to getIndirectly | +| by_reference.cpp:62:5:62:23 | call to user_input | by_reference.cpp:23:34:23:38 | value | by_reference.cpp:24:19:24:22 | Chi [a] | by_reference.cpp:62:3:62:3 | setThroughNonMember output argument [a] | +| by_reference.cpp:63:8:63:8 | s indirection [a] | by_reference.cpp:43:9:43:27 | *#this [a] | by_reference.cpp:44:12:44:24 | Store | by_reference.cpp:63:10:63:28 | call to getThroughNonMember | +| by_reference.cpp:68:3:68:15 | call to user_input | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:16 | Chi [a] | by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] | +| by_reference.cpp:69:22:69:23 | & ... indirection [a] | by_reference.cpp:31:46:31:46 | *s [a] | by_reference.cpp:32:15:32:15 | Store | by_reference.cpp:69:8:69:20 | call to nonMemberGetA | +| complex.cpp:42:16:42:16 | f indirection [a_] | complex.cpp:9:7:9:7 | *#this [a_] | complex.cpp:9:20:9:21 | Store | complex.cpp:42:18:42:18 | call to a | +| complex.cpp:42:16:42:16 | f indirection [b_] | complex.cpp:9:7:9:7 | *#this [b_] | complex.cpp:9:7:9:7 | *#this [b_] | complex.cpp:42:16:42:16 | a output argument [b_] | +| complex.cpp:43:16:43:16 | f indirection [b_] | complex.cpp:10:7:10:7 | *#this [b_] | complex.cpp:10:20:10:21 | Store | complex.cpp:43:18:43:18 | call to b | +| complex.cpp:53:14:53:17 | call to user_input | complex.cpp:11:17:11:17 | a | complex.cpp:11:22:11:27 | Chi [a_] | complex.cpp:53:12:53:12 | setA output argument [a_] | +| complex.cpp:54:14:54:17 | call to user_input | complex.cpp:12:17:12:17 | b | complex.cpp:12:22:12:27 | Chi [b_] | complex.cpp:54:12:54:12 | setB output argument [b_] | +| complex.cpp:55:14:55:17 | call to user_input | complex.cpp:11:17:11:17 | a | complex.cpp:11:22:11:27 | Chi [a_] | complex.cpp:55:12:55:12 | setA output argument [a_] | +| complex.cpp:56:12:56:12 | f indirection [a_] | complex.cpp:12:8:12:11 | *#this [a_] | complex.cpp:12:22:12:27 | Chi [a_] | complex.cpp:56:12:56:12 | setB output argument [a_] | +| complex.cpp:56:14:56:17 | call to user_input | complex.cpp:12:17:12:17 | b | complex.cpp:12:22:12:27 | Chi [b_] | complex.cpp:56:12:56:12 | setB output argument [b_] | +| constructors.cpp:28:10:28:10 | f indirection [a_] | constructors.cpp:18:9:18:9 | *#this [a_] | constructors.cpp:18:22:18:23 | Store | constructors.cpp:28:12:28:12 | call to a | +| constructors.cpp:28:10:28:10 | f indirection [b_] | constructors.cpp:18:9:18:9 | *#this [b_] | constructors.cpp:18:9:18:9 | *#this [b_] | constructors.cpp:28:10:28:10 | a output argument [b_] | +| constructors.cpp:29:10:29:10 | f indirection [b_] | constructors.cpp:19:9:19:9 | *#this [b_] | constructors.cpp:19:22:19:23 | Store | constructors.cpp:29:12:29:12 | call to b | +| constructors.cpp:34:11:34:26 | call to user_input | constructors.cpp:23:13:23:13 | a | constructors.cpp:23:35:23:35 | Chi [a_] | constructors.cpp:34:11:34:26 | Foo output argument [a_] | +| constructors.cpp:35:11:35:26 | call to user_input | constructors.cpp:23:20:23:20 | b | constructors.cpp:23:35:23:35 | Chi [b_] | constructors.cpp:35:11:35:26 | Foo output argument [b_] | +| constructors.cpp:36:11:36:37 | call to user_input | constructors.cpp:23:13:23:13 | a | constructors.cpp:23:35:23:35 | Chi [a_] | constructors.cpp:36:11:36:37 | Foo output argument [a_] | +| constructors.cpp:36:11:36:37 | call to user_input | constructors.cpp:23:20:23:20 | b | constructors.cpp:23:35:23:35 | Chi [b_] | constructors.cpp:36:11:36:37 | Foo output argument [b_] | +| simple.cpp:28:10:28:10 | f indirection [a_] | simple.cpp:18:9:18:9 | *#this [a_] | simple.cpp:18:22:18:23 | Store | simple.cpp:28:12:28:12 | call to a | +| simple.cpp:28:10:28:10 | f indirection [b_] | simple.cpp:18:9:18:9 | *#this [b_] | simple.cpp:18:9:18:9 | *#this [b_] | simple.cpp:28:10:28:10 | a output argument [b_] | +| simple.cpp:29:10:29:10 | f indirection [b_] | simple.cpp:19:9:19:9 | *#this [b_] | simple.cpp:19:22:19:23 | Store | simple.cpp:29:12:29:12 | call to b | +| simple.cpp:39:7:39:10 | call to user_input | simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:29 | Chi [a_] | simple.cpp:39:5:39:5 | setA output argument [a_] | +| simple.cpp:40:7:40:10 | call to user_input | simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:29 | Chi [b_] | simple.cpp:40:5:40:5 | setB output argument [b_] | +| simple.cpp:41:7:41:10 | call to user_input | simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:29 | Chi [a_] | simple.cpp:41:5:41:5 | setA output argument [a_] | +| simple.cpp:42:5:42:5 | h indirection [a_] | simple.cpp:21:10:21:13 | *#this [a_] | simple.cpp:21:24:21:29 | Chi [a_] | simple.cpp:42:5:42:5 | setB output argument [a_] | +| simple.cpp:42:7:42:10 | call to user_input | simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:29 | Chi [b_] | simple.cpp:42:5:42:5 | setB output argument [b_] | +| simple.cpp:84:14:84:20 | this indirection [f1] | simple.cpp:78:9:78:15 | *#this [f1] | simple.cpp:79:19:79:20 | Store | simple.cpp:84:14:84:20 | call to getf2f1 | #select | A.cpp:56:13:56:15 | call to get | A.cpp:55:12:55:19 | (C *)... | A.cpp:56:13:56:15 | call to get | call to get flows from $@ | A.cpp:55:12:55:19 | (C *)... | (C *)... | | A.cpp:56:13:56:15 | call to get | A.cpp:55:12:55:19 | new | A.cpp:56:13:56:15 | call to get | call to get flows from $@ | A.cpp:55:12:55:19 | new | new | diff --git a/cpp/ql/test/library-tests/dataflow/fields/path-flow.expected b/cpp/ql/test/library-tests/dataflow/fields/path-flow.expected index 6604dde87d4..7af6f7f488c 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/path-flow.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/path-flow.expected @@ -1,21 +1,46 @@ edges +| A.cpp:23:10:23:10 | c | A.cpp:25:7:25:17 | ... = ... | +| A.cpp:25:7:25:17 | ... = ... | A.cpp:25:7:25:10 | this [post update] [c] | +| A.cpp:27:17:27:17 | c | A.cpp:27:22:27:32 | ... = ... | +| A.cpp:27:22:27:32 | ... = ... | A.cpp:27:22:27:25 | this [post update] [c] | +| A.cpp:28:8:28:10 | this [c] | A.cpp:28:23:28:26 | this [c] | +| A.cpp:28:23:28:26 | this [c] | A.cpp:28:29:28:29 | c | +| A.cpp:29:23:29:23 | c | A.cpp:31:20:31:20 | c | +| A.cpp:31:14:31:21 | call to B [c] | A.cpp:31:14:31:21 | new [c] | +| A.cpp:31:20:31:20 | c | A.cpp:23:10:23:10 | c | +| A.cpp:31:20:31:20 | c | A.cpp:31:14:31:21 | call to B [c] | | A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... | | A.cpp:47:12:47:18 | new | A.cpp:48:20:48:20 | c | | A.cpp:48:12:48:18 | call to make [c] | A.cpp:49:10:49:10 | b [c] | +| A.cpp:48:20:48:20 | c | A.cpp:29:23:29:23 | c | | A.cpp:48:20:48:20 | c | A.cpp:48:12:48:18 | call to make [c] | | A.cpp:49:10:49:10 | b [c] | A.cpp:49:13:49:13 | c | | A.cpp:55:5:55:5 | ref arg b [c] | A.cpp:56:10:56:10 | b [c] | +| A.cpp:55:12:55:19 | new | A.cpp:27:17:27:17 | c | | A.cpp:55:12:55:19 | new | A.cpp:55:5:55:5 | ref arg b [c] | +| A.cpp:56:10:56:10 | b [c] | A.cpp:28:8:28:10 | this [c] | | A.cpp:56:10:56:10 | b [c] | A.cpp:56:13:56:15 | call to get | | A.cpp:57:11:57:24 | call to B [c] | A.cpp:57:11:57:24 | new [c] | +| A.cpp:57:11:57:24 | new [c] | A.cpp:28:8:28:10 | this [c] | | A.cpp:57:11:57:24 | new [c] | A.cpp:57:28:57:30 | call to get | +| A.cpp:57:17:57:23 | new | A.cpp:23:10:23:10 | c | | A.cpp:57:17:57:23 | new | A.cpp:57:11:57:24 | call to B [c] | | A.cpp:64:10:64:15 | call to setOnB [c] | A.cpp:66:10:66:11 | b2 [c] | | A.cpp:64:21:64:28 | new | A.cpp:64:10:64:15 | call to setOnB [c] | +| A.cpp:64:21:64:28 | new | A.cpp:85:26:85:26 | c | | A.cpp:66:10:66:11 | b2 [c] | A.cpp:66:14:66:14 | c | | A.cpp:73:10:73:19 | call to setOnBWrap [c] | A.cpp:75:10:75:11 | b2 [c] | | A.cpp:73:25:73:32 | new | A.cpp:73:10:73:19 | call to setOnBWrap [c] | +| A.cpp:73:25:73:32 | new | A.cpp:78:27:78:27 | c | | A.cpp:75:10:75:11 | b2 [c] | A.cpp:75:14:75:14 | c | +| A.cpp:78:27:78:27 | c | A.cpp:81:21:81:21 | c | +| A.cpp:81:10:81:15 | call to setOnB [c] | A.cpp:82:12:82:24 | ... ? ... : ... [c] | +| A.cpp:81:21:81:21 | c | A.cpp:81:10:81:15 | call to setOnB [c] | +| A.cpp:81:21:81:21 | c | A.cpp:85:26:85:26 | c | +| A.cpp:85:26:85:26 | c | A.cpp:90:15:90:15 | c | +| A.cpp:90:7:90:8 | ref arg b2 [c] | A.cpp:91:14:91:15 | b2 [c] | +| A.cpp:90:15:90:15 | c | A.cpp:27:17:27:17 | c | +| A.cpp:90:15:90:15 | c | A.cpp:90:7:90:8 | ref arg b2 [c] | | A.cpp:98:12:98:18 | new | A.cpp:100:5:100:13 | ... = ... | | A.cpp:100:5:100:6 | c1 [post update] [a] | A.cpp:101:8:101:9 | c1 [a] | | A.cpp:100:5:100:13 | ... = ... | A.cpp:100:5:100:6 | c1 [post update] [a] | @@ -25,9 +50,11 @@ edges | A.cpp:107:12:107:13 | c1 [a] | A.cpp:107:16:107:16 | a | | A.cpp:120:12:120:13 | c1 [a] | A.cpp:120:16:120:16 | a | | A.cpp:126:5:126:5 | ref arg b [c] | A.cpp:131:8:131:8 | ref arg b [c] | +| A.cpp:126:12:126:18 | new | A.cpp:27:17:27:17 | c | | A.cpp:126:12:126:18 | new | A.cpp:126:5:126:5 | ref arg b [c] | | A.cpp:131:8:131:8 | ref arg b [c] | A.cpp:132:10:132:10 | b [c] | | A.cpp:132:10:132:10 | b [c] | A.cpp:132:13:132:13 | c | +| A.cpp:140:13:140:13 | b | A.cpp:143:7:143:31 | ... = ... | | A.cpp:142:7:142:7 | b [post update] [c] | A.cpp:143:7:143:31 | ... = ... [c] | | A.cpp:142:7:142:7 | b [post update] [c] | A.cpp:151:18:151:18 | ref arg b [c] | | A.cpp:142:7:142:20 | ... = ... | A.cpp:142:7:142:7 | b [post update] [c] | @@ -35,11 +62,13 @@ edges | A.cpp:143:7:143:10 | this [post update] [b, c] | A.cpp:151:12:151:24 | call to D [b, c] | | A.cpp:143:7:143:10 | this [post update] [b] | A.cpp:151:12:151:24 | call to D [b] | | A.cpp:143:7:143:31 | ... = ... | A.cpp:143:7:143:10 | this [post update] [b] | +| A.cpp:143:7:143:31 | ... = ... | A.cpp:143:7:143:10 | this [post update] [b] | | A.cpp:143:7:143:31 | ... = ... [c] | A.cpp:143:7:143:10 | this [post update] [b, c] | | A.cpp:143:25:143:31 | new | A.cpp:143:7:143:31 | ... = ... | | A.cpp:150:12:150:18 | new | A.cpp:151:18:151:18 | b | | A.cpp:151:12:151:24 | call to D [b, c] | A.cpp:153:10:153:10 | d [b, c] | | A.cpp:151:12:151:24 | call to D [b] | A.cpp:152:10:152:10 | d [b] | +| A.cpp:151:18:151:18 | b | A.cpp:140:13:140:13 | b | | A.cpp:151:18:151:18 | b | A.cpp:151:12:151:24 | call to D [b] | | A.cpp:151:18:151:18 | ref arg b [c] | A.cpp:154:10:154:10 | b [c] | | A.cpp:152:10:152:10 | d [b] | A.cpp:152:13:152:13 | b | @@ -49,11 +78,14 @@ edges | A.cpp:159:12:159:18 | new | A.cpp:160:29:160:29 | b | | A.cpp:160:18:160:60 | call to MyList [head] | A.cpp:161:38:161:39 | l1 [head] | | A.cpp:160:29:160:29 | b | A.cpp:160:18:160:60 | call to MyList [head] | +| A.cpp:160:29:160:29 | b | A.cpp:181:15:181:21 | newHead | | A.cpp:161:18:161:40 | call to MyList [next, head] | A.cpp:162:38:162:39 | l2 [next, head] | | A.cpp:161:38:161:39 | l1 [head] | A.cpp:161:18:161:40 | call to MyList [next, head] | +| A.cpp:161:38:161:39 | l1 [head] | A.cpp:181:32:181:35 | next [head] | | A.cpp:162:18:162:40 | call to MyList [next, next, head] | A.cpp:165:10:165:11 | l3 [next, next, head] | | A.cpp:162:18:162:40 | call to MyList [next, next, head] | A.cpp:167:44:167:44 | l [next, next, head] | | A.cpp:162:38:162:39 | l2 [next, head] | A.cpp:162:18:162:40 | call to MyList [next, next, head] | +| A.cpp:162:38:162:39 | l2 [next, head] | A.cpp:181:32:181:35 | next [next, head] | | A.cpp:165:10:165:11 | l3 [next, next, head] | A.cpp:165:14:165:17 | next [next, head] | | A.cpp:165:14:165:17 | next [next, head] | A.cpp:165:20:165:23 | next [head] | | A.cpp:165:20:165:23 | next [head] | A.cpp:165:26:165:29 | head | @@ -62,20 +94,38 @@ edges | A.cpp:167:47:167:50 | next [head] | A.cpp:169:12:169:12 | l [head] | | A.cpp:167:47:167:50 | next [next, head] | A.cpp:167:44:167:44 | l [next, head] | | A.cpp:169:12:169:12 | l [head] | A.cpp:169:15:169:18 | head | +| A.cpp:181:15:181:21 | newHead | A.cpp:183:7:183:20 | ... = ... | +| A.cpp:181:32:181:35 | next [head] | A.cpp:184:7:184:23 | ... = ... [head] | +| A.cpp:181:32:181:35 | next [next, head] | A.cpp:184:7:184:23 | ... = ... [next, head] | +| A.cpp:183:7:183:20 | ... = ... | A.cpp:183:7:183:10 | this [post update] [head] | +| A.cpp:184:7:184:23 | ... = ... [head] | A.cpp:184:7:184:10 | this [post update] [next, head] | +| A.cpp:184:7:184:23 | ... = ... [next, head] | A.cpp:184:7:184:10 | this [post update] [next, next, head] | | B.cpp:6:15:6:24 | new | B.cpp:7:25:7:25 | e | | B.cpp:7:16:7:35 | call to Box1 [elem1] | B.cpp:8:25:8:26 | b1 [elem1] | | B.cpp:7:25:7:25 | e | B.cpp:7:16:7:35 | call to Box1 [elem1] | +| B.cpp:7:25:7:25 | e | B.cpp:33:16:33:17 | e1 | | B.cpp:8:16:8:27 | call to Box2 [box1, elem1] | B.cpp:9:10:9:11 | b2 [box1, elem1] | | B.cpp:8:25:8:26 | b1 [elem1] | B.cpp:8:16:8:27 | call to Box2 [box1, elem1] | +| B.cpp:8:25:8:26 | b1 [elem1] | B.cpp:44:16:44:17 | b1 [elem1] | | B.cpp:9:10:9:11 | b2 [box1, elem1] | B.cpp:9:14:9:17 | box1 [elem1] | | B.cpp:9:14:9:17 | box1 [elem1] | B.cpp:9:20:9:24 | elem1 | | B.cpp:15:15:15:27 | new | B.cpp:16:37:16:37 | e | | B.cpp:16:16:16:38 | call to Box1 [elem2] | B.cpp:17:25:17:26 | b1 [elem2] | | B.cpp:16:37:16:37 | e | B.cpp:16:16:16:38 | call to Box1 [elem2] | +| B.cpp:16:37:16:37 | e | B.cpp:33:26:33:27 | e2 | | B.cpp:17:16:17:27 | call to Box2 [box1, elem2] | B.cpp:19:10:19:11 | b2 [box1, elem2] | | B.cpp:17:25:17:26 | b1 [elem2] | B.cpp:17:16:17:27 | call to Box2 [box1, elem2] | +| B.cpp:17:25:17:26 | b1 [elem2] | B.cpp:44:16:44:17 | b1 [elem2] | | B.cpp:19:10:19:11 | b2 [box1, elem2] | B.cpp:19:14:19:17 | box1 [elem2] | | B.cpp:19:14:19:17 | box1 [elem2] | B.cpp:19:20:19:24 | elem2 | +| B.cpp:33:16:33:17 | e1 | B.cpp:35:7:35:22 | ... = ... | +| B.cpp:33:26:33:27 | e2 | B.cpp:36:7:36:22 | ... = ... | +| B.cpp:35:7:35:22 | ... = ... | B.cpp:35:7:35:10 | this [post update] [elem1] | +| B.cpp:36:7:36:22 | ... = ... | B.cpp:36:7:36:10 | this [post update] [elem2] | +| B.cpp:44:16:44:17 | b1 [elem1] | B.cpp:46:7:46:21 | ... = ... [elem1] | +| B.cpp:44:16:44:17 | b1 [elem2] | B.cpp:46:7:46:21 | ... = ... [elem2] | +| B.cpp:46:7:46:21 | ... = ... [elem1] | B.cpp:46:7:46:10 | this [post update] [box1, elem1] | +| B.cpp:46:7:46:21 | ... = ... [elem2] | B.cpp:46:7:46:10 | this [post update] [box1, elem2] | | C.cpp:18:12:18:18 | call to C [s1] | C.cpp:19:5:19:5 | c [s1] | | C.cpp:18:12:18:18 | call to C [s3] | C.cpp:19:5:19:5 | c [s3] | | C.cpp:19:5:19:5 | c [s1] | C.cpp:27:8:27:11 | this [s1] | @@ -89,8 +139,16 @@ edges | C.cpp:27:8:27:11 | this [s3] | C.cpp:31:10:31:11 | this [s3] | | C.cpp:29:10:29:11 | this [s1] | C.cpp:29:10:29:11 | s1 | | C.cpp:31:10:31:11 | this [s3] | C.cpp:31:10:31:11 | s3 | +| D.cpp:10:11:10:17 | this [elem] | D.cpp:10:30:10:33 | this [elem] | +| D.cpp:10:30:10:33 | this [elem] | D.cpp:10:30:10:33 | elem | +| D.cpp:11:24:11:24 | e | D.cpp:11:29:11:36 | ... = ... | +| D.cpp:11:29:11:36 | ... = ... | D.cpp:11:29:11:32 | this [post update] [elem] | +| D.cpp:17:11:17:17 | this [box, elem] | D.cpp:17:30:17:32 | this [box, elem] | +| D.cpp:17:30:17:32 | this [box, elem] | D.cpp:17:30:17:32 | box [elem] | | D.cpp:21:30:21:31 | b2 [box, elem] | D.cpp:22:10:22:11 | b2 [box, elem] | +| D.cpp:22:10:22:11 | b2 [box, elem] | D.cpp:17:11:17:17 | this [box, elem] | | D.cpp:22:10:22:11 | b2 [box, elem] | D.cpp:22:14:22:20 | call to getBox1 [elem] | +| D.cpp:22:14:22:20 | call to getBox1 [elem] | D.cpp:10:11:10:17 | this [elem] | | D.cpp:22:14:22:20 | call to getBox1 [elem] | D.cpp:22:25:22:31 | call to getElem | | D.cpp:28:15:28:24 | new | D.cpp:30:5:30:20 | ... = ... | | D.cpp:30:5:30:5 | b [post update] [box, elem] | D.cpp:31:14:31:14 | b [box, elem] | @@ -100,6 +158,7 @@ edges | D.cpp:35:15:35:24 | new | D.cpp:37:21:37:21 | e | | D.cpp:37:5:37:5 | b [post update] [box, elem] | D.cpp:38:14:38:14 | b [box, elem] | | D.cpp:37:8:37:10 | ref arg box [elem] | D.cpp:37:5:37:5 | b [post update] [box, elem] | +| D.cpp:37:21:37:21 | e | D.cpp:11:24:11:24 | e | | D.cpp:37:21:37:21 | e | D.cpp:37:8:37:10 | ref arg box [elem] | | D.cpp:38:14:38:14 | b [box, elem] | D.cpp:21:30:21:31 | b2 [box, elem] | | D.cpp:42:15:42:24 | new | D.cpp:44:5:44:26 | ... = ... | @@ -110,6 +169,7 @@ edges | D.cpp:49:15:49:24 | new | D.cpp:51:27:51:27 | e | | D.cpp:51:5:51:5 | ref arg b [box, elem] | D.cpp:52:14:52:14 | b [box, elem] | | D.cpp:51:8:51:14 | ref arg call to getBox1 [elem] | D.cpp:51:5:51:5 | ref arg b [box, elem] | +| D.cpp:51:27:51:27 | e | D.cpp:11:24:11:24 | e | | D.cpp:51:27:51:27 | e | D.cpp:51:8:51:14 | ref arg call to getBox1 [elem] | | D.cpp:52:14:52:14 | b [box, elem] | D.cpp:21:30:21:31 | b2 [box, elem] | | D.cpp:56:15:56:24 | new | D.cpp:58:5:58:27 | ... = ... | @@ -223,17 +283,45 @@ edges | arrays.cpp:44:8:44:25 | access to array [data] | arrays.cpp:44:27:44:30 | data | | arrays.cpp:44:10:44:17 | indirect [arr, data] | arrays.cpp:44:20:44:22 | arr [data] | | arrays.cpp:44:20:44:22 | arr [data] | arrays.cpp:44:8:44:25 | access to array [data] | +| by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:16 | ... = ... | +| by_reference.cpp:12:5:12:16 | ... = ... | by_reference.cpp:12:5:12:5 | s [post update] [a] | +| by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:19 | ... = ... | +| by_reference.cpp:16:5:16:19 | ... = ... | by_reference.cpp:16:5:16:8 | this [post update] [a] | +| by_reference.cpp:19:28:19:32 | value | by_reference.cpp:20:23:20:27 | value | +| by_reference.cpp:20:23:20:27 | value | by_reference.cpp:15:26:15:30 | value | +| by_reference.cpp:20:23:20:27 | value | by_reference.cpp:20:5:20:8 | ref arg this [a] | +| by_reference.cpp:23:34:23:38 | value | by_reference.cpp:24:25:24:29 | value | +| by_reference.cpp:24:25:24:29 | value | by_reference.cpp:11:48:11:52 | value | +| by_reference.cpp:24:25:24:29 | value | by_reference.cpp:24:19:24:22 | ref arg this [a] | +| by_reference.cpp:31:46:31:46 | s [a] | by_reference.cpp:32:12:32:12 | s [a] | +| by_reference.cpp:32:12:32:12 | s [a] | by_reference.cpp:32:15:32:15 | a | +| by_reference.cpp:35:9:35:19 | this [a] | by_reference.cpp:36:12:36:15 | this [a] | +| by_reference.cpp:36:12:36:15 | this [a] | by_reference.cpp:36:18:36:18 | a | +| by_reference.cpp:39:9:39:21 | this [a] | by_reference.cpp:40:12:40:15 | this [a] | +| by_reference.cpp:40:12:40:15 | this [a] | by_reference.cpp:35:9:35:19 | this [a] | +| by_reference.cpp:40:12:40:15 | this [a] | by_reference.cpp:40:18:40:28 | call to getDirectly | +| by_reference.cpp:43:9:43:27 | this [a] | by_reference.cpp:44:26:44:29 | this [a] | +| by_reference.cpp:44:26:44:29 | this [a] | by_reference.cpp:31:46:31:46 | s [a] | +| by_reference.cpp:44:26:44:29 | this [a] | by_reference.cpp:44:12:44:24 | call to nonMemberGetA | | by_reference.cpp:50:3:50:3 | ref arg s [a] | by_reference.cpp:51:8:51:8 | s [a] | +| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:15:26:15:30 | value | | by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:50:3:50:3 | ref arg s [a] | +| by_reference.cpp:51:8:51:8 | s [a] | by_reference.cpp:35:9:35:19 | this [a] | | by_reference.cpp:51:8:51:8 | s [a] | by_reference.cpp:51:10:51:20 | call to getDirectly | | by_reference.cpp:56:3:56:3 | ref arg s [a] | by_reference.cpp:57:8:57:8 | s [a] | +| by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:19:28:19:32 | value | | by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:56:3:56:3 | ref arg s [a] | +| by_reference.cpp:57:8:57:8 | s [a] | by_reference.cpp:39:9:39:21 | this [a] | | by_reference.cpp:57:8:57:8 | s [a] | by_reference.cpp:57:10:57:22 | call to getIndirectly | | by_reference.cpp:62:3:62:3 | ref arg s [a] | by_reference.cpp:63:8:63:8 | s [a] | +| by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:23:34:23:38 | value | | by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:62:3:62:3 | ref arg s [a] | +| by_reference.cpp:63:8:63:8 | s [a] | by_reference.cpp:43:9:43:27 | this [a] | | by_reference.cpp:63:8:63:8 | s [a] | by_reference.cpp:63:10:63:28 | call to getThroughNonMember | | by_reference.cpp:68:17:68:18 | ref arg & ... [a] | by_reference.cpp:69:22:69:23 | & ... [a] | +| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:11:48:11:52 | value | | by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:68:17:68:18 | ref arg & ... [a] | +| by_reference.cpp:69:22:69:23 | & ... [a] | by_reference.cpp:31:46:31:46 | s [a] | | by_reference.cpp:69:22:69:23 | & ... [a] | by_reference.cpp:69:8:69:20 | call to nonMemberGetA | | by_reference.cpp:84:3:84:7 | inner [post update] [a] | by_reference.cpp:102:21:102:39 | ref arg & ... [a] | | by_reference.cpp:84:3:84:7 | inner [post update] [a] | by_reference.cpp:103:27:103:35 | ref arg inner_ptr [a] | @@ -308,29 +396,43 @@ edges | by_reference.cpp:135:8:135:13 | pouter [inner_ptr, a] | by_reference.cpp:135:16:135:24 | inner_ptr [a] | | by_reference.cpp:135:16:135:24 | inner_ptr [a] | by_reference.cpp:135:27:135:27 | a | | by_reference.cpp:136:8:136:13 | pouter [a] | by_reference.cpp:136:16:136:16 | a | +| complex.cpp:9:7:9:7 | this [a_] | complex.cpp:9:20:9:21 | this [a_] | +| complex.cpp:9:20:9:21 | this [a_] | complex.cpp:9:20:9:21 | a_ | +| complex.cpp:10:7:10:7 | this [b_] | complex.cpp:10:20:10:21 | this [b_] | +| complex.cpp:10:20:10:21 | this [b_] | complex.cpp:10:20:10:21 | b_ | +| complex.cpp:11:17:11:17 | a | complex.cpp:11:22:11:27 | ... = ... | +| complex.cpp:11:22:11:27 | ... = ... | complex.cpp:11:22:11:23 | this [post update] [a_] | +| complex.cpp:12:17:12:17 | b | complex.cpp:12:22:12:27 | ... = ... | +| complex.cpp:12:22:12:27 | ... = ... | complex.cpp:12:22:12:23 | this [post update] [b_] | | complex.cpp:40:17:40:17 | b [inner, f, a_] | complex.cpp:42:8:42:8 | b [inner, f, a_] | | complex.cpp:40:17:40:17 | b [inner, f, b_] | complex.cpp:43:8:43:8 | b [inner, f, b_] | | complex.cpp:42:8:42:8 | b [inner, f, a_] | complex.cpp:42:10:42:14 | inner [f, a_] | | complex.cpp:42:10:42:14 | inner [f, a_] | complex.cpp:42:16:42:16 | f [a_] | +| complex.cpp:42:16:42:16 | f [a_] | complex.cpp:9:7:9:7 | this [a_] | | complex.cpp:42:16:42:16 | f [a_] | complex.cpp:42:18:42:18 | call to a | | complex.cpp:43:8:43:8 | b [inner, f, b_] | complex.cpp:43:10:43:14 | inner [f, b_] | | complex.cpp:43:10:43:14 | inner [f, b_] | complex.cpp:43:16:43:16 | f [b_] | +| complex.cpp:43:16:43:16 | f [b_] | complex.cpp:10:7:10:7 | this [b_] | | complex.cpp:43:16:43:16 | f [b_] | complex.cpp:43:18:43:18 | call to b | | complex.cpp:53:3:53:4 | b1 [post update] [inner, f, a_] | complex.cpp:59:7:59:8 | b1 [inner, f, a_] | | complex.cpp:53:6:53:10 | inner [post update] [f, a_] | complex.cpp:53:3:53:4 | b1 [post update] [inner, f, a_] | | complex.cpp:53:12:53:12 | ref arg f [a_] | complex.cpp:53:6:53:10 | inner [post update] [f, a_] | +| complex.cpp:53:19:53:28 | call to user_input | complex.cpp:11:17:11:17 | a | | complex.cpp:53:19:53:28 | call to user_input | complex.cpp:53:12:53:12 | ref arg f [a_] | | complex.cpp:54:3:54:4 | b2 [post update] [inner, f, b_] | complex.cpp:62:7:62:8 | b2 [inner, f, b_] | | complex.cpp:54:6:54:10 | inner [post update] [f, b_] | complex.cpp:54:3:54:4 | b2 [post update] [inner, f, b_] | | complex.cpp:54:12:54:12 | ref arg f [b_] | complex.cpp:54:6:54:10 | inner [post update] [f, b_] | +| complex.cpp:54:19:54:28 | call to user_input | complex.cpp:12:17:12:17 | b | | complex.cpp:54:19:54:28 | call to user_input | complex.cpp:54:12:54:12 | ref arg f [b_] | | complex.cpp:55:3:55:4 | b3 [post update] [inner, f, a_] | complex.cpp:65:7:65:8 | b3 [inner, f, a_] | | complex.cpp:55:6:55:10 | inner [post update] [f, a_] | complex.cpp:55:3:55:4 | b3 [post update] [inner, f, a_] | | complex.cpp:55:12:55:12 | ref arg f [a_] | complex.cpp:55:6:55:10 | inner [post update] [f, a_] | +| complex.cpp:55:19:55:28 | call to user_input | complex.cpp:11:17:11:17 | a | | complex.cpp:55:19:55:28 | call to user_input | complex.cpp:55:12:55:12 | ref arg f [a_] | | complex.cpp:56:3:56:4 | b3 [post update] [inner, f, b_] | complex.cpp:65:7:65:8 | b3 [inner, f, b_] | | complex.cpp:56:6:56:10 | inner [post update] [f, b_] | complex.cpp:56:3:56:4 | b3 [post update] [inner, f, b_] | | complex.cpp:56:12:56:12 | ref arg f [b_] | complex.cpp:56:6:56:10 | inner [post update] [f, b_] | +| complex.cpp:56:19:56:28 | call to user_input | complex.cpp:12:17:12:17 | b | | complex.cpp:56:19:56:28 | call to user_input | complex.cpp:56:12:56:12 | ref arg f [b_] | | complex.cpp:59:7:59:8 | b1 [inner, f, a_] | complex.cpp:40:17:40:17 | b [inner, f, a_] | | complex.cpp:62:7:62:8 | b2 [inner, f, b_] | complex.cpp:40:17:40:17 | b [inner, f, b_] | @@ -357,22 +459,43 @@ edges | conflated.cpp:60:17:60:26 | call to user_input | conflated.cpp:60:3:60:28 | ... = ... | | conflated.cpp:61:8:61:9 | ll [next, y] | conflated.cpp:61:12:61:15 | next [y] | | conflated.cpp:61:12:61:15 | next [y] | conflated.cpp:61:18:61:18 | y | +| constructors.cpp:18:9:18:9 | this [a_] | constructors.cpp:18:22:18:23 | this [a_] | +| constructors.cpp:18:22:18:23 | this [a_] | constructors.cpp:18:22:18:23 | a_ | +| constructors.cpp:19:9:19:9 | this [b_] | constructors.cpp:19:22:19:23 | this [b_] | +| constructors.cpp:19:22:19:23 | this [b_] | constructors.cpp:19:22:19:23 | b_ | +| constructors.cpp:23:13:23:13 | a | constructors.cpp:23:28:23:28 | a | +| constructors.cpp:23:20:23:20 | b | constructors.cpp:23:35:23:35 | b | +| constructors.cpp:23:28:23:28 | a | constructors.cpp:23:25:23:29 | constructor init of field a_ [post-this] [a_] | +| constructors.cpp:23:35:23:35 | b | constructors.cpp:23:32:23:36 | constructor init of field b_ [post-this] [b_] | | constructors.cpp:26:15:26:15 | f [a_] | constructors.cpp:28:10:28:10 | f [a_] | | constructors.cpp:26:15:26:15 | f [b_] | constructors.cpp:29:10:29:10 | f [b_] | +| constructors.cpp:28:10:28:10 | f [a_] | constructors.cpp:18:9:18:9 | this [a_] | | constructors.cpp:28:10:28:10 | f [a_] | constructors.cpp:28:12:28:12 | call to a | +| constructors.cpp:29:10:29:10 | f [b_] | constructors.cpp:19:9:19:9 | this [b_] | | constructors.cpp:29:10:29:10 | f [b_] | constructors.cpp:29:12:29:12 | call to b | +| constructors.cpp:34:11:34:20 | call to user_input | constructors.cpp:23:13:23:13 | a | | constructors.cpp:34:11:34:20 | call to user_input | constructors.cpp:34:11:34:26 | call to Foo [a_] | | constructors.cpp:34:11:34:26 | call to Foo [a_] | constructors.cpp:40:9:40:9 | f [a_] | | constructors.cpp:35:11:35:26 | call to Foo [b_] | constructors.cpp:43:9:43:9 | g [b_] | +| constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:23:20:23:20 | b | | constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:35:11:35:26 | call to Foo [b_] | +| constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:23:13:23:13 | a | | constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:36:11:36:37 | call to Foo [a_] | | constructors.cpp:36:11:36:37 | call to Foo [a_] | constructors.cpp:46:9:46:9 | h [a_] | | constructors.cpp:36:11:36:37 | call to Foo [b_] | constructors.cpp:46:9:46:9 | h [b_] | +| constructors.cpp:36:25:36:34 | call to user_input | constructors.cpp:23:20:23:20 | b | | constructors.cpp:36:25:36:34 | call to user_input | constructors.cpp:36:11:36:37 | call to Foo [b_] | | constructors.cpp:40:9:40:9 | f [a_] | constructors.cpp:26:15:26:15 | f [a_] | | constructors.cpp:43:9:43:9 | g [b_] | constructors.cpp:26:15:26:15 | f [b_] | | constructors.cpp:46:9:46:9 | h [a_] | constructors.cpp:26:15:26:15 | f [a_] | | constructors.cpp:46:9:46:9 | h [b_] | constructors.cpp:26:15:26:15 | f [b_] | +| qualifiers.cpp:9:21:9:25 | value | qualifiers.cpp:9:30:9:44 | ... = ... | +| qualifiers.cpp:9:30:9:44 | ... = ... | qualifiers.cpp:9:30:9:33 | this [post update] [a] | +| qualifiers.cpp:12:40:12:44 | value | qualifiers.cpp:12:49:12:64 | ... = ... | +| qualifiers.cpp:12:49:12:64 | ... = ... | qualifiers.cpp:12:49:12:53 | inner [post update] [a] | +| qualifiers.cpp:13:42:13:46 | value | qualifiers.cpp:13:51:13:65 | ... = ... | +| qualifiers.cpp:13:51:13:55 | inner [post update] [a] | qualifiers.cpp:13:29:13:33 | inner [a] | +| qualifiers.cpp:13:51:13:65 | ... = ... | qualifiers.cpp:13:51:13:55 | inner [post update] [a] | | qualifiers.cpp:22:5:22:9 | ref arg outer [inner, a] | qualifiers.cpp:23:10:23:14 | outer [inner, a] | | qualifiers.cpp:22:5:22:38 | ... = ... | qualifiers.cpp:22:11:22:18 | call to getInner [post update] [a] | | qualifiers.cpp:22:11:22:18 | call to getInner [post update] [a] | qualifiers.cpp:22:5:22:9 | ref arg outer [inner, a] | @@ -381,17 +504,20 @@ edges | qualifiers.cpp:23:16:23:20 | inner [a] | qualifiers.cpp:23:23:23:23 | a | | qualifiers.cpp:27:5:27:9 | ref arg outer [inner, a] | qualifiers.cpp:28:10:28:14 | outer [inner, a] | | qualifiers.cpp:27:11:27:18 | ref arg call to getInner [a] | qualifiers.cpp:27:5:27:9 | ref arg outer [inner, a] | +| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:9:21:9:25 | value | | qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:27:11:27:18 | ref arg call to getInner [a] | | qualifiers.cpp:28:10:28:14 | outer [inner, a] | qualifiers.cpp:28:16:28:20 | inner [a] | | qualifiers.cpp:28:16:28:20 | inner [a] | qualifiers.cpp:28:23:28:23 | a | | qualifiers.cpp:32:17:32:21 | ref arg outer [inner, a] | qualifiers.cpp:33:10:33:14 | outer [inner, a] | | qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] | qualifiers.cpp:32:17:32:21 | ref arg outer [inner, a] | +| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:12:40:12:44 | value | | qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] | | qualifiers.cpp:33:10:33:14 | outer [inner, a] | qualifiers.cpp:33:16:33:20 | inner [a] | | qualifiers.cpp:33:16:33:20 | inner [a] | qualifiers.cpp:33:23:33:23 | a | | qualifiers.cpp:37:19:37:35 | ref arg * ... [a] | qualifiers.cpp:37:26:37:33 | call to getInner [inner post update] [a] | | qualifiers.cpp:37:20:37:24 | ref arg outer [inner, a] | qualifiers.cpp:38:10:38:14 | outer [inner, a] | | qualifiers.cpp:37:26:37:33 | call to getInner [inner post update] [a] | qualifiers.cpp:37:20:37:24 | ref arg outer [inner, a] | +| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:13:42:13:46 | value | | qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:37:19:37:35 | ref arg * ... [a] | | qualifiers.cpp:38:10:38:14 | outer [inner, a] | qualifiers.cpp:38:16:38:20 | inner [a] | | qualifiers.cpp:38:16:38:20 | inner [a] | qualifiers.cpp:38:23:38:23 | a | @@ -420,17 +546,31 @@ edges | realistic.cpp:61:25:61:27 | bar [baz, userInput, bufferLen] | realistic.cpp:61:21:61:30 | access to array [baz, userInput, bufferLen] | | realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] | realistic.cpp:61:37:61:45 | userInput [bufferLen] | | realistic.cpp:61:37:61:45 | userInput [bufferLen] | realistic.cpp:61:47:61:55 | bufferLen | +| simple.cpp:18:9:18:9 | this [a_] | simple.cpp:18:22:18:23 | this [a_] | +| simple.cpp:18:22:18:23 | this [a_] | simple.cpp:18:22:18:23 | a_ | +| simple.cpp:19:9:19:9 | this [b_] | simple.cpp:19:22:19:23 | this [b_] | +| simple.cpp:19:22:19:23 | this [b_] | simple.cpp:19:22:19:23 | b_ | +| simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:29 | ... = ... | +| simple.cpp:20:24:20:29 | ... = ... | simple.cpp:20:24:20:25 | this [post update] [a_] | +| simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:29 | ... = ... | +| simple.cpp:21:24:21:29 | ... = ... | simple.cpp:21:24:21:25 | this [post update] [b_] | | simple.cpp:26:15:26:15 | f [a_] | simple.cpp:28:10:28:10 | f [a_] | | simple.cpp:26:15:26:15 | f [b_] | simple.cpp:29:10:29:10 | f [b_] | +| simple.cpp:28:10:28:10 | f [a_] | simple.cpp:18:9:18:9 | this [a_] | | simple.cpp:28:10:28:10 | f [a_] | simple.cpp:28:12:28:12 | call to a | +| simple.cpp:29:10:29:10 | f [b_] | simple.cpp:19:9:19:9 | this [b_] | | simple.cpp:29:10:29:10 | f [b_] | simple.cpp:29:12:29:12 | call to b | | simple.cpp:39:5:39:5 | ref arg f [a_] | simple.cpp:45:9:45:9 | f [a_] | +| simple.cpp:39:12:39:21 | call to user_input | simple.cpp:20:19:20:19 | a | | simple.cpp:39:12:39:21 | call to user_input | simple.cpp:39:5:39:5 | ref arg f [a_] | | simple.cpp:40:5:40:5 | ref arg g [b_] | simple.cpp:48:9:48:9 | g [b_] | +| simple.cpp:40:12:40:21 | call to user_input | simple.cpp:21:19:21:19 | b | | simple.cpp:40:12:40:21 | call to user_input | simple.cpp:40:5:40:5 | ref arg g [b_] | | simple.cpp:41:5:41:5 | ref arg h [a_] | simple.cpp:51:9:51:9 | h [a_] | +| simple.cpp:41:12:41:21 | call to user_input | simple.cpp:20:19:20:19 | a | | simple.cpp:41:12:41:21 | call to user_input | simple.cpp:41:5:41:5 | ref arg h [a_] | | simple.cpp:42:5:42:5 | ref arg h [b_] | simple.cpp:51:9:51:9 | h [b_] | +| simple.cpp:42:12:42:21 | call to user_input | simple.cpp:21:19:21:19 | b | | simple.cpp:42:12:42:21 | call to user_input | simple.cpp:42:5:42:5 | ref arg h [b_] | | simple.cpp:45:9:45:9 | f [a_] | simple.cpp:26:15:26:15 | f [a_] | | simple.cpp:48:9:48:9 | g [b_] | simple.cpp:26:15:26:15 | f [b_] | @@ -440,10 +580,14 @@ edges | simple.cpp:65:5:65:22 | ... = ... | simple.cpp:65:5:65:5 | a [post update] [i] | | simple.cpp:65:11:65:20 | call to user_input | simple.cpp:65:5:65:22 | ... = ... | | simple.cpp:67:10:67:11 | a2 [i] | simple.cpp:67:13:67:13 | i | +| simple.cpp:78:9:78:15 | this [f2, f1] | simple.cpp:79:16:79:17 | this [f2, f1] | +| simple.cpp:79:16:79:17 | f2 [f1] | simple.cpp:79:19:79:20 | f1 | +| simple.cpp:79:16:79:17 | this [f2, f1] | simple.cpp:79:16:79:17 | f2 [f1] | | simple.cpp:83:9:83:10 | f2 [post update] [f1] | simple.cpp:83:9:83:10 | this [post update] [f2, f1] | | simple.cpp:83:9:83:10 | this [post update] [f2, f1] | simple.cpp:84:14:84:20 | this [f2, f1] | | simple.cpp:83:9:83:28 | ... = ... | simple.cpp:83:9:83:10 | f2 [post update] [f1] | | simple.cpp:83:17:83:26 | call to user_input | simple.cpp:83:9:83:28 | ... = ... | +| simple.cpp:84:14:84:20 | this [f2, f1] | simple.cpp:78:9:78:15 | this [f2, f1] | | simple.cpp:84:14:84:20 | this [f2, f1] | simple.cpp:84:14:84:20 | call to getf2f1 | | simple.cpp:92:5:92:5 | a [post update] [i] | simple.cpp:94:10:94:11 | a2 [i] | | simple.cpp:92:5:92:22 | ... = ... | simple.cpp:92:5:92:5 | a [post update] [i] | @@ -477,6 +621,19 @@ edges | struct_init.c:46:10:46:14 | outer [pointerAB, a] | struct_init.c:46:16:46:24 | pointerAB [a] | | struct_init.c:46:16:46:24 | pointerAB [a] | struct_init.c:14:24:14:25 | ab [a] | nodes +| A.cpp:23:10:23:10 | c | semmle.label | c | +| A.cpp:25:7:25:10 | this [post update] [c] | semmle.label | this [post update] [c] | +| A.cpp:25:7:25:17 | ... = ... | semmle.label | ... = ... | +| A.cpp:27:17:27:17 | c | semmle.label | c | +| A.cpp:27:22:27:25 | this [post update] [c] | semmle.label | this [post update] [c] | +| A.cpp:27:22:27:32 | ... = ... | semmle.label | ... = ... | +| A.cpp:28:8:28:10 | this [c] | semmle.label | this [c] | +| A.cpp:28:23:28:26 | this [c] | semmle.label | this [c] | +| A.cpp:28:29:28:29 | c | semmle.label | c | +| A.cpp:29:23:29:23 | c | semmle.label | c | +| A.cpp:31:14:31:21 | call to B [c] | semmle.label | call to B [c] | +| A.cpp:31:14:31:21 | new [c] | semmle.label | new [c] | +| A.cpp:31:20:31:20 | c | semmle.label | c | | A.cpp:41:15:41:21 | new | semmle.label | new | | A.cpp:43:10:43:12 | & ... | semmle.label | & ... | | A.cpp:47:12:47:18 | new | semmle.label | new | @@ -500,6 +657,14 @@ nodes | A.cpp:73:25:73:32 | new | semmle.label | new | | A.cpp:75:10:75:11 | b2 [c] | semmle.label | b2 [c] | | A.cpp:75:14:75:14 | c | semmle.label | c | +| A.cpp:78:27:78:27 | c | semmle.label | c | +| A.cpp:81:10:81:15 | call to setOnB [c] | semmle.label | call to setOnB [c] | +| A.cpp:81:21:81:21 | c | semmle.label | c | +| A.cpp:82:12:82:24 | ... ? ... : ... [c] | semmle.label | ... ? ... : ... [c] | +| A.cpp:85:26:85:26 | c | semmle.label | c | +| A.cpp:90:7:90:8 | ref arg b2 [c] | semmle.label | ref arg b2 [c] | +| A.cpp:90:15:90:15 | c | semmle.label | c | +| A.cpp:91:14:91:15 | b2 [c] | semmle.label | b2 [c] | | A.cpp:98:12:98:18 | new | semmle.label | new | | A.cpp:100:5:100:6 | c1 [post update] [a] | semmle.label | c1 [post update] [a] | | A.cpp:100:5:100:13 | ... = ... | semmle.label | ... = ... | @@ -514,11 +679,14 @@ nodes | A.cpp:131:8:131:8 | ref arg b [c] | semmle.label | ref arg b [c] | | A.cpp:132:10:132:10 | b [c] | semmle.label | b [c] | | A.cpp:132:13:132:13 | c | semmle.label | c | +| A.cpp:140:13:140:13 | b | semmle.label | b | | A.cpp:142:7:142:7 | b [post update] [c] | semmle.label | b [post update] [c] | | A.cpp:142:7:142:20 | ... = ... | semmle.label | ... = ... | | A.cpp:142:14:142:20 | new | semmle.label | new | | A.cpp:143:7:143:10 | this [post update] [b, c] | semmle.label | this [post update] [b, c] | | A.cpp:143:7:143:10 | this [post update] [b] | semmle.label | this [post update] [b] | +| A.cpp:143:7:143:10 | this [post update] [b] | semmle.label | this [post update] [b] | +| A.cpp:143:7:143:31 | ... = ... | semmle.label | ... = ... | | A.cpp:143:7:143:31 | ... = ... | semmle.label | ... = ... | | A.cpp:143:7:143:31 | ... = ... [c] | semmle.label | ... = ... [c] | | A.cpp:143:25:143:31 | new | semmle.label | new | @@ -551,6 +719,15 @@ nodes | A.cpp:167:47:167:50 | next [next, head] | semmle.label | next [next, head] | | A.cpp:169:12:169:12 | l [head] | semmle.label | l [head] | | A.cpp:169:15:169:18 | head | semmle.label | head | +| A.cpp:181:15:181:21 | newHead | semmle.label | newHead | +| A.cpp:181:32:181:35 | next [head] | semmle.label | next [head] | +| A.cpp:181:32:181:35 | next [next, head] | semmle.label | next [next, head] | +| A.cpp:183:7:183:10 | this [post update] [head] | semmle.label | this [post update] [head] | +| A.cpp:183:7:183:20 | ... = ... | semmle.label | ... = ... | +| A.cpp:184:7:184:10 | this [post update] [next, head] | semmle.label | this [post update] [next, head] | +| A.cpp:184:7:184:10 | this [post update] [next, next, head] | semmle.label | this [post update] [next, next, head] | +| A.cpp:184:7:184:23 | ... = ... [head] | semmle.label | ... = ... [head] | +| A.cpp:184:7:184:23 | ... = ... [next, head] | semmle.label | ... = ... [next, head] | | B.cpp:6:15:6:24 | new | semmle.label | new | | B.cpp:7:16:7:35 | call to Box1 [elem1] | semmle.label | call to Box1 [elem1] | | B.cpp:7:25:7:25 | e | semmle.label | e | @@ -567,6 +744,18 @@ nodes | B.cpp:19:10:19:11 | b2 [box1, elem2] | semmle.label | b2 [box1, elem2] | | B.cpp:19:14:19:17 | box1 [elem2] | semmle.label | box1 [elem2] | | B.cpp:19:20:19:24 | elem2 | semmle.label | elem2 | +| B.cpp:33:16:33:17 | e1 | semmle.label | e1 | +| B.cpp:33:26:33:27 | e2 | semmle.label | e2 | +| B.cpp:35:7:35:10 | this [post update] [elem1] | semmle.label | this [post update] [elem1] | +| B.cpp:35:7:35:22 | ... = ... | semmle.label | ... = ... | +| B.cpp:36:7:36:10 | this [post update] [elem2] | semmle.label | this [post update] [elem2] | +| B.cpp:36:7:36:22 | ... = ... | semmle.label | ... = ... | +| B.cpp:44:16:44:17 | b1 [elem1] | semmle.label | b1 [elem1] | +| B.cpp:44:16:44:17 | b1 [elem2] | semmle.label | b1 [elem2] | +| B.cpp:46:7:46:10 | this [post update] [box1, elem1] | semmle.label | this [post update] [box1, elem1] | +| B.cpp:46:7:46:10 | this [post update] [box1, elem2] | semmle.label | this [post update] [box1, elem2] | +| B.cpp:46:7:46:21 | ... = ... [elem1] | semmle.label | ... = ... [elem1] | +| B.cpp:46:7:46:21 | ... = ... [elem2] | semmle.label | ... = ... [elem2] | | C.cpp:18:12:18:18 | call to C [s1] | semmle.label | call to C [s1] | | C.cpp:18:12:18:18 | call to C [s3] | semmle.label | call to C [s3] | | C.cpp:19:5:19:5 | c [s1] | semmle.label | c [s1] | @@ -582,6 +771,15 @@ nodes | C.cpp:29:10:29:11 | this [s1] | semmle.label | this [s1] | | C.cpp:31:10:31:11 | s3 | semmle.label | s3 | | C.cpp:31:10:31:11 | this [s3] | semmle.label | this [s3] | +| D.cpp:10:11:10:17 | this [elem] | semmle.label | this [elem] | +| D.cpp:10:30:10:33 | elem | semmle.label | elem | +| D.cpp:10:30:10:33 | this [elem] | semmle.label | this [elem] | +| D.cpp:11:24:11:24 | e | semmle.label | e | +| D.cpp:11:29:11:32 | this [post update] [elem] | semmle.label | this [post update] [elem] | +| D.cpp:11:29:11:36 | ... = ... | semmle.label | ... = ... | +| D.cpp:17:11:17:17 | this [box, elem] | semmle.label | this [box, elem] | +| D.cpp:17:30:17:32 | box [elem] | semmle.label | box [elem] | +| D.cpp:17:30:17:32 | this [box, elem] | semmle.label | this [box, elem] | | D.cpp:21:30:21:31 | b2 [box, elem] | semmle.label | b2 [box, elem] | | D.cpp:22:10:22:11 | b2 [box, elem] | semmle.label | b2 [box, elem] | | D.cpp:22:14:22:20 | call to getBox1 [elem] | semmle.label | call to getBox1 [elem] | @@ -729,6 +927,30 @@ nodes | arrays.cpp:44:10:44:17 | indirect [arr, data] | semmle.label | indirect [arr, data] | | arrays.cpp:44:20:44:22 | arr [data] | semmle.label | arr [data] | | arrays.cpp:44:27:44:30 | data | semmle.label | data | +| by_reference.cpp:11:48:11:52 | value | semmle.label | value | +| by_reference.cpp:12:5:12:5 | s [post update] [a] | semmle.label | s [post update] [a] | +| by_reference.cpp:12:5:12:16 | ... = ... | semmle.label | ... = ... | +| by_reference.cpp:15:26:15:30 | value | semmle.label | value | +| by_reference.cpp:16:5:16:8 | this [post update] [a] | semmle.label | this [post update] [a] | +| by_reference.cpp:16:5:16:19 | ... = ... | semmle.label | ... = ... | +| by_reference.cpp:19:28:19:32 | value | semmle.label | value | +| by_reference.cpp:20:5:20:8 | ref arg this [a] | semmle.label | ref arg this [a] | +| by_reference.cpp:20:23:20:27 | value | semmle.label | value | +| by_reference.cpp:23:34:23:38 | value | semmle.label | value | +| by_reference.cpp:24:19:24:22 | ref arg this [a] | semmle.label | ref arg this [a] | +| by_reference.cpp:24:25:24:29 | value | semmle.label | value | +| by_reference.cpp:31:46:31:46 | s [a] | semmle.label | s [a] | +| by_reference.cpp:32:12:32:12 | s [a] | semmle.label | s [a] | +| by_reference.cpp:32:15:32:15 | a | semmle.label | a | +| by_reference.cpp:35:9:35:19 | this [a] | semmle.label | this [a] | +| by_reference.cpp:36:12:36:15 | this [a] | semmle.label | this [a] | +| by_reference.cpp:36:18:36:18 | a | semmle.label | a | +| by_reference.cpp:39:9:39:21 | this [a] | semmle.label | this [a] | +| by_reference.cpp:40:12:40:15 | this [a] | semmle.label | this [a] | +| by_reference.cpp:40:18:40:28 | call to getDirectly | semmle.label | call to getDirectly | +| by_reference.cpp:43:9:43:27 | this [a] | semmle.label | this [a] | +| by_reference.cpp:44:12:44:24 | call to nonMemberGetA | semmle.label | call to nonMemberGetA | +| by_reference.cpp:44:26:44:29 | this [a] | semmle.label | this [a] | | by_reference.cpp:50:3:50:3 | ref arg s [a] | semmle.label | ref arg s [a] | | by_reference.cpp:50:17:50:26 | call to user_input | semmle.label | call to user_input | | by_reference.cpp:51:8:51:8 | s [a] | semmle.label | s [a] | @@ -818,6 +1040,18 @@ nodes | by_reference.cpp:135:27:135:27 | a | semmle.label | a | | by_reference.cpp:136:8:136:13 | pouter [a] | semmle.label | pouter [a] | | by_reference.cpp:136:16:136:16 | a | semmle.label | a | +| complex.cpp:9:7:9:7 | this [a_] | semmle.label | this [a_] | +| complex.cpp:9:20:9:21 | a_ | semmle.label | a_ | +| complex.cpp:9:20:9:21 | this [a_] | semmle.label | this [a_] | +| complex.cpp:10:7:10:7 | this [b_] | semmle.label | this [b_] | +| complex.cpp:10:20:10:21 | b_ | semmle.label | b_ | +| complex.cpp:10:20:10:21 | this [b_] | semmle.label | this [b_] | +| complex.cpp:11:17:11:17 | a | semmle.label | a | +| complex.cpp:11:22:11:23 | this [post update] [a_] | semmle.label | this [post update] [a_] | +| complex.cpp:11:22:11:27 | ... = ... | semmle.label | ... = ... | +| complex.cpp:12:17:12:17 | b | semmle.label | b | +| complex.cpp:12:22:12:23 | this [post update] [b_] | semmle.label | this [post update] [b_] | +| complex.cpp:12:22:12:27 | ... = ... | semmle.label | ... = ... | | complex.cpp:40:17:40:17 | b [inner, f, a_] | semmle.label | b [inner, f, a_] | | complex.cpp:40:17:40:17 | b [inner, f, b_] | semmle.label | b [inner, f, b_] | | complex.cpp:42:8:42:8 | b [inner, f, a_] | semmle.label | b [inner, f, a_] | @@ -874,6 +1108,18 @@ nodes | conflated.cpp:61:8:61:9 | ll [next, y] | semmle.label | ll [next, y] | | conflated.cpp:61:12:61:15 | next [y] | semmle.label | next [y] | | conflated.cpp:61:18:61:18 | y | semmle.label | y | +| constructors.cpp:18:9:18:9 | this [a_] | semmle.label | this [a_] | +| constructors.cpp:18:22:18:23 | a_ | semmle.label | a_ | +| constructors.cpp:18:22:18:23 | this [a_] | semmle.label | this [a_] | +| constructors.cpp:19:9:19:9 | this [b_] | semmle.label | this [b_] | +| constructors.cpp:19:22:19:23 | b_ | semmle.label | b_ | +| constructors.cpp:19:22:19:23 | this [b_] | semmle.label | this [b_] | +| constructors.cpp:23:13:23:13 | a | semmle.label | a | +| constructors.cpp:23:20:23:20 | b | semmle.label | b | +| constructors.cpp:23:25:23:29 | constructor init of field a_ [post-this] [a_] | semmle.label | constructor init of field a_ [post-this] [a_] | +| constructors.cpp:23:28:23:28 | a | semmle.label | a | +| constructors.cpp:23:32:23:36 | constructor init of field b_ [post-this] [b_] | semmle.label | constructor init of field b_ [post-this] [b_] | +| constructors.cpp:23:35:23:35 | b | semmle.label | b | | constructors.cpp:26:15:26:15 | f [a_] | semmle.label | f [a_] | | constructors.cpp:26:15:26:15 | f [b_] | semmle.label | f [b_] | | constructors.cpp:28:10:28:10 | f [a_] | semmle.label | f [a_] | @@ -892,6 +1138,16 @@ nodes | constructors.cpp:43:9:43:9 | g [b_] | semmle.label | g [b_] | | constructors.cpp:46:9:46:9 | h [a_] | semmle.label | h [a_] | | constructors.cpp:46:9:46:9 | h [b_] | semmle.label | h [b_] | +| qualifiers.cpp:9:21:9:25 | value | semmle.label | value | +| qualifiers.cpp:9:30:9:33 | this [post update] [a] | semmle.label | this [post update] [a] | +| qualifiers.cpp:9:30:9:44 | ... = ... | semmle.label | ... = ... | +| qualifiers.cpp:12:40:12:44 | value | semmle.label | value | +| qualifiers.cpp:12:49:12:53 | inner [post update] [a] | semmle.label | inner [post update] [a] | +| qualifiers.cpp:12:49:12:64 | ... = ... | semmle.label | ... = ... | +| qualifiers.cpp:13:29:13:33 | inner [a] | semmle.label | inner [a] | +| qualifiers.cpp:13:42:13:46 | value | semmle.label | value | +| qualifiers.cpp:13:51:13:55 | inner [post update] [a] | semmle.label | inner [post update] [a] | +| qualifiers.cpp:13:51:13:65 | ... = ... | semmle.label | ... = ... | | qualifiers.cpp:22:5:22:9 | ref arg outer [inner, a] | semmle.label | ref arg outer [inner, a] | | qualifiers.cpp:22:5:22:38 | ... = ... | semmle.label | ... = ... | | qualifiers.cpp:22:11:22:18 | call to getInner [post update] [a] | semmle.label | call to getInner [post update] [a] | @@ -946,6 +1202,18 @@ nodes | realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] | semmle.label | baz [userInput, bufferLen] | | realistic.cpp:61:37:61:45 | userInput [bufferLen] | semmle.label | userInput [bufferLen] | | realistic.cpp:61:47:61:55 | bufferLen | semmle.label | bufferLen | +| simple.cpp:18:9:18:9 | this [a_] | semmle.label | this [a_] | +| simple.cpp:18:22:18:23 | a_ | semmle.label | a_ | +| simple.cpp:18:22:18:23 | this [a_] | semmle.label | this [a_] | +| simple.cpp:19:9:19:9 | this [b_] | semmle.label | this [b_] | +| simple.cpp:19:22:19:23 | b_ | semmle.label | b_ | +| simple.cpp:19:22:19:23 | this [b_] | semmle.label | this [b_] | +| simple.cpp:20:19:20:19 | a | semmle.label | a | +| simple.cpp:20:24:20:25 | this [post update] [a_] | semmle.label | this [post update] [a_] | +| simple.cpp:20:24:20:29 | ... = ... | semmle.label | ... = ... | +| simple.cpp:21:19:21:19 | b | semmle.label | b | +| simple.cpp:21:24:21:25 | this [post update] [b_] | semmle.label | this [post update] [b_] | +| simple.cpp:21:24:21:29 | ... = ... | semmle.label | ... = ... | | simple.cpp:26:15:26:15 | f [a_] | semmle.label | f [a_] | | simple.cpp:26:15:26:15 | f [b_] | semmle.label | f [b_] | | simple.cpp:28:10:28:10 | f [a_] | semmle.label | f [a_] | @@ -969,6 +1237,10 @@ nodes | simple.cpp:65:11:65:20 | call to user_input | semmle.label | call to user_input | | simple.cpp:67:10:67:11 | a2 [i] | semmle.label | a2 [i] | | simple.cpp:67:13:67:13 | i | semmle.label | i | +| simple.cpp:78:9:78:15 | this [f2, f1] | semmle.label | this [f2, f1] | +| simple.cpp:79:16:79:17 | f2 [f1] | semmle.label | f2 [f1] | +| simple.cpp:79:16:79:17 | this [f2, f1] | semmle.label | this [f2, f1] | +| simple.cpp:79:19:79:20 | f1 | semmle.label | f1 | | simple.cpp:83:9:83:10 | f2 [post update] [f1] | semmle.label | f2 [post update] [f1] | | simple.cpp:83:9:83:10 | this [post update] [f2, f1] | semmle.label | this [post update] [f2, f1] | | simple.cpp:83:9:83:28 | ... = ... | semmle.label | ... = ... | @@ -1008,6 +1280,65 @@ nodes | struct_init.c:43:5:43:7 | & ... [a] | semmle.label | & ... [a] | | struct_init.c:46:10:46:14 | outer [pointerAB, a] | semmle.label | outer [pointerAB, a] | | struct_init.c:46:16:46:24 | pointerAB [a] | semmle.label | pointerAB [a] | +subpaths +| A.cpp:31:20:31:20 | c | A.cpp:23:10:23:10 | c | A.cpp:25:7:25:10 | this [post update] [c] | A.cpp:31:14:31:21 | call to B [c] | +| A.cpp:48:20:48:20 | c | A.cpp:29:23:29:23 | c | A.cpp:31:14:31:21 | new [c] | A.cpp:48:12:48:18 | call to make [c] | +| A.cpp:55:12:55:19 | new | A.cpp:27:17:27:17 | c | A.cpp:27:22:27:25 | this [post update] [c] | A.cpp:55:5:55:5 | ref arg b [c] | +| A.cpp:56:10:56:10 | b [c] | A.cpp:28:8:28:10 | this [c] | A.cpp:28:29:28:29 | c | A.cpp:56:13:56:15 | call to get | +| A.cpp:57:11:57:24 | new [c] | A.cpp:28:8:28:10 | this [c] | A.cpp:28:29:28:29 | c | A.cpp:57:28:57:30 | call to get | +| A.cpp:57:17:57:23 | new | A.cpp:23:10:23:10 | c | A.cpp:25:7:25:10 | this [post update] [c] | A.cpp:57:11:57:24 | call to B [c] | +| A.cpp:64:21:64:28 | new | A.cpp:85:26:85:26 | c | A.cpp:91:14:91:15 | b2 [c] | A.cpp:64:10:64:15 | call to setOnB [c] | +| A.cpp:73:25:73:32 | new | A.cpp:78:27:78:27 | c | A.cpp:82:12:82:24 | ... ? ... : ... [c] | A.cpp:73:10:73:19 | call to setOnBWrap [c] | +| A.cpp:81:21:81:21 | c | A.cpp:85:26:85:26 | c | A.cpp:91:14:91:15 | b2 [c] | A.cpp:81:10:81:15 | call to setOnB [c] | +| A.cpp:90:15:90:15 | c | A.cpp:27:17:27:17 | c | A.cpp:27:22:27:25 | this [post update] [c] | A.cpp:90:7:90:8 | ref arg b2 [c] | +| A.cpp:126:12:126:18 | new | A.cpp:27:17:27:17 | c | A.cpp:27:22:27:25 | this [post update] [c] | A.cpp:126:5:126:5 | ref arg b [c] | +| A.cpp:151:18:151:18 | b | A.cpp:140:13:140:13 | b | A.cpp:143:7:143:10 | this [post update] [b] | A.cpp:151:12:151:24 | call to D [b] | +| A.cpp:160:29:160:29 | b | A.cpp:181:15:181:21 | newHead | A.cpp:183:7:183:10 | this [post update] [head] | A.cpp:160:18:160:60 | call to MyList [head] | +| A.cpp:161:38:161:39 | l1 [head] | A.cpp:181:32:181:35 | next [head] | A.cpp:184:7:184:10 | this [post update] [next, head] | A.cpp:161:18:161:40 | call to MyList [next, head] | +| A.cpp:162:38:162:39 | l2 [next, head] | A.cpp:181:32:181:35 | next [next, head] | A.cpp:184:7:184:10 | this [post update] [next, next, head] | A.cpp:162:18:162:40 | call to MyList [next, next, head] | +| B.cpp:7:25:7:25 | e | B.cpp:33:16:33:17 | e1 | B.cpp:35:7:35:10 | this [post update] [elem1] | B.cpp:7:16:7:35 | call to Box1 [elem1] | +| B.cpp:8:25:8:26 | b1 [elem1] | B.cpp:44:16:44:17 | b1 [elem1] | B.cpp:46:7:46:10 | this [post update] [box1, elem1] | B.cpp:8:16:8:27 | call to Box2 [box1, elem1] | +| B.cpp:16:37:16:37 | e | B.cpp:33:26:33:27 | e2 | B.cpp:36:7:36:10 | this [post update] [elem2] | B.cpp:16:16:16:38 | call to Box1 [elem2] | +| B.cpp:17:25:17:26 | b1 [elem2] | B.cpp:44:16:44:17 | b1 [elem2] | B.cpp:46:7:46:10 | this [post update] [box1, elem2] | B.cpp:17:16:17:27 | call to Box2 [box1, elem2] | +| D.cpp:22:10:22:11 | b2 [box, elem] | D.cpp:17:11:17:17 | this [box, elem] | D.cpp:17:30:17:32 | box [elem] | D.cpp:22:14:22:20 | call to getBox1 [elem] | +| D.cpp:22:14:22:20 | call to getBox1 [elem] | D.cpp:10:11:10:17 | this [elem] | D.cpp:10:30:10:33 | elem | D.cpp:22:25:22:31 | call to getElem | +| D.cpp:37:21:37:21 | e | D.cpp:11:24:11:24 | e | D.cpp:11:29:11:32 | this [post update] [elem] | D.cpp:37:8:37:10 | ref arg box [elem] | +| D.cpp:51:27:51:27 | e | D.cpp:11:24:11:24 | e | D.cpp:11:29:11:32 | this [post update] [elem] | D.cpp:51:8:51:14 | ref arg call to getBox1 [elem] | +| by_reference.cpp:20:23:20:27 | value | by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:8 | this [post update] [a] | by_reference.cpp:20:5:20:8 | ref arg this [a] | +| by_reference.cpp:24:25:24:29 | value | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:5 | s [post update] [a] | by_reference.cpp:24:19:24:22 | ref arg this [a] | +| by_reference.cpp:40:12:40:15 | this [a] | by_reference.cpp:35:9:35:19 | this [a] | by_reference.cpp:36:18:36:18 | a | by_reference.cpp:40:18:40:28 | call to getDirectly | +| by_reference.cpp:44:26:44:29 | this [a] | by_reference.cpp:31:46:31:46 | s [a] | by_reference.cpp:32:15:32:15 | a | by_reference.cpp:44:12:44:24 | call to nonMemberGetA | +| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:8 | this [post update] [a] | by_reference.cpp:50:3:50:3 | ref arg s [a] | +| by_reference.cpp:51:8:51:8 | s [a] | by_reference.cpp:35:9:35:19 | this [a] | by_reference.cpp:36:18:36:18 | a | by_reference.cpp:51:10:51:20 | call to getDirectly | +| by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:19:28:19:32 | value | by_reference.cpp:20:5:20:8 | ref arg this [a] | by_reference.cpp:56:3:56:3 | ref arg s [a] | +| by_reference.cpp:57:8:57:8 | s [a] | by_reference.cpp:39:9:39:21 | this [a] | by_reference.cpp:40:18:40:28 | call to getDirectly | by_reference.cpp:57:10:57:22 | call to getIndirectly | +| by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:23:34:23:38 | value | by_reference.cpp:24:19:24:22 | ref arg this [a] | by_reference.cpp:62:3:62:3 | ref arg s [a] | +| by_reference.cpp:63:8:63:8 | s [a] | by_reference.cpp:43:9:43:27 | this [a] | by_reference.cpp:44:12:44:24 | call to nonMemberGetA | by_reference.cpp:63:10:63:28 | call to getThroughNonMember | +| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:5 | s [post update] [a] | by_reference.cpp:68:17:68:18 | ref arg & ... [a] | +| by_reference.cpp:69:22:69:23 | & ... [a] | by_reference.cpp:31:46:31:46 | s [a] | by_reference.cpp:32:15:32:15 | a | by_reference.cpp:69:8:69:20 | call to nonMemberGetA | +| complex.cpp:42:16:42:16 | f [a_] | complex.cpp:9:7:9:7 | this [a_] | complex.cpp:9:20:9:21 | a_ | complex.cpp:42:18:42:18 | call to a | +| complex.cpp:43:16:43:16 | f [b_] | complex.cpp:10:7:10:7 | this [b_] | complex.cpp:10:20:10:21 | b_ | complex.cpp:43:18:43:18 | call to b | +| complex.cpp:53:19:53:28 | call to user_input | complex.cpp:11:17:11:17 | a | complex.cpp:11:22:11:23 | this [post update] [a_] | complex.cpp:53:12:53:12 | ref arg f [a_] | +| complex.cpp:54:19:54:28 | call to user_input | complex.cpp:12:17:12:17 | b | complex.cpp:12:22:12:23 | this [post update] [b_] | complex.cpp:54:12:54:12 | ref arg f [b_] | +| complex.cpp:55:19:55:28 | call to user_input | complex.cpp:11:17:11:17 | a | complex.cpp:11:22:11:23 | this [post update] [a_] | complex.cpp:55:12:55:12 | ref arg f [a_] | +| complex.cpp:56:19:56:28 | call to user_input | complex.cpp:12:17:12:17 | b | complex.cpp:12:22:12:23 | this [post update] [b_] | complex.cpp:56:12:56:12 | ref arg f [b_] | +| constructors.cpp:28:10:28:10 | f [a_] | constructors.cpp:18:9:18:9 | this [a_] | constructors.cpp:18:22:18:23 | a_ | constructors.cpp:28:12:28:12 | call to a | +| constructors.cpp:29:10:29:10 | f [b_] | constructors.cpp:19:9:19:9 | this [b_] | constructors.cpp:19:22:19:23 | b_ | constructors.cpp:29:12:29:12 | call to b | +| constructors.cpp:34:11:34:20 | call to user_input | constructors.cpp:23:13:23:13 | a | constructors.cpp:23:25:23:29 | constructor init of field a_ [post-this] [a_] | constructors.cpp:34:11:34:26 | call to Foo [a_] | +| constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:23:20:23:20 | b | constructors.cpp:23:32:23:36 | constructor init of field b_ [post-this] [b_] | constructors.cpp:35:11:35:26 | call to Foo [b_] | +| constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:23:13:23:13 | a | constructors.cpp:23:25:23:29 | constructor init of field a_ [post-this] [a_] | constructors.cpp:36:11:36:37 | call to Foo [a_] | +| constructors.cpp:36:25:36:34 | call to user_input | constructors.cpp:23:20:23:20 | b | constructors.cpp:23:32:23:36 | constructor init of field b_ [post-this] [b_] | constructors.cpp:36:11:36:37 | call to Foo [b_] | +| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:9:21:9:25 | value | qualifiers.cpp:9:30:9:33 | this [post update] [a] | qualifiers.cpp:27:11:27:18 | ref arg call to getInner [a] | +| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:12:40:12:44 | value | qualifiers.cpp:12:49:12:53 | inner [post update] [a] | qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] | +| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:13:42:13:46 | value | qualifiers.cpp:13:29:13:33 | inner [a] | qualifiers.cpp:37:19:37:35 | ref arg * ... [a] | +| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:13:42:13:46 | value | qualifiers.cpp:13:51:13:55 | inner [post update] [a] | qualifiers.cpp:37:19:37:35 | ref arg * ... [a] | +| simple.cpp:28:10:28:10 | f [a_] | simple.cpp:18:9:18:9 | this [a_] | simple.cpp:18:22:18:23 | a_ | simple.cpp:28:12:28:12 | call to a | +| simple.cpp:29:10:29:10 | f [b_] | simple.cpp:19:9:19:9 | this [b_] | simple.cpp:19:22:19:23 | b_ | simple.cpp:29:12:29:12 | call to b | +| simple.cpp:39:12:39:21 | call to user_input | simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:25 | this [post update] [a_] | simple.cpp:39:5:39:5 | ref arg f [a_] | +| simple.cpp:40:12:40:21 | call to user_input | simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:25 | this [post update] [b_] | simple.cpp:40:5:40:5 | ref arg g [b_] | +| simple.cpp:41:12:41:21 | call to user_input | simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:25 | this [post update] [a_] | simple.cpp:41:5:41:5 | ref arg h [a_] | +| simple.cpp:42:12:42:21 | call to user_input | simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:25 | this [post update] [b_] | simple.cpp:42:5:42:5 | ref arg h [b_] | +| simple.cpp:84:14:84:20 | this [f2, f1] | simple.cpp:78:9:78:15 | this [f2, f1] | simple.cpp:79:19:79:20 | f1 | simple.cpp:84:14:84:20 | call to getf2f1 | #select | A.cpp:43:10:43:12 | & ... | A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... | & ... flows from $@ | A.cpp:41:15:41:21 | new | new | | A.cpp:49:13:49:13 | c | A.cpp:47:12:47:18 | new | A.cpp:49:13:49:13 | c | c flows from $@ | A.cpp:47:12:47:18 | new | new | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/copyableclass_declonly.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/copyableclass_declonly.cpp index f8169db1128..307e1ecaa76 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/copyableclass_declonly.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/copyableclass_declonly.cpp @@ -64,6 +64,6 @@ void test_copyableclass_declonly() sink(s1); // $ ast,ir sink(s2); // $ ast,ir - sink(s3 = source()); // $ ast MISSING: ir + sink(s3 = source()); // $ ast,ir } } diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp index aabd898830e..4e85a6b9aa3 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp @@ -415,10 +415,10 @@ void test_unordered_map() sink(m30["abc"]); sink(m31.try_emplace("abc", source(), 2)); // $ ast,ir sink(m31); // $ ast,ir - sink(m31["abc"]); // $ ast MISSING: ir + sink(m31["abc"]); // $ ast,ir sink(m32.try_emplace("abc", 1, source())); // $ ast,ir sink(m32); // $ ast,ir - sink(m32["abc"]); // $ ast MISSING: ir + sink(m32["abc"]); // $ ast,ir // additional emplace test cases std::unordered_map m33; diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp index 0e29d314887..9ce653c654a 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp @@ -30,20 +30,20 @@ void test_string() sink(b); sink(c); // $ ast,ir sink(b.c_str()); - sink(c.c_str()); // $ ast MISSING: ir + sink(c.c_str()); // $ ast,ir } void test_strings2() { string path1 = user_input(); - sink(path1.c_str(), "r"); // $ ast MISSING: ir + sink(path1.c_str(), "r"); // $ ast,ir string path2; path2 = user_input(); - sink(path2.c_str(), "r"); // $ ast MISSING: ir + sink(path2.c_str(), "r"); // $ ast,ir string path3(user_input()); - sink(path3.c_str(), "r"); // $ ast MISSING: ir + sink(path3.c_str(), "r"); // $ ast,ir } void test_string3() @@ -67,7 +67,7 @@ void test_string4() // convert back std::string -> char * cs = ss.c_str(); - sink(cs); // $ ast MISSING: ir + sink(cs); // $ ast,ir sink(ss); // $ ast,ir } @@ -159,12 +159,12 @@ void test_string_append() { sink(s5); // $ ast,ir s6 = s3; - sink(s6 += s4); // $ ast MISSING: ir + sink(s6 += s4); // $ ast,ir sink(s6); // $ ast,ir s7 = s3; - sink(s7 += source()); // $ ast MISSING: ir - sink(s7 += " "); // $ ast MISSING: ir + sink(s7 += source()); // $ ast,ir + sink(s7 += " "); // $ ast,ir sink(s7); // $ ast,ir s8 = s3; @@ -196,10 +196,10 @@ void test_string_assign() { sink(s3.assign(s1)); sink(s3); - sink(s4.assign(s2)); // $ ast MISSING: ir + sink(s4.assign(s2)); // $ ast,ir sink(s4); // $ ast,ir - sink(s5.assign(10, c)); // $ ast MISSING: ir + sink(s5.assign(10, c)); // $ ast,ir sink(s5); // $ ast,ir sink(s6.assign(s1)); @@ -217,15 +217,15 @@ void test_string_insert() { sink(s3); s4 = s2; - sink(s4.insert(0, s1)); // $ ast MISSING: ir + sink(s4.insert(0, s1)); // $ ast,ir sink(s4); // $ ast,ir s5 = s1; - sink(s5.insert(0, s2)); // $ ast MISSING: ir + sink(s5.insert(0, s2)); // $ ast,ir sink(s5); // $ ast,ir s6 = s1; - sink(s6.insert(0, 10, c)); // $ ast MISSING: ir + sink(s6.insert(0, 10, c)); // $ ast,ir sink(s6); // $ ast,ir } @@ -240,15 +240,15 @@ void test_string_replace() { sink(s3); s4 = s2; - sink(s4.replace(1, 2, s1)); // $ ast MISSING: ir + sink(s4.replace(1, 2, s1)); // $ ast,ir sink(s4); // $ ast,ir s5 = s1; - sink(s5.replace(1, 2, s2)); // $ ast MISSING: ir + sink(s5.replace(1, 2, s2)); // $ ast,ir sink(s5); // $ ast,ir s6 = s1; - sink(s6.replace(1, 2, 10, c)); // $ ast MISSING: ir + sink(s6.replace(1, 2, 10, c)); // $ ast,ir sink(s6); // $ ast,ir } @@ -309,7 +309,7 @@ void test_string_data() std::string b(source()); sink(a.data()); - sink(b.data()); // $ ast MISSING: ir + sink(b.data()); // $ ast,ir sink(a.length()); sink(b.length()); } @@ -360,7 +360,7 @@ void test_string_iterators() { std::string s4("world"); sink(s1); - sink(s1.append(s2.begin(), s2.end())); // $ ast MISSING: ir + sink(s1.append(s2.begin(), s2.end())); // $ ast,ir sink(s1); // $ ast,ir sink(s3); @@ -433,7 +433,7 @@ void test_string_insert_more() sink(s1.insert(0, cs1)); sink(s1); - sink(s2.insert(0, cs2)); // $ ast MISSING: ir + sink(s2.insert(0, cs2)); // $ ast,ir sink(s2); // $ ast,ir } @@ -446,7 +446,7 @@ void test_string_iterator_methods() sink(a.insert(a.begin(), 10, 'x')); sink(a); - sink(b.insert(b.begin(), 10, ns_char::source())); // $ ast MISSING: ir + sink(b.insert(b.begin(), 10, ns_char::source())); // $ ast,ir sink(b); // $ ast,ir } @@ -459,10 +459,10 @@ void test_string_iterator_methods() sink(c.insert(c.end(), s1.begin(), s1.end())); sink(c); - sink(d.insert(d.end(), s2.begin(), s2.end())); // $ ast MISSING: ir + sink(d.insert(d.end(), s2.begin(), s2.end())); // $ ast,ir sink(d); // $ ast,ir - sink(s2.insert(s2.end(), s1.begin(), s1.end())); // $ ast MISSING: ir + sink(s2.insert(s2.end(), s1.begin(), s1.end())); // $ ast,ir sink(s2); // $ ast,ir } @@ -475,10 +475,10 @@ void test_string_iterator_methods() sink(e.append(s3.begin(), s3.end())); sink(e); - sink(f.append(s4.begin(), s4.end())); // $ ast MISSING: ir + sink(f.append(s4.begin(), s4.end())); // $ ast,ir sink(f); // $ ast,ir - sink(s4.append(s3.begin(), s3.end())); // $ ast MISSING: ir + sink(s4.append(s3.begin(), s3.end())); // $ ast,ir sink(s4); // $ ast,ir } @@ -491,7 +491,7 @@ void test_string_iterator_methods() sink(g.assign(s5.cbegin(), s5.cend())); sink(g); - sink(h.assign(s6.cbegin(), s6.cend())); // $ ast MISSING: ir + sink(h.assign(s6.cbegin(), s6.cend())); // $ ast,ir sink(h); // $ ast,ir sink(s6.assign(s5.cbegin(), s5.cend())); @@ -519,8 +519,8 @@ void test_string_front_back() { sink(a.front()); sink(a.back()); a.push_back(ns_char::source()); - sink(a.front()); // $ SPURIOUS: ast - sink(a.back()); // $ ast MISSING: ir + sink(a.front()); // $ SPURIOUS: ast,ir + sink(a.back()); // $ ast,ir } void test_string_return_assign() { @@ -533,12 +533,12 @@ void test_string_return_assign() { std::string f("ff"); sink( a += (b += "bb") ); - sink( c += (d += source()) ); // $ ast MISSING: ir - sink( (e += "ee") += source() ); // $ ast MISSING: ir - sink( (f += source()) += "ff" ); // $ ast MISSING: ir + sink( c += (d += source()) ); // $ ast,ir + sink( (e += "ee") += source() ); // $ ast,ir + sink( (f += source()) += "ff" ); // $ ast,ir sink(a); sink(b); - sink(c); // $ ast MISSING: ir + sink(c); // $ ast,ir sink(d); // $ ast,ir sink(e); // $ ast MISSING: ir sink(f); // $ ast,ir @@ -553,12 +553,12 @@ void test_string_return_assign() { std::string f("ff"); sink( a.assign(b.assign("bb")) ); - sink( c.assign(d.assign(source())) ); // $ ast MISSING: ir - sink( e.assign("ee").assign(source()) ); // $ ast MISSING: ir + sink( c.assign(d.assign(source())) ); // $ ast,ir + sink( e.assign("ee").assign(source()) ); // $ ast,ir sink( f.assign(source()).assign("ff") ); sink(a); sink(b); - sink(c); // $ ast MISSING: ir + sink(c); // $ ast,ir sink(d); // $ ast,ir sink(e); // $ ast MISSING: ir sink(f); // $ SPURIOUS: ast,ir diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp index fab96fc878d..249c8ac21bf 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp @@ -53,15 +53,15 @@ void test_stringstream_string(int amount) sink(ss7); // $ SPURIOUS: ast,ir sink(ss8.put('a')); - sink(ss9.put(ns_char::source())); // $ ast MISSING: ir - sink(ss10.put('a').put(ns_char::source()).put('z')); // $ ast MISSING: ir + sink(ss9.put(ns_char::source())); // $ ast,ir + sink(ss10.put('a').put(ns_char::source()).put('z')); // $ ast,ir sink(ss8); sink(ss9); // $ ast,ir sink(ss10); // $ ast MISSING: ir sink(ss11.write("begin", 5)); - sink(ss12.write(source(), 5)); // $ ast MISSING: ir - sink(ss13.write("begin", 5).write(source(), amount).write("end", 3)); // $ ast MISSING: ir + sink(ss12.write(source(), 5)); // $ ast,ir + sink(ss13.write("begin", 5).write(source(), amount).write("end", 3)); // $ ast,ir sink(ss11); sink(ss12); // $ ast,ir sink(ss13); // $ ast MISSING: ir @@ -73,7 +73,7 @@ void test_stringstream_int(int source) int v1 = 0, v2 = 0; sink(ss1 << 1234); - sink(ss2 << source); // $ ast MISSING: ir + sink(ss2 << source); // $ ast,ir sink(ss1 >> v1); sink(ss2 >> v2); // $ ast,ir @@ -97,7 +97,7 @@ void test_stringstream_constructors() std::stringstream ss6; sink(ss5 = std::stringstream("abc")); - sink(ss6 = std::stringstream(source())); // $ ast MISSING: ir + sink(ss6 = std::stringstream(source())); // $ ast,ir sink(ss1); sink(ss2); // $ ast,ir @@ -193,7 +193,7 @@ void test_stringstream_putback() sink(ss.get()); sink(ss.putback('b')); sink(ss.get()); - sink(ss.putback(ns_char::source())); // $ ast MISSING: ir + sink(ss.putback(ns_char::source())); // $ ast,ir sink(ss.get()); // $ ast,ir } @@ -263,6 +263,6 @@ void test_chaining() sink(b1); // $ ast,ir sink(b2); // $ ast,ir - sink(ss2.write("abc", 3).flush().write(source(), 3).flush().write("xyz", 3)); // $ ast MISSING: ir + sink(ss2.write("abc", 3).flush().write(source(), 3).flush().write("xyz", 3)); // $ ast,ir sink(ss2); // $ ast MISSING: ir } diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp index 9434dbe52ae..92a44f2950c 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp @@ -466,7 +466,7 @@ void test_qualifiers() sink(d.getString()); d.setString(strings::source()); sink(d); // $ ast,ir - sink(d.getString()); // $ ast MISSING: ir + sink(d.getString()); // $ ast,ir } // --- non-standard swap --- diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp index 4f0c8fab414..aacef1f4a5b 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp @@ -68,8 +68,8 @@ void test_element_taint(int x) { v5.push_back(source()); sink(v5); // $ ast,ir - sink(v5.front()); // $ SPURIOUS: ast - sink(v5.back()); // $ ast MISSING: ir + sink(v5.front()); // $ SPURIOUS: ast,ir + sink(v5.back()); // $ ast,ir v6.data()[2] = source(); sink(v6); // $ ast MISSING: ir @@ -81,8 +81,8 @@ void test_element_taint(int x) { v7.insert(it, source()); } sink(v7); // $ ast,ir - sink(v7.front()); // $ ast MISSING: ir - sink(v7.back()); // $ SPURIOUS: ast + sink(v7.front()); // $ ast,ir + sink(v7.back()); // $ SPURIOUS: ast,ir { const std::vector &v8c = v8; @@ -283,8 +283,8 @@ void test_data_more() { v1.push_back(source()); sink(v1); // $ ast,ir - sink(v1.data()); // $ ast MISSING: ir - sink(v1.data()[2]); // $ ast MISSING: ir + sink(v1.data()); // $ ast,ir + sink(v1.data()[2]); // $ ast,ir *(v2.data()) = ns_int::source(); sink(v2); // $ ast MISSING: ir @@ -305,10 +305,10 @@ void test_vector_insert() { sink(a.insert(a.end(), b.begin(), b.end())); sink(a); - sink(c.insert(c.end(), d.begin(), d.end())); // $ ast MISSING: ir + sink(c.insert(c.end(), d.begin(), d.end())); // $ ast,ir sink(c); // $ ast,ir - sink(d.insert(d.end(), a.begin(), a.end())); // $ ast MISSING: ir + sink(d.insert(d.end(), a.begin(), a.end())); // $ ast,ir sink(d); // $ ast,ir } diff --git a/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/lowerBound.expected b/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/lowerBound.expected index 7478060a95b..112b6cb0201 100644 --- a/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/lowerBound.expected +++ b/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/lowerBound.expected @@ -594,6 +594,15 @@ | test.c:659:9:659:9 | u | 0 | | test.c:664:12:664:12 | s | -2147483648 | | test.c:665:7:665:8 | s2 | -4 | +| test.c:670:7:670:7 | x | -2147483648 | +| test.c:671:9:671:9 | y | -2147483648 | +| test.c:675:7:675:7 | y | -2147483648 | +| test.c:684:7:684:7 | x | -2147483648 | +| test.c:689:7:689:7 | x | -2147483648 | +| test.c:696:8:696:8 | x | 2147483647 | +| test.c:696:12:696:12 | y | 256 | +| test.c:697:9:697:9 | x | 2147483647 | +| test.c:698:9:698:9 | y | 256 | | test.cpp:10:7:10:7 | b | -2147483648 | | test.cpp:11:5:11:5 | x | -2147483648 | | test.cpp:13:10:13:10 | x | -2147483648 | @@ -647,16 +656,18 @@ | test.cpp:97:10:97:10 | i | -2147483648 | | test.cpp:97:22:97:22 | i | -2147483648 | | test.cpp:98:5:98:5 | i | -2147483648 | -| test.cpp:105:7:105:7 | n | -32768 | -| test.cpp:108:7:108:7 | n | 0 | -| test.cpp:109:5:109:5 | n | 1 | -| test.cpp:111:5:111:5 | n | 0 | -| test.cpp:114:8:114:8 | n | 0 | -| test.cpp:115:5:115:5 | n | 0 | -| test.cpp:117:5:117:5 | n | 1 | -| test.cpp:120:3:120:3 | n | 0 | -| test.cpp:120:8:120:8 | n | 1 | -| test.cpp:120:12:120:12 | n | 0 | -| test.cpp:121:4:121:4 | n | 0 | -| test.cpp:121:8:121:8 | n | 0 | -| test.cpp:121:12:121:12 | n | 1 | +| test.cpp:98:9:98:9 | i | -2147483648 | +| test.cpp:99:5:99:5 | i | -2147483648 | +| test.cpp:106:7:106:7 | n | -32768 | +| test.cpp:109:7:109:7 | n | 0 | +| test.cpp:110:5:110:5 | n | 1 | +| test.cpp:112:5:112:5 | n | 0 | +| test.cpp:115:8:115:8 | n | 0 | +| test.cpp:116:5:116:5 | n | 0 | +| test.cpp:118:5:118:5 | n | 1 | +| test.cpp:121:3:121:3 | n | 0 | +| test.cpp:121:8:121:8 | n | 1 | +| test.cpp:121:12:121:12 | n | 0 | +| test.cpp:122:4:122:4 | n | 0 | +| test.cpp:122:8:122:8 | n | 0 | +| test.cpp:122:12:122:12 | n | 1 | diff --git a/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/ternaryLower.expected b/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/ternaryLower.expected index fedd3853ce2..f012490f115 100644 --- a/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/ternaryLower.expected +++ b/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/ternaryLower.expected @@ -15,5 +15,5 @@ | test.c:394:20:394:36 | ... ? ... : ... | 0.0 | 0.0 | 100.0 | | test.c:606:5:606:14 | ... ? ... : ... | 0.0 | 1.0 | 0.0 | | test.c:607:5:607:14 | ... ? ... : ... | 0.0 | 0.0 | 1.0 | -| test.cpp:120:3:120:12 | ... ? ... : ... | 0.0 | 1.0 | 0.0 | -| test.cpp:121:3:121:12 | ... ? ... : ... | 0.0 | 0.0 | 1.0 | +| test.cpp:121:3:121:12 | ... ? ... : ... | 0.0 | 1.0 | 0.0 | +| test.cpp:122:3:122:12 | ... ? ... : ... | 0.0 | 0.0 | 1.0 | diff --git a/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/ternaryUpper.expected b/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/ternaryUpper.expected index 0b8fe8c1164..8a387c3ae46 100644 --- a/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/ternaryUpper.expected +++ b/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/ternaryUpper.expected @@ -15,5 +15,5 @@ | test.c:394:20:394:36 | ... ? ... : ... | 100.0 | 99.0 | 100.0 | | test.c:606:5:606:14 | ... ? ... : ... | 32767.0 | 32767.0 | 0.0 | | test.c:607:5:607:14 | ... ? ... : ... | 32767.0 | 0.0 | 32767.0 | -| test.cpp:120:3:120:12 | ... ? ... : ... | 32767.0 | 32767.0 | 0.0 | -| test.cpp:121:3:121:12 | ... ? ... : ... | 32767.0 | 0.0 | 32767.0 | +| test.cpp:121:3:121:12 | ... ? ... : ... | 32767.0 | 32767.0 | 0.0 | +| test.cpp:122:3:122:12 | ... ? ... : ... | 32767.0 | 0.0 | 32767.0 | diff --git a/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/test.c b/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/test.c index 40168c3e697..8c7978ac4aa 100644 --- a/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/test.c +++ b/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/test.c @@ -664,3 +664,37 @@ void test_mod(int s) { int s2 = s % 5; out(s2); // -4 .. 4 } + +void exit(int); +void guard_with_exit(int x, int y) { + if (x) { + if (y != 0) { + exit(0); + } + } + out(y); // .. + + // This test ensures that we correctly identify + // that the upper bound for y is max_int when calling `out(y)`. + // The RangeSsa will place guardPhy on `out(y)`, and consequently there is no + // frontier phi node at out(y). +} + +void test(int x) { + if (x >= 10) { + return; + } + // The basic below has two predecessors. +label: + out(x); + goto label; +} + +void test_overflow() { + const int x = 2147483647; // 2^31-1 + const int y = 256; + if ((x + y) <= 512) { + out(x); + out(y); + } +} diff --git a/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/test.cpp b/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/test.cpp index 515633f4f73..e5eb9554966 100644 --- a/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/test.cpp +++ b/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/test.cpp @@ -95,6 +95,7 @@ int ref_to_number(int &i, const int &ci, int &aliased) { return alias; for (; i <= 12345; i++) { // test that widening works for references + i = i; i; } diff --git a/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/upperBound.expected b/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/upperBound.expected index ce6bed728eb..8772a763a4d 100644 --- a/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/upperBound.expected +++ b/cpp/ql/test/library-tests/rangeanalysis/SimpleRangeAnalysis/upperBound.expected @@ -584,9 +584,9 @@ | test.c:639:9:639:10 | ss | 2 | | test.c:645:8:645:8 | s | 2147483647 | | test.c:645:15:645:15 | s | 127 | -| test.c:645:23:645:23 | s | 15 | -| test.c:646:18:646:18 | s | 15 | -| test.c:646:22:646:22 | s | 15 | +| test.c:645:23:645:23 | s | 9 | +| test.c:646:18:646:18 | s | 9 | +| test.c:646:22:646:22 | s | 9 | | test.c:647:9:647:14 | result | 127 | | test.c:653:7:653:7 | i | 0 | | test.c:654:9:654:9 | i | 2147483647 | @@ -594,6 +594,15 @@ | test.c:659:9:659:9 | u | 4294967295 | | test.c:664:12:664:12 | s | 2147483647 | | test.c:665:7:665:8 | s2 | 4 | +| test.c:670:7:670:7 | x | 2147483647 | +| test.c:671:9:671:9 | y | 2147483647 | +| test.c:675:7:675:7 | y | 2147483647 | +| test.c:684:7:684:7 | x | 2147483647 | +| test.c:689:7:689:7 | x | 15 | +| test.c:696:8:696:8 | x | 2147483647 | +| test.c:696:12:696:12 | y | 256 | +| test.c:697:9:697:9 | x | 2147483647 | +| test.c:698:9:698:9 | y | 256 | | test.cpp:10:7:10:7 | b | 2147483647 | | test.cpp:11:5:11:5 | x | 2147483647 | | test.cpp:13:10:13:10 | x | 2147483647 | @@ -646,17 +655,19 @@ | test.cpp:95:12:95:16 | alias | 2147483647 | | test.cpp:97:10:97:10 | i | 65535 | | test.cpp:97:22:97:22 | i | 32767 | -| test.cpp:98:5:98:5 | i | 32767 | -| test.cpp:105:7:105:7 | n | 32767 | -| test.cpp:108:7:108:7 | n | 32767 | -| test.cpp:109:5:109:5 | n | 32767 | -| test.cpp:111:5:111:5 | n | 0 | -| test.cpp:114:8:114:8 | n | 32767 | -| test.cpp:115:5:115:5 | n | 0 | -| test.cpp:117:5:117:5 | n | 32767 | -| test.cpp:120:3:120:3 | n | 32767 | -| test.cpp:120:8:120:8 | n | 32767 | -| test.cpp:120:12:120:12 | n | 0 | -| test.cpp:121:4:121:4 | n | 32767 | -| test.cpp:121:8:121:8 | n | 0 | -| test.cpp:121:12:121:12 | n | 32767 | +| test.cpp:98:5:98:5 | i | 2147483647 | +| test.cpp:98:9:98:9 | i | 12345 | +| test.cpp:99:5:99:5 | i | 32767 | +| test.cpp:106:7:106:7 | n | 32767 | +| test.cpp:109:7:109:7 | n | 32767 | +| test.cpp:110:5:110:5 | n | 32767 | +| test.cpp:112:5:112:5 | n | 0 | +| test.cpp:115:8:115:8 | n | 32767 | +| test.cpp:116:5:116:5 | n | 0 | +| test.cpp:118:5:118:5 | n | 32767 | +| test.cpp:121:3:121:3 | n | 32767 | +| test.cpp:121:8:121:8 | n | 32767 | +| test.cpp:121:12:121:12 | n | 0 | +| test.cpp:122:4:122:4 | n | 32767 | +| test.cpp:122:8:122:8 | n | 0 | +| test.cpp:122:12:122:12 | n | 32767 | diff --git a/cpp/ql/test/query-tests/Critical/OverflowStatic/OverflowStatic.expected b/cpp/ql/test/query-tests/Critical/OverflowStatic/OverflowStatic.expected index 01a2dfc38b3..0e5bbee7d73 100644 --- a/cpp/ql/test/query-tests/Critical/OverflowStatic/OverflowStatic.expected +++ b/cpp/ql/test/query-tests/Critical/OverflowStatic/OverflowStatic.expected @@ -5,10 +5,10 @@ | test2.c:33:26:33:27 | 46 | Potential buffer-overflow: 'buffer' has size 40 not 46. | | test2.c:34:22:34:23 | 47 | Potential buffer-overflow: 'buffer' has size 40 not 47. | | test2.c:35:23:35:24 | 48 | Potential buffer-overflow: 'buffer' has size 40 not 48. | -| test.c:14:9:14:13 | access to array | Potential buffer-overflow: 'xs' has size 5 but 'xs[5]' is accessed here. | -| test.c:15:9:15:13 | access to array | Potential buffer-overflow: 'xs' has size 5 but 'xs[6]' is accessed here. | -| test.c:20:9:20:18 | access to array | Potential buffer-overflow: 'ys' has size 5 but 'ys[5]' is accessed here. | -| test.c:21:9:21:18 | access to array | Potential buffer-overflow: 'ys' has size 5 but 'ys[6]' is accessed here. | +| test.c:14:9:14:13 | access to array | Potential buffer-overflow: 'xs' has size 5 but 'xs[5]' may be accessed here. | +| test.c:15:9:15:13 | access to array | Potential buffer-overflow: 'xs' has size 5 but 'xs[6]' may be accessed here. | +| test.c:20:9:20:18 | access to array | Potential buffer-overflow: 'ys' has size 5 but 'ys[5]' may be accessed here. | +| test.c:21:9:21:18 | access to array | Potential buffer-overflow: 'ys' has size 5 but 'ys[6]' may be accessed here. | | test.cpp:19:3:19:12 | access to array | Potential buffer-overflow: counter 'i' <= 3 but 'buffer1' has 3 elements. | | test.cpp:20:3:20:12 | access to array | Potential buffer-overflow: counter 'i' <= 3 but 'buffer2' has 3 elements. | | test.cpp:24:27:24:27 | 4 | Potential buffer-overflow: 'buffer1' has size 3 not 4. | diff --git a/cpp/ql/test/query-tests/Critical/OverflowStatic/test.c b/cpp/ql/test/query-tests/Critical/OverflowStatic/test.c index baa8999412c..3c726a452b9 100644 --- a/cpp/ql/test/query-tests/Critical/OverflowStatic/test.c +++ b/cpp/ql/test/query-tests/Critical/OverflowStatic/test.c @@ -27,3 +27,47 @@ void f(void) { c = stru.zs[6]; // GOOD (zs is variable size) } +void* malloc(long unsigned int); +void test_buffer_sentinal() { + struct { char len; char buf[1]; } *b = malloc(10); // len(buf.buffer) effectively 8 + b->buf[0] = 0; // GOOD + b->buf[7] = 0; // GOOD + b->buf[8] = 0; // BAD [NOT DETECTED] +} + +union u { + unsigned long value; + char ptr[1]; +}; + +void union_test() { + union u u; + u.ptr[0] = 0; // GOOD + u.ptr[sizeof(u)-1] = 0; // GOOD + u.ptr[sizeof(u)] = 0; // BAD [NOT DETECTED] +} + +void test_struct_union() { + struct { union u u; } v; + v.u.ptr[0] = 0; // GOOD + v.u.ptr[sizeof(union u)-1] = 0; // GOOD + v.u.ptr[sizeof(union u)] = 0; // BAD [NOT DETECTED] +} + +void union_test2() { + union { char ptr[1]; unsigned long value; } u; + u.ptr[0] = 0; // GOOD + u.ptr[sizeof(u)-1] = 0; // GOOD + u.ptr[sizeof(u)] = 0; // BAD [NOT DETECTED] +} + +typedef struct { + char len; + char buf[1]; +} var_buf; + +void test_alloc() { + // Special case of taking sizeof without any addition or multiplications + var_buf *b = malloc(sizeof(var_buf)); + b->buf[1] = 0; // BAD [NOT DETECTED] +} diff --git a/cpp/ql/test/query-tests/Critical/OverflowStatic/test.cpp b/cpp/ql/test/query-tests/Critical/OverflowStatic/test.cpp index be9e14bd841..01a4a0adaef 100644 --- a/cpp/ql/test/query-tests/Critical/OverflowStatic/test.cpp +++ b/cpp/ql/test/query-tests/Critical/OverflowStatic/test.cpp @@ -46,3 +46,13 @@ void f2(char *src) ptr = &(buffer[1]); memcpy(ptr, src, 100); // BAD [NOT DETECTED] } + +void f3() { + int i; + char buffer[5]; + for (i=0; i<10; i++) { + if (i < 5) { + buffer[i] = 0; // GOOD + } + } +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/PointlessComparison.c b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/PointlessComparison.c index 9fc257e3eeb..fd1bc655051 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/PointlessComparison.c +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/PointlessComparison.c @@ -115,7 +115,7 @@ int twoReasons(int a, int b) { if (a <= 0 && b > 5) { return a < b; } - if (a <= 100 && b > 105) { + if (a <= 100 && b > 105) { // BUG [Not detected - this clause is always false] return a > b; } return 0; diff --git a/cpp/ql/test/query-tests/Likely Bugs/Conversion/CastArrayPointerArithmetic/CastArrayPointerArithmetic.expected b/cpp/ql/test/query-tests/Likely Bugs/Conversion/CastArrayPointerArithmetic/CastArrayPointerArithmetic.expected index db84b3b0911..794a7fba821 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Conversion/CastArrayPointerArithmetic/CastArrayPointerArithmetic.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Conversion/CastArrayPointerArithmetic/CastArrayPointerArithmetic.expected @@ -34,6 +34,7 @@ nodes | test.cpp:88:21:88:22 | d2 | semmle.label | d2 | | test.cpp:95:21:95:21 | d | semmle.label | d | | test.cpp:96:21:96:23 | dss | semmle.label | dss | +subpaths #select | test.cpp:27:2:27:2 | b | test.cpp:57:19:57:19 | d | test.cpp:27:2:27:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:57:19:57:19 | d | here | | test.cpp:27:2:27:2 | b | test.cpp:74:19:74:21 | dss | test.cpp:27:2:27:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:74:19:74:21 | dss | here | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/ImproperNullTermination.expected b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/ImproperNullTermination.expected index b8f5c71e8e2..c83205ef49f 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/ImproperNullTermination.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/ImproperNullTermination.expected @@ -23,3 +23,5 @@ | test.cpp:365:19:365:25 | buffer2 | Variable $@ may not be null terminated. | test.cpp:363:8:363:14 | buffer2 | buffer2 | | test.cpp:392:17:392:22 | buffer | Variable $@ may not be null terminated. | test.cpp:390:8:390:13 | buffer | buffer | | test.cpp:398:18:398:23 | buffer | Variable $@ may not be null terminated. | test.cpp:396:8:396:13 | buffer | buffer | +| test.cpp:444:10:444:15 | buffer | Variable $@ may not be null terminated. | test.cpp:442:8:442:13 | buffer | buffer | +| test.cpp:450:16:450:21 | buffer | Variable $@ may not be null terminated. | test.cpp:448:8:448:13 | buffer | buffer | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/test.cpp b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/test.cpp index 7fa4ef60093..45410c15ebf 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/test.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/test.cpp @@ -433,3 +433,36 @@ void test_read_fread(int read_src, FILE *s) strlen(buffer); // GOOD } } + +int printf(const char *format, ...); + +void test_printf(char *str) +{ + { + char buffer[1024]; + + printf(buffer, ""); // BAD + } + + { + char buffer[1024]; + + printf("%s", buffer); // BAD + } + + { + size_t len = strlen(str); + char *copied_str = (char *)malloc(len); + + memcpy(copied_str, str, len); + printf("%s", copied_str); // BAD [NOT DETECTED] + } + + { + size_t len = strlen(str); + char *copied_str = (char *)malloc(len + 1); + + memcpy(copied_str, str, len + 1); + printf("%s", copied_str); // GOOD + } +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-022/SAMATE/TaintedPath/CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-022/SAMATE/TaintedPath/CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp new file mode 100644 index 00000000000..876584c5117 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-022/SAMATE/TaintedPath/CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp @@ -0,0 +1,134 @@ +/** + * This test case is closely based on CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp + * from the SAMATE Juliet test suite. + */ + +#define NULL (0) + +typedef unsigned long size_t; +typedef size_t time_t; +time_t time(time_t *timer); + +typedef struct {} FILE; +extern FILE *stdin; +FILE *fopen(const char *filename, const char *mode); +int fclose(FILE *stream); +#define FILENAME_MAX (4096) + +typedef unsigned long size_t; +size_t strlen(const char *s); +char *strcat(char *s1, const char *s2); +char *fgets(char *s, int n, FILE *stream); + +int globalReturnsTrue() +{ + return 1; +} + +int globalReturnsFalse() +{ + return 0; +} + +void printLine(const char *str); + +#define BASEPATH "c:\\temp\\" +#define FOPEN fopen + +namespace CWE23_Relative_Path_Traversal__char_console_fopen_11 +{ + +void bad() +{ + char * data; + char dataBuffer[FILENAME_MAX] = BASEPATH; + data = dataBuffer; + if(globalReturnsTrue()) + { + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (FILENAME_MAX-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console */ + if (fgets(data+dataLen, (int)(FILENAME_MAX-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine("fgets() failed"); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + } + { + FILE *pFile = NULL; + /* POTENTIAL FLAW: Possibly opening a file without validating the file name or path */ + pFile = FOPEN(data, "wb+"); + if (pFile != NULL) + { + fclose(pFile); + } + } +} + +/* goodG2B1() - use goodsource and badsink by changing the globalReturnsTrue() to globalReturnsFalse() */ +static void goodG2B1() +{ + char * data; + char dataBuffer[FILENAME_MAX] = BASEPATH; + data = dataBuffer; + if(globalReturnsFalse()) + { + /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ + printLine("Benign, fixed string"); + } + else + { + /* FIX: Use a fixed file name */ + strcat(data, "file.txt"); + } + { + FILE *pFile = NULL; + /* POTENTIAL FLAW: Possibly opening a file without validating the file name or path */ + pFile = FOPEN(data, "wb+"); + if (pFile != NULL) + { + fclose(pFile); + } + } +} + +/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ +static void goodG2B2() +{ + char * data; + char dataBuffer[FILENAME_MAX] = BASEPATH; + data = dataBuffer; + if(globalReturnsTrue()) + { + /* FIX: Use a fixed file name */ + strcat(data, "file.txt"); + } + { + FILE *pFile = NULL; + /* POTENTIAL FLAW: Possibly opening a file without validating the file name or path */ + pFile = FOPEN(data, "wb+"); + if (pFile != NULL) + { + fclose(pFile); + } + } +} + +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-022/SAMATE/TaintedPath/TaintedPath.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-022/SAMATE/TaintedPath/TaintedPath.expected new file mode 100644 index 00000000000..6271123d9d1 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-022/SAMATE/TaintedPath/TaintedPath.expected @@ -0,0 +1,18 @@ +edges +| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... | +| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | +| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | +| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... | +| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | +| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | +subpaths +nodes +| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | semmle.label | ... + ... | +| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | semmle.label | fgets output argument | +| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... | semmle.label | (const char *)... | +| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... | semmle.label | (const char *)... | +| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | semmle.label | data | +| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | semmle.label | data indirection | +| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | semmle.label | data indirection | +#select +| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | This argument to a file access function is derived from $@ and then passed to fopen(filename) | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | user input (fgets) | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-022/SAMATE/TaintedPath/TaintedPath.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-022/SAMATE/TaintedPath/TaintedPath.qlref new file mode 100644 index 00000000000..1677939387d --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-022/SAMATE/TaintedPath/TaintedPath.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-022/TaintedPath.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected index 7b513c574ad..cb8dfd321b3 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected @@ -5,6 +5,7 @@ edges | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName | | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection | | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection | +subpaths nodes | test.c:9:23:9:26 | argv | semmle.label | argv | | test.c:9:23:9:26 | argv | semmle.label | argv | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-078/SAMATE/ExecTainted/ExecTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-078/SAMATE/ExecTainted/ExecTainted.expected new file mode 100644 index 00000000000..51c8906abb5 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-078/SAMATE/ExecTainted/ExecTainted.expected @@ -0,0 +1,17 @@ +edges +| tests.cpp:33:34:33:39 | call to getenv | tests.cpp:38:39:38:49 | environment indirection | +| tests.cpp:38:25:38:36 | strncat output argument | tests.cpp:42:5:42:16 | Phi | +| tests.cpp:38:39:38:49 | environment indirection | tests.cpp:38:25:38:36 | strncat output argument | +| tests.cpp:38:39:38:49 | environment indirection | tests.cpp:38:25:38:36 | strncat output argument | +| tests.cpp:42:5:42:16 | Phi | tests.cpp:51:22:51:25 | badSource output argument | +| tests.cpp:51:22:51:25 | badSource output argument | tests.cpp:53:16:53:19 | data indirection | +nodes +| tests.cpp:33:34:33:39 | call to getenv | semmle.label | call to getenv | +| tests.cpp:38:25:38:36 | strncat output argument | semmle.label | strncat output argument | +| tests.cpp:38:39:38:49 | environment indirection | semmle.label | environment indirection | +| tests.cpp:42:5:42:16 | Phi | semmle.label | Phi | +| tests.cpp:51:22:51:25 | badSource output argument | semmle.label | badSource output argument | +| tests.cpp:53:16:53:19 | data indirection | semmle.label | data indirection | +subpaths +#select +| tests.cpp:53:16:53:19 | data | tests.cpp:33:34:33:39 | call to getenv | tests.cpp:53:16:53:19 | data indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string) | tests.cpp:33:34:33:39 | call to getenv | user input (an environment variable) | tests.cpp:38:25:38:36 | strncat output argument | strncat output argument | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-078/SAMATE/ExecTainted/ExecTainted.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-078/SAMATE/ExecTainted/ExecTainted.qlref new file mode 100644 index 00000000000..9fe2347270f --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-078/SAMATE/ExecTainted/ExecTainted.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-078/ExecTainted.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-078/SAMATE/ExecTainted/tests.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-078/SAMATE/ExecTainted/tests.cpp new file mode 100644 index 00000000000..80f8221d903 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-078/SAMATE/ExecTainted/tests.cpp @@ -0,0 +1,58 @@ +//semmle-extractor-options: --edg --target --edg win64 + +// A selection of tests from the SAMATE Juliet framework for rule CWE-78. + +// library types, functions etc +#define NULL (0) +typedef unsigned long size_t; +size_t strlen(const char *s); +char *strncat(char *s1, const char *s2, size_t n); +char *getenv(const char *name); +int system(const char *string); +void exit(int status); + +#define FULL_COMMAND "dir " +#define ENV_VARIABLE "ADD" +#define GETENV getenv +#define SYSTEM system + +void printLine(const char *str); + +// ---------- + +/* The static variable below is used to drive control flow in the source function */ +static int badStatic = 0; + +static char * badSource(char * data) +{ + if(badStatic) + { + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + } + return data; +} + +void CWE78_OS_Command_Injection__char_environment_system_21_bad() +{ + char * data; + char data_buf[100] = FULL_COMMAND; + data = data_buf; + badStatic = 1; /* true */ + data = badSource(data); + /* POTENTIAL FLAW: Execute command in data possibly leading to command injection [NOT DETECTED] */ + if (SYSTEM(data) != 0) + { + printLine("command execution failed!"); + exit(1); + } +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected index a78a7a99d90..4b1b5a61ace 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected @@ -1 +1,85 @@ -| test.c:21:12:21:19 | command1 | This argument to an OS command is derived from $@ and then passed to system(string) | test.c:14:20:14:23 | argv | user input (argv) | +edges +| test.cpp:16:20:16:23 | argv | test.cpp:22:45:22:52 | userName indirection | +| test.cpp:22:13:22:20 | sprintf output argument | test.cpp:23:12:23:19 | command1 indirection | +| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:13:22:20 | sprintf output argument | +| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:13:22:20 | sprintf output argument | +| test.cpp:47:21:47:26 | call to getenv | test.cpp:50:35:50:43 | envCflags indirection | +| test.cpp:50:11:50:17 | sprintf output argument | test.cpp:51:10:51:16 | command indirection | +| test.cpp:50:35:50:43 | envCflags indirection | test.cpp:50:11:50:17 | sprintf output argument | +| test.cpp:50:35:50:43 | envCflags indirection | test.cpp:50:11:50:17 | sprintf output argument | +| test.cpp:62:9:62:16 | fread output argument | test.cpp:64:20:64:27 | filename indirection | +| test.cpp:64:11:64:17 | strncat output argument | test.cpp:65:10:65:16 | command indirection | +| test.cpp:64:20:64:27 | filename indirection | test.cpp:64:11:64:17 | strncat output argument | +| test.cpp:64:20:64:27 | filename indirection | test.cpp:64:11:64:17 | strncat output argument | +| test.cpp:82:9:82:16 | fread output argument | test.cpp:84:20:84:27 | filename indirection | +| test.cpp:84:11:84:17 | strncat output argument | test.cpp:85:32:85:38 | command indirection | +| test.cpp:84:20:84:27 | filename indirection | test.cpp:84:11:84:17 | strncat output argument | +| test.cpp:84:20:84:27 | filename indirection | test.cpp:84:11:84:17 | strncat output argument | +| test.cpp:91:9:91:16 | fread output argument | test.cpp:93:17:93:24 | filename indirection | +| test.cpp:93:11:93:14 | strncat output argument | test.cpp:94:45:94:48 | path indirection | +| test.cpp:93:17:93:24 | filename indirection | test.cpp:93:11:93:14 | strncat output argument | +| test.cpp:93:17:93:24 | filename indirection | test.cpp:93:11:93:14 | strncat output argument | +| test.cpp:106:20:106:25 | call to getenv | test.cpp:107:33:107:36 | path indirection | +| test.cpp:107:31:107:31 | call to operator+ | test.cpp:108:18:108:22 | call to c_str indirection | +| test.cpp:107:33:107:36 | path indirection | test.cpp:107:31:107:31 | call to operator+ | +| test.cpp:107:33:107:36 | path indirection | test.cpp:107:31:107:31 | call to operator+ | +| test.cpp:113:20:113:25 | call to getenv | test.cpp:114:19:114:22 | path indirection | +| test.cpp:114:17:114:17 | Call | test.cpp:114:25:114:29 | call to c_str indirection | +| test.cpp:114:19:114:22 | path indirection | test.cpp:114:17:114:17 | Call | +| test.cpp:114:19:114:22 | path indirection | test.cpp:114:17:114:17 | Call | +| test.cpp:119:20:119:25 | call to getenv | test.cpp:120:19:120:22 | path indirection | +| test.cpp:120:17:120:17 | Call | test.cpp:120:10:120:30 | call to data indirection | +| test.cpp:120:19:120:22 | path indirection | test.cpp:120:17:120:17 | Call | +| test.cpp:120:19:120:22 | path indirection | test.cpp:120:17:120:17 | Call | +| test.cpp:140:9:140:11 | fread output argument | test.cpp:142:31:142:33 | str indirection | +| test.cpp:142:11:142:17 | sprintf output argument | test.cpp:143:10:143:16 | command indirection | +| test.cpp:142:31:142:33 | str indirection | test.cpp:142:11:142:17 | sprintf output argument | +| test.cpp:142:31:142:33 | str indirection | test.cpp:142:11:142:17 | sprintf output argument | +nodes +| test.cpp:16:20:16:23 | argv | semmle.label | argv | +| test.cpp:22:13:22:20 | sprintf output argument | semmle.label | sprintf output argument | +| test.cpp:22:45:22:52 | userName indirection | semmle.label | userName indirection | +| test.cpp:23:12:23:19 | command1 indirection | semmle.label | command1 indirection | +| test.cpp:47:21:47:26 | call to getenv | semmle.label | call to getenv | +| test.cpp:50:11:50:17 | sprintf output argument | semmle.label | sprintf output argument | +| test.cpp:50:35:50:43 | envCflags indirection | semmle.label | envCflags indirection | +| test.cpp:51:10:51:16 | command indirection | semmle.label | command indirection | +| test.cpp:62:9:62:16 | fread output argument | semmle.label | fread output argument | +| test.cpp:64:11:64:17 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:64:20:64:27 | filename indirection | semmle.label | filename indirection | +| test.cpp:65:10:65:16 | command indirection | semmle.label | command indirection | +| test.cpp:82:9:82:16 | fread output argument | semmle.label | fread output argument | +| test.cpp:84:11:84:17 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:84:20:84:27 | filename indirection | semmle.label | filename indirection | +| test.cpp:85:32:85:38 | command indirection | semmle.label | command indirection | +| test.cpp:91:9:91:16 | fread output argument | semmle.label | fread output argument | +| test.cpp:93:11:93:14 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:93:17:93:24 | filename indirection | semmle.label | filename indirection | +| test.cpp:94:45:94:48 | path indirection | semmle.label | path indirection | +| test.cpp:106:20:106:25 | call to getenv | semmle.label | call to getenv | +| test.cpp:107:31:107:31 | call to operator+ | semmle.label | call to operator+ | +| test.cpp:107:33:107:36 | path indirection | semmle.label | path indirection | +| test.cpp:108:18:108:22 | call to c_str indirection | semmle.label | call to c_str indirection | +| test.cpp:113:20:113:25 | call to getenv | semmle.label | call to getenv | +| test.cpp:114:17:114:17 | Call | semmle.label | Call | +| test.cpp:114:19:114:22 | path indirection | semmle.label | path indirection | +| test.cpp:114:25:114:29 | call to c_str indirection | semmle.label | call to c_str indirection | +| test.cpp:119:20:119:25 | call to getenv | semmle.label | call to getenv | +| test.cpp:120:10:120:30 | call to data indirection | semmle.label | call to data indirection | +| test.cpp:120:17:120:17 | Call | semmle.label | Call | +| test.cpp:120:19:120:22 | path indirection | semmle.label | path indirection | +| test.cpp:140:9:140:11 | fread output argument | semmle.label | fread output argument | +| test.cpp:142:11:142:17 | sprintf output argument | semmle.label | sprintf output argument | +| test.cpp:142:31:142:33 | str indirection | semmle.label | str indirection | +| test.cpp:143:10:143:16 | command indirection | semmle.label | command indirection | +subpaths +#select +| test.cpp:23:12:23:19 | command1 | test.cpp:16:20:16:23 | argv | test.cpp:23:12:23:19 | command1 indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string) | test.cpp:16:20:16:23 | argv | user input (a command-line argument) | test.cpp:22:13:22:20 | sprintf output argument | sprintf output argument | +| test.cpp:51:10:51:16 | command | test.cpp:47:21:47:26 | call to getenv | test.cpp:51:10:51:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string) | test.cpp:47:21:47:26 | call to getenv | user input (an environment variable) | test.cpp:50:11:50:17 | sprintf output argument | sprintf output argument | +| test.cpp:65:10:65:16 | command | test.cpp:62:9:62:16 | fread output argument | test.cpp:65:10:65:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string) | test.cpp:62:9:62:16 | fread output argument | user input (String read by fread) | test.cpp:64:11:64:17 | strncat output argument | strncat output argument | +| test.cpp:85:32:85:38 | command | test.cpp:82:9:82:16 | fread output argument | test.cpp:85:32:85:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl | test.cpp:82:9:82:16 | fread output argument | user input (String read by fread) | test.cpp:84:11:84:17 | strncat output argument | strncat output argument | +| test.cpp:94:45:94:48 | path | test.cpp:91:9:91:16 | fread output argument | test.cpp:94:45:94:48 | path indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl | test.cpp:91:9:91:16 | fread output argument | user input (String read by fread) | test.cpp:93:11:93:14 | strncat output argument | strncat output argument | +| test.cpp:108:18:108:22 | call to c_str | test.cpp:106:20:106:25 | call to getenv | test.cpp:108:18:108:22 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string) | test.cpp:106:20:106:25 | call to getenv | user input (an environment variable) | test.cpp:107:31:107:31 | call to operator+ | call to operator+ | +| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:25 | call to getenv | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string) | test.cpp:113:20:113:25 | call to getenv | user input (an environment variable) | test.cpp:114:17:114:17 | Call | Call | +| test.cpp:120:25:120:28 | call to data | test.cpp:119:20:119:25 | call to getenv | test.cpp:120:10:120:30 | call to data indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string) | test.cpp:119:20:119:25 | call to getenv | user input (an environment variable) | test.cpp:120:17:120:17 | Call | Call | +| test.cpp:143:10:143:16 | command | test.cpp:140:9:140:11 | fread output argument | test.cpp:143:10:143:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string) | test.cpp:140:9:140:11 | fread output argument | user input (String read by fread) | test.cpp:142:11:142:17 | sprintf output argument | sprintf output argument | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.c b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.c deleted file mode 100644 index c3155787368..00000000000 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.c +++ /dev/null @@ -1,33 +0,0 @@ -// Semmle test case for rule ExecTainted.ql (Uncontrolled data used in OS command) -// Associated with CWE-078: OS Command Injection. http://cwe.mitre.org/data/definitions/78.html - -///// Library routines ///// - -int sprintf(char *s, const char *format, ...); -int system(const char *string); - -extern void encodeShellString(char *shellStr, int maxChars, const char* cStr); - -///// Test code ///// - -int main(int argc, char** argv) { - char *userName = argv[2]; - - { - // BAD: a string from the user is injected directly into - // a command. - char command1[1000] = {0}; - sprintf(command1, "userinfo -v \"%s\"", userName); - system(command1); - } - - { - // GOOD: the user string is encoded by a library routine. - char userNameQuoted[1000] = {0}; - encodeShellString(userNameQuoted, 1000, userName); - char command2[1000] = {0}; - sprintf(command2, "userinfo -v %s", userNameQuoted); - system(command2); - } -} - diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.cpp new file mode 100644 index 00000000000..8407ffb68da --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.cpp @@ -0,0 +1,174 @@ +// Semmle test case for rule ExecTainted.ql (Uncontrolled data used in OS command) +// Associated with CWE-078: OS Command Injection. http://cwe.mitre.org/data/definitions/78.html + +///// Library routines ///// + +int sprintf(char *s, const char *format, ...); +int system(const char *string); + +char *getenv(char *var); + +extern void encodeShellString(char *shellStr, int maxChars, const char* cStr); +#include "../../../../../../include/string.h" +///// Test code ///// + +int main(int argc, char** argv) { + char *userName = argv[2]; + + { + // BAD: a string from the user is injected directly into + // a command. + char command1[1000] = {0}; + sprintf(command1, "userinfo -v \"%s\"", userName); + system(command1); + } + + { + // GOOD: the user string is encoded by a library routine. + char userNameQuoted[1000] = {0}; + encodeShellString(userNameQuoted, 1000, userName); + char command2[1000] = {0}; + sprintf(command2, "userinfo -v %s", userNameQuoted); + system(command2); + } +} + +void test2(char* arg2) { + // GOOD?: the user string is the *first* part of the command, like $CC in many environments + char *envCC = getenv("CC"); + + char command[1000]; + sprintf("%s %s", envCC, arg2); + system(command); +} + +void test3(char* arg1) { + // GOOD?: the user string is a `$CFLAGS` environment variable + char *envCflags = getenv("CFLAGS"); + + char command[1000]; + sprintf(command, "%s %s", arg1, envCflags); + system(command); +} + +typedef unsigned long size_t; +typedef void FILE; +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); +char *strncat(char *s1, const char *s2, size_t n); + +void test4(FILE *f) { + // BAD: the user string is injected directly into a command + char command[1000] = "mv ", filename[1000]; + fread(filename, 1, 1000, f); + + strncat(command, filename, 1000); + system(command); +} + +void test5(FILE *f) { + // GOOD?: the user string is the start of a command + char command[1000], filename[1000] = " test.txt"; + fread(command, 1, 1000, f); + + strncat(command, filename, 1000); + system(command); +} + +int execl(char *path, char *arg1, ...); + +void test6(FILE *f) { + // BAD: the user string is injected directly into a command + char command[1000] = "mv ", filename[1000]; + fread(filename, 1, 1000, f); + + strncat(command, filename, 1000); + execl("/bin/sh", "sh", "-c", command); +} + +void test7(FILE *f) { + // GOOD [FALSE POSITIVE]: the user string is a positional argument to a shell script + char path[1000] = "/home/me/", filename[1000]; + fread(filename, 1, 1000, f); + + strncat(path, filename, 1000); + execl("/bin/sh", "sh", "-c", "script.sh", path); +} + +void test8(char *arg2) { + // GOOD?: the user string is the *first* part of the command, like $CC in many environments + std::string envCC(getenv("CC")); + std::string command = envCC + arg2; + system(command.c_str()); +} + +void test9(FILE *f) { + // BAD: the user string is injected directly into a command + std::string path(getenv("something")); + std::string command = "mv " + path; + system(command.c_str()); +} + +void test10(FILE *f) { + // BAD: the user string is injected directly into a command + std::string path(getenv("something")); + system(("mv " + path).c_str()); +} + +void test11(FILE *f) { + // BAD: the user string is injected directly into a command + std::string path(getenv("something")); + system(("mv " + path).data()); +} + +int atoi(char *); + +void test12(FILE *f) { + char temp[10]; + char command[1000]; + + fread(temp, 1, 10, f); + + int x = atoi(temp); + sprintf(command, "tail -n %d foo.log", x); + system(command); // GOOD: the user string was converted to an integer and back +} + +void test13(FILE *f) { + char str[1000]; + char command[1000]; + + fread(str, 1, 1000, f); + + sprintf(command, "echo %s", str); + system(command); // BAD: the user string was printed into the command with the %s specifier +} + +void test14(FILE *f) { + char str[1000]; + char command[1000]; + + fread(str, 1, 1000, f); + + sprintf(command, "echo %p", str); + system(command); // GOOD: the user string's address was printed into the command with the %p specifier +} + +void test15(FILE *f) { + char temp[10]; + char command[1000]; + + fread(temp, 1, 10, f); + + int x = atoi(temp); + + char temp2[10]; + sprintf(temp2, "%d", x); + sprintf(command, "tail -n %s foo.log", temp2); + + system(command); // GOOD: the user string was converted to an integer and back +} + + +// TODO: test for call context sensitivity at concatenation site + +// open question: do we want to report certain sources even when they're the start of the string? diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-079/semmle/CgiXss/CgiXss.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-079/semmle/CgiXss/CgiXss.expected index d9fa0d7029f..ebf051ddd0b 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-079/semmle/CgiXss/CgiXss.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-079/semmle/CgiXss/CgiXss.expected @@ -24,6 +24,7 @@ edges | search.c:55:17:55:25 | raw_query indirection | search.c:14:24:14:28 | *query | | search.c:57:5:57:15 | raw_query | search.c:22:24:22:28 | query | | search.c:57:17:57:25 | raw_query indirection | search.c:22:24:22:28 | *query | +subpaths nodes | search.c:14:24:14:28 | *query | semmle.label | *query | | search.c:14:24:14:28 | query | semmle.label | query | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/SqlTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/SqlTainted.expected index e267dd48bba..2b572375ce9 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/SqlTainted.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/SqlTainted.expected @@ -5,6 +5,15 @@ edges | test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 | | test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 indirection | | test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 indirection | +| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | (const char *)... | +| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | (const char *)... | +| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array | +| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array | +| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array | +| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array | +| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array indirection | +| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array indirection | +subpaths nodes | test.c:15:20:15:23 | argv | semmle.label | argv | | test.c:15:20:15:23 | argv | semmle.label | argv | @@ -13,5 +22,15 @@ nodes | test.c:21:18:21:23 | query1 | semmle.label | query1 | | test.c:21:18:21:23 | query1 indirection | semmle.label | query1 indirection | | test.c:21:18:21:23 | query1 indirection | semmle.label | query1 indirection | +| test.cpp:43:27:43:30 | argv | semmle.label | argv | +| test.cpp:43:27:43:30 | argv | semmle.label | argv | +| test.cpp:43:27:43:33 | (const char *)... | semmle.label | (const char *)... | +| test.cpp:43:27:43:33 | (const char *)... | semmle.label | (const char *)... | +| test.cpp:43:27:43:33 | access to array | semmle.label | access to array | +| test.cpp:43:27:43:33 | access to array | semmle.label | access to array | +| test.cpp:43:27:43:33 | access to array | semmle.label | access to array | +| test.cpp:43:27:43:33 | access to array indirection | semmle.label | access to array indirection | +| test.cpp:43:27:43:33 | access to array indirection | semmle.label | access to array indirection | #select | test.c:21:18:21:23 | query1 | test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg) | test.c:15:20:15:23 | argv | user input (argv) | +| test.cpp:43:27:43:33 | access to array | test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array | This argument to a SQL query function is derived from $@ and then passed to pqxx::work::exec1((unnamed parameter 0)) | test.cpp:43:27:43:30 | argv | user input (argv) | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/test.cpp new file mode 100644 index 00000000000..8bdf7dded23 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/test.cpp @@ -0,0 +1,48 @@ +int sprintf(char* str, const char* format, ...); + +namespace std +{ + template struct char_traits; + + template class allocator { + public: + allocator() throw(); + }; + + template, class Allocator = allocator > + class basic_string { + public: + explicit basic_string(const Allocator& a = Allocator()); + basic_string(const charT* s, const Allocator& a = Allocator()); + + const charT* c_str() const; + }; + + typedef basic_string string; +} + +namespace pqxx { + struct connection {}; + + struct row {}; + struct result {}; + + struct work { + work(connection&); + + row exec1(const char*); + result exec(const std::string&); + std::string quote(const char*); + }; +} + +int main(int argc, char** argv) { + pqxx::connection c; + pqxx::work w(c); + + pqxx::row r = w.exec1(argv[1]); // BAD + + pqxx::result r2 = w.exec(w.quote(argv[1])); // GOOD + + return 0; +} \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-114/SAMATE/UncontrolledProcessOperation/UncontrolledProcessOperation.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-114/SAMATE/UncontrolledProcessOperation/UncontrolledProcessOperation.expected new file mode 100644 index 00000000000..11cca0cf50b --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-114/SAMATE/UncontrolledProcessOperation/UncontrolledProcessOperation.expected @@ -0,0 +1,31 @@ +edges +| test.cpp:37:73:37:76 | *data | test.cpp:43:32:43:35 | (LPCSTR)... | +| test.cpp:37:73:37:76 | *data | test.cpp:43:32:43:35 | data | +| test.cpp:37:73:37:76 | *data | test.cpp:43:32:43:35 | data indirection | +| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | (LPCSTR)... | +| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | data | +| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | data | +| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | data indirection | +| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:17:73:22 | data | +| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:17:73:22 | data | +| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data indirection | +| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data indirection | +| test.cpp:73:17:73:22 | data | test.cpp:37:73:37:76 | data | +| test.cpp:73:24:73:27 | data indirection | test.cpp:37:73:37:76 | *data | +subpaths +nodes +| test.cpp:37:73:37:76 | *data | semmle.label | *data | +| test.cpp:37:73:37:76 | data | semmle.label | data | +| test.cpp:43:32:43:35 | (LPCSTR)... | semmle.label | (LPCSTR)... | +| test.cpp:43:32:43:35 | (LPCSTR)... | semmle.label | (LPCSTR)... | +| test.cpp:43:32:43:35 | data | semmle.label | data | +| test.cpp:43:32:43:35 | data | semmle.label | data | +| test.cpp:43:32:43:35 | data | semmle.label | data | +| test.cpp:43:32:43:35 | data indirection | semmle.label | data indirection | +| test.cpp:43:32:43:35 | data indirection | semmle.label | data indirection | +| test.cpp:64:30:64:35 | call to getenv | semmle.label | call to getenv | +| test.cpp:64:30:64:35 | call to getenv | semmle.label | call to getenv | +| test.cpp:73:17:73:22 | data | semmle.label | data | +| test.cpp:73:24:73:27 | data indirection | semmle.label | data indirection | +#select +| test.cpp:43:32:43:35 | data | test.cpp:64:30:64:35 | call to getenv | test.cpp:43:32:43:35 | data | The value of this argument may come from $@ and is being passed to LoadLibraryA | test.cpp:64:30:64:35 | call to getenv | call to getenv | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-114/SAMATE/UncontrolledProcessOperation/UncontrolledProcessOperation.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-114/SAMATE/UncontrolledProcessOperation/UncontrolledProcessOperation.qlref new file mode 100644 index 00000000000..a9ca1db5199 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-114/SAMATE/UncontrolledProcessOperation/UncontrolledProcessOperation.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-114/UncontrolledProcessOperation.ql diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-114/SAMATE/UncontrolledProcessOperation/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-114/SAMATE/UncontrolledProcessOperation/test.cpp new file mode 100644 index 00000000000..299e0372d4a --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-114/SAMATE/UncontrolledProcessOperation/test.cpp @@ -0,0 +1,132 @@ +// Some SAMATE Juliet test cases for CWE-114. + +typedef unsigned long size_t; +typedef unsigned int BOOL; +typedef const char *LPCSTR; +typedef void *HMODULE; +#define NULL (0) + +size_t strlen(const char *s); +char *strncat(char *s1, const char *s2, size_t n); + +HMODULE LoadLibraryA(LPCSTR libname); +BOOL FreeLibrary(HMODULE hModule); + +char *getenv(const char *name); + +#define GETENV getenv +#define ENV_VARIABLE "ADD" + +void printLine(const char *msg); + +// --- CWE114_Process_Control__w32_char_environment_82 --- + +class CWE114_Process_Control__w32_char_environment_82_base +{ +public: + /* pure virtual function */ + virtual void action(char * data) = 0; +}; + +class CWE114_Process_Control__w32_char_environment_82_bad : public CWE114_Process_Control__w32_char_environment_82_base +{ +public: + void action(char * data); +}; + +void CWE114_Process_Control__w32_char_environment_82_bad::action(char * data) +{ + { + HMODULE hModule; + /* POTENTIAL FLAW: If the path to the library is not specified, an attacker may be able to + * replace his own file with the intended library */ + hModule = LoadLibraryA(data); + if (hModule != NULL) + { + FreeLibrary(hModule); + printLine("Library loaded and freed successfully"); + } + else + { + printLine("Unable to load library"); + } + } +} + +void bad() +{ + char * data; + char dataBuffer[100] = ""; + data = dataBuffer; + { + /* Append input from an environment variable to data */ + size_t dataLen = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+dataLen, environment, 100-dataLen-1); + } + } + CWE114_Process_Control__w32_char_environment_82_base* baseObject = new CWE114_Process_Control__w32_char_environment_82_bad; + baseObject->action(data); + delete baseObject; +} + +// --- CWE114_Process_Control__w32_char_console_33 --- + +typedef struct {} FILE; +char *fgets(char *s, int n, FILE *stream); +FILE *stdin; + +void CWE114_Process_Control__w32_char_console_33_bad() +{ + char * data; + char * &dataRef = data; + char dataBuffer[100] = ""; + data = dataBuffer; + { + /* Read input from the console */ + size_t dataLen = strlen(data); + /* if there is room in data, read into it from the console */ + if (100-dataLen > 1) + { + /* POTENTIAL FLAW: Read data from the console [NOT DETECTED] */ + if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL) + { + /* The next few lines remove the carriage return from the string that is + * inserted by fgets() */ + dataLen = strlen(data); + if (dataLen > 0 && data[dataLen-1] == '\n') + { + data[dataLen-1] = '\0'; + } + } + else + { + printLine("fgets() failed"); + /* Restore NUL terminator if fgets fails */ + data[dataLen] = '\0'; + } + } + } + { + char * data = dataRef; + { + HMODULE hModule; + /* POTENTIAL FLAW: If the path to the library is not specified, an attacker may be able to + * replace his own file with the intended library */ + hModule = LoadLibraryA(data); + if (hModule != NULL) + { + FreeLibrary(hModule); + printLine("Library loaded and freed successfully"); + } + else + { + printLine("Unable to load library"); + } + } + } +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-114/semmle/UncontrolledProcessOperation/UncontrolledProcessOperation.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-114/semmle/UncontrolledProcessOperation/UncontrolledProcessOperation.expected index c610e346bb1..b9a0f7b3631 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-114/semmle/UncontrolledProcessOperation/UncontrolledProcessOperation.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-114/semmle/UncontrolledProcessOperation/UncontrolledProcessOperation.expected @@ -47,6 +47,7 @@ edges | test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | (const char *)... | | test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer | | test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer indirection | +subpaths nodes | test.cpp:24:30:24:36 | *command | semmle.label | *command | | test.cpp:24:30:24:36 | command | semmle.label | command | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/BadlyBoundedWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/BadlyBoundedWrite.expected new file mode 100644 index 00000000000..bd60a176ca9 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/BadlyBoundedWrite.expected @@ -0,0 +1,4 @@ +| tests.cpp:350:13:350:19 | call to strncat | This 'call to strncat' operation is limited to 100 bytes but the destination is only 50 bytes. | +| tests.cpp:452:9:452:15 | call to wcsncpy | This 'call to wcsncpy' operation is limited to 396 bytes but the destination is only 200 bytes. | +| tests.cpp:481:9:481:16 | call to swprintf | This 'call to swprintf' operation is limited to 400 bytes but the destination is only 200 bytes. | +| tests.cpp:630:13:630:20 | call to swprintf | This 'call to swprintf' operation is limited to 400 bytes but the destination is only 200 bytes. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/BadlyBoundedWrite.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/BadlyBoundedWrite.qlref new file mode 100644 index 00000000000..9636c74d0a8 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/BadlyBoundedWrite.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-120/BadlyBoundedWrite.ql \ No newline at end of file diff --git a/java/ql/test/library-tests/frameworks/guava/flow.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OffsetUseBeforeRangeCheck.expected similarity index 100% rename from java/ql/test/library-tests/frameworks/guava/flow.expected rename to cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OffsetUseBeforeRangeCheck.expected diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OffsetUseBeforeRangeCheck.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OffsetUseBeforeRangeCheck.qlref new file mode 100644 index 00000000000..d934901f174 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OffsetUseBeforeRangeCheck.qlref @@ -0,0 +1 @@ +Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowBuffer.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowBuffer.expected new file mode 100644 index 00000000000..73f1b74db56 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowBuffer.expected @@ -0,0 +1,19 @@ +| tests.cpp:45:9:45:14 | call to memcpy | This 'memcpy' operation accesses 32 bytes but the $@ is only 16 bytes. | tests.cpp:32:10:32:18 | charFirst | destination buffer | +| tests.cpp:60:9:60:14 | call to memcpy | This 'memcpy' operation accesses 32 bytes but the $@ is only 16 bytes. | tests.cpp:32:10:32:18 | charFirst | destination buffer | +| tests.cpp:171:9:171:14 | call to memcpy | This 'memcpy' operation accesses 100 bytes but the $@ is only 50 bytes. | tests.cpp:164:20:164:25 | call to malloc | destination buffer | +| tests.cpp:172:9:172:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:164:20:164:25 | call to malloc | array | +| tests.cpp:192:9:192:14 | call to memcpy | This 'memcpy' operation accesses 100 bytes but the $@ is only 50 bytes. | tests.cpp:181:10:181:22 | dataBadBuffer | destination buffer | +| tests.cpp:192:9:192:14 | call to memcpy | This 'memcpy' operation accesses 100 bytes but the $@ is only 50 bytes. | tests.cpp:185:12:185:24 | dataBadBuffer | destination buffer | +| tests.cpp:193:9:193:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:181:10:181:22 | dataBadBuffer | array | +| tests.cpp:193:9:193:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:185:12:185:24 | dataBadBuffer | array | +| tests.cpp:212:9:212:14 | call to memcpy | This 'memcpy' operation accesses 100 bytes but the $@ is only 50 bytes. | tests.cpp:201:36:201:41 | call to alloca | destination buffer | +| tests.cpp:212:9:212:14 | call to memcpy | This 'memcpy' operation accesses 100 bytes but the $@ is only 50 bytes. | tests.cpp:205:12:205:24 | dataBadBuffer | destination buffer | +| tests.cpp:213:9:213:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:201:36:201:41 | call to alloca | array | +| tests.cpp:213:9:213:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:205:12:205:24 | dataBadBuffer | array | +| tests.cpp:237:9:237:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:221:36:221:41 | call to alloca | array | +| tests.cpp:237:9:237:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:225:12:225:24 | dataBadBuffer | array | +| tests.cpp:261:9:261:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:245:10:245:22 | dataBadBuffer | array | +| tests.cpp:261:9:261:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:249:12:249:24 | dataBadBuffer | array | +| tests.cpp:384:9:384:14 | call to memcpy | This 'memcpy' operation accesses 40 bytes but the $@ is only 10 bytes. | tests.cpp:380:19:380:24 | call to alloca | destination buffer | +| tests.cpp:434:9:434:19 | access to array | This array indexing operation accesses byte offset 399 but the $@ is only 200 bytes. | tests.cpp:422:12:422:26 | new[] | array | +| tests.cpp:453:9:453:19 | access to array | This array indexing operation accesses byte offset 399 but the $@ is only 200 bytes. | tests.cpp:445:12:445:26 | new[] | array | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowBuffer.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowBuffer.qlref new file mode 100644 index 00000000000..5c2bacec579 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowBuffer.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-119/OverflowBuffer.ql \ No newline at end of file diff --git a/python/ql/test/experimental/library-tests/frameworks/sqlalchemy/ConceptsTest.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowDestination.expected similarity index 100% rename from python/ql/test/experimental/library-tests/frameworks/sqlalchemy/ConceptsTest.expected rename to cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowDestination.expected diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowDestination.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowDestination.qlref new file mode 100644 index 00000000000..a4213e22fcd --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowDestination.qlref @@ -0,0 +1 @@ +Critical/OverflowDestination.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowStatic.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowStatic.expected new file mode 100644 index 00000000000..ab9263b8544 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowStatic.expected @@ -0,0 +1,2 @@ +| tests.cpp:45:51:45:72 | sizeof() | Potential buffer-overflow: 'charFirst' has size 16 not 32. | +| tests.cpp:60:52:60:74 | sizeof() | Potential buffer-overflow: 'charFirst' has size 16 not 32. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowStatic.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowStatic.qlref new file mode 100644 index 00000000000..9ff1c3b33dc --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverflowStatic.qlref @@ -0,0 +1 @@ +Critical/OverflowStatic.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWrite.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWrite.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWrite.qlref new file mode 100644 index 00000000000..f6c962c1a7b --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWrite.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-120/OverrunWrite.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteFloat.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteFloat.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteFloat.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteFloat.qlref new file mode 100644 index 00000000000..757d1592e83 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteFloat.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-120/OverrunWriteFloat.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/StrncpyFlippedArgs.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/StrncpyFlippedArgs.expected new file mode 100644 index 00000000000..778adb97718 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/StrncpyFlippedArgs.expected @@ -0,0 +1,3 @@ +| tests.cpp:290:13:290:19 | call to wcsncpy | Potentially unsafe call to wcsncpy; third argument should be size of destination. | +| tests.cpp:306:4:306:10 | call to wcsncpy | Potentially unsafe call to wcsncpy; third argument should be size of destination. | +| tests.cpp:452:9:452:15 | call to wcsncpy | Potentially unsafe call to wcsncpy; third argument should be size of destination. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/StrncpyFlippedArgs.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/StrncpyFlippedArgs.qlref new file mode 100644 index 00000000000..bf0bf1ea7d0 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/StrncpyFlippedArgs.qlref @@ -0,0 +1 @@ +Likely Bugs/Memory Management/StrncpyFlippedArgs.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/UnboundedWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/UnboundedWrite.expected new file mode 100644 index 00000000000..7cefb7cfafc --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/UnboundedWrite.expected @@ -0,0 +1,4 @@ +edges +subpaths +nodes +#select diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/UnboundedWrite.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/UnboundedWrite.qlref new file mode 100644 index 00000000000..767f2ea4db9 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/UnboundedWrite.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-120/UnboundedWrite.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/tests.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/tests.cpp new file mode 100644 index 00000000000..1c7f9ad60f5 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/tests.cpp @@ -0,0 +1,671 @@ +// A sample of tests from the SAMATE Juliet framework for rule CWE-119. + +// library types, functions etc +typedef unsigned long size_t; +void *malloc(size_t size); +void *alloca(size_t size); +void free(void *ptr); +#define ALLOCA alloca + +void *memcpy(void *s1, const void *s2, size_t n); +void *memset(void *s, int c, size_t n); +char *strcpy(char *s1, const char *s2); +size_t strlen(const char *s); + +void exit(int status); + +typedef unsigned int DWORD; +DWORD GetCurrentDirectoryA(DWORD bufferLength, char *buffer); +bool PathAppendA(char *path, const char *more); +#define MAX_PATH 4096 + +void printLine(const char *str); +void printSizeTLine(size_t val); +void printIntLine(int val); + +// ---------- + +#define SRC_STR "0123456789abcde0123" + +typedef struct _charVoid +{ + char charFirst[16]; + void * voidSecond; + void * voidThird; +} charVoid; + +void CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memcpy_01_bad() +{ + { + charVoid structCharVoid; + structCharVoid.voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid.voidSecond */ + printLine((char *)structCharVoid.voidSecond); + /* FLAW: Use the sizeof(structCharVoid) which will overwrite the pointer voidSecond */ + memcpy(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid)); + structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid.charFirst); + printLine((char *)structCharVoid.voidSecond); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memcpy_01_bad() +{ + { + charVoid * structCharVoid = (charVoid *)malloc(sizeof(charVoid)); + structCharVoid->voidSecond = (void *)SRC_STR; + /* Print the initial block pointed to by structCharVoid->voidSecond */ + printLine((char *)structCharVoid->voidSecond); + /* FLAW: Use the sizeof(*structCharVoid) which will overwrite the pointer y */ + memcpy(structCharVoid->charFirst, SRC_STR, sizeof(*structCharVoid)); + structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */ + printLine((char *)structCharVoid->charFirst); + printLine((char *)structCharVoid->voidSecond); + free(structCharVoid); + } +} + +void CWE124_Buffer_Underwrite__char_alloca_cpy_01_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + memset(dataBuffer, 'A', 100-1); + dataBuffer[100-1] = '\0'; + /* FLAW: Set data pointer to before the allocated memory buffer */ + data = dataBuffer - 8; + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possibly copying data to memory before the destination buffer */ + strcpy(data, source); // [NOT DETECTED] + printLine(data); + } +} + +void CWE126_Buffer_Overread__char_alloca_loop_01_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + memset(dataBadBuffer, 'A', 50-1); /* fill with 'A's */ + dataBadBuffer[50-1] = '\0'; /* null terminate */ + memset(dataGoodBuffer, 'A', 100-1); /* fill with 'A's */ + dataGoodBuffer[100-1] = '\0'; /* null terminate */ + /* FLAW: Set data pointer to a small buffer */ + data = dataBadBuffer; + { + size_t i, destLen; + char dest[100]; + memset(dest, 'C', 100-1); + dest[100-1] = '\0'; /* null terminate */ + destLen = strlen(dest); + /* POTENTIAL FLAW: using length of the dest where data + * could be smaller than dest causing buffer overread */ + for (i = 0; i < destLen; i++) + { + dest[i] = data[i]; // [NOT DETECTED] + } + dest[100-1] = '\0'; + printLine(dest); + } +} + +void CWE127_Buffer_Underread__char_alloca_cpy_01_bad() +{ + char * data; + char * dataBuffer = (char *)ALLOCA(100*sizeof(char)); + memset(dataBuffer, 'A', 100-1); + dataBuffer[100-1] = '\0'; + /* FLAW: Set data pointer to before the allocated memory buffer */ + data = dataBuffer - 8; + { + char dest[100*2]; + memset(dest, 'C', 100*2-1); /* fill with 'C's */ + dest[100*2-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possibly copy from a memory location located before the source buffer */ + strcpy(dest, data); // [NOT DETECTED] + printLine(dest); + } +} + +#define BAD_PATH_SIZE (MAX_PATH / 2) /* maintenance note: must be < MAX_PATH in order for 'bad' to be 'bad' */ + +void CWE785_Path_Manipulation_Function_Without_Max_Sized_Buffer__w32_01_bad() +{ + { + char path[BAD_PATH_SIZE]; + DWORD length; + length = GetCurrentDirectoryA(BAD_PATH_SIZE, path); + if (length == 0 || length >= BAD_PATH_SIZE) /* failure conditions for this API call */ + { + exit(1); + } + /* FLAW: PathAppend assumes the 'path' parameter is MAX_PATH */ + /* INCIDENTAL: CWE 121 stack based buffer overflow, which is intrinsic to + * this example identified on the CWE webpage */ + if (!PathAppendA(path, "AAAAAAAAAAAA")) // [NOT DETECTED] + { + exit(1); + } + printSizeTLine(strlen(path)); + printIntLine(BAD_PATH_SIZE); + printLine(path); + } +} + +#define NULL (0) + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_memcpy_01_bad() +{ + char * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + data[0] = '\0'; /* null terminate */ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + free(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_memcpy_01_bad() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FLAW: Set a pointer to a "small" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a "large" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_memcpy_01_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FLAW: Set a pointer to a "small" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a "large" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + memcpy(data, source, 100*sizeof(char)); + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_alloca_loop_01_bad() +{ + char * data; + char * dataBadBuffer = (char *)ALLOCA(50*sizeof(char)); + char * dataGoodBuffer = (char *)ALLOCA(100*sizeof(char)); + /* FLAW: Set a pointer to a "small" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a "large" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE805_char_declare_loop_01_bad() +{ + char * data; + char dataBadBuffer[50]; + char dataGoodBuffer[100]; + /* FLAW: Set a pointer to a "small" buffer. This buffer will be used in the sinks as a destination + * buffer in various memory copying functions using a "large" source buffer. */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + { + size_t i; + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if the size of data is less than the length of source */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = '\0'; /* Ensure the destination buffer is null terminated */ + printLine(data); + } +} + +wchar_t *wcsncpy(wchar_t *destination, const wchar_t *source, size_t num); +size_t wcslen(const wchar_t *str); +char *strcat(char *destination, const char *source); +char *strncat(char *destination, const char *source, size_t num); + +void *memmove(void *destination, const void *source, size_t num); + +void printWLine(const wchar_t *line); + +/* MAINTENANCE NOTE: The length of this string should equal the 10 */ +#define SRC_STRING L"AAAAAAAAAA" + +namespace CWE122_Heap_Based_Buffer_Overflow__cpp_CWE193_wchar_t_ncpy_01 +{ + void bad() + { + wchar_t * data; + data = NULL; + /* FLAW: Did not leave space for a null terminator */ + data = new wchar_t[10]; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); + printWLine(data); + delete [] data; + } + } + + static void goodG2B() + { + wchar_t * data; + data = NULL; + /* FIX: Allocate space for a null terminator */ + data = new wchar_t[10+1]; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + wcsncpy(data, source, wcslen(source) + 1); // [FALSE POSITIVE RESULT] (debatable) + printWLine(data); + delete [] data; + } + } +} /* close namespace */ + +namespace CWE122_Heap_Based_Buffer_Overflow__cpp_CWE193_wchar_t_memmove_31 +{ + void bad() + { + wchar_t * data; + data = NULL; + /* FLAW: Did not leave space for a null terminator */ + data = new wchar_t[10]; + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t source[10+1] = SRC_STRING; + /* Copy length + 1 to include NUL terminator from source */ + /* POTENTIAL FLAW: data may not have enough space to hold source */ + memmove(data, source, (wcslen(source) + 1) * sizeof(wchar_t)); // [NOT DETECTED] + printWLine(data); + delete [] data; + } + } + } +} /* close namespace */ + +namespace CWE122_Heap_Based_Buffer_Overflow__cpp_CWE805_char_ncat_01 +{ + void bad() + { + char * data; + data = NULL; + /* FLAW: Allocate using new[] and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = new char[50]; + data[0] = '\0'; /* null terminate */ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strncat(data, source, 100); + printLine(data); + delete [] data; + } + } +} /* close namespace */ + +void CWE122_Heap_Based_Buffer_Overflow__c_dest_char_cat_01_bad() +{ + char * data; + data = NULL; + /* FLAW: Allocate and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = (char *)malloc(50*sizeof(char)); + data[0] = '\0'; /* null terminate */ + { + char source[100]; + memset(source, 'C', 100-1); /* fill with 'C's */ + source[100-1] = '\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than sizeof(data)-strlen(data) */ + strcat(data, source); // [NOT DETECTED] + printLine(data); + free(data); + } +} + +void CWE121_Stack_Based_Buffer_Overflow__CWE131_memcpy_01_bad() +{ + int * data; + data = NULL; + /* FLAW: Allocate memory without using sizeof(int) */ + data = (int *)ALLOCA(10); + { + int source[10] = {0}; + /* POTENTIAL FLAW: Possible buffer overflow if data was not allocated correctly in the source */ + memcpy(data, source, 10*sizeof(int)); + printIntLine(data[0]); + } +} + +typedef long long int64_t; +wchar_t *wmemset(wchar_t *dest, wchar_t c, size_t count); +void* calloc(size_t num, size_t size); + +void printLongLongLine(int64_t longLongIntNumber); +void printDoubleLine(double doubleNumber); + +void CWE122_Heap_Based_Buffer_Overflow__cpp_CWE805_int64_t_loop_01_bad() +{ + int64_t * data; + data = NULL; + /* FLAW: Allocate using new[] and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = new int64_t[50]; + { + int64_t source[100] = {0}; /* fill with 0's */ + { + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; // [NOT DETECTED] + } + printLongLongLine(data[0]); + delete [] data; + } + } +} + +void CWE122_Heap_Based_Buffer_Overflow__cpp_CWE805_wchar_t_loop_01_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Allocate using new[] and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = new wchar_t[50]; + data[0] = L'\0'; /* null terminate */ + { + size_t i; + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + for (i = 0; i < 100; i++) + { + data[i] = source[i]; + } + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + delete [] data; + } +} + +void CWE122_Heap_Based_Buffer_Overflow__cpp_CWE805_wchar_t_ncpy_01_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Allocate using new[] and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = new wchar_t[50]; + data[0] = L'\0'; /* null terminate */ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + wcsncpy(data, source, 100-1); + data[100-1] = L'\0'; /* Ensure the destination buffer is null terminated */ + printWLine(data); + delete [] data; + } +} + +#ifdef _WIN32 +int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format, ...); +#define SNPRINTF _snwprintf +#else +int snprintf(char *s, size_t n, const char *format, ...); +int swprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, ...); +//#define SNPRINTF snprintf --- original code; using snprintf appears to be a mistake in samate? +#define SNPRINTF swprintf +#endif + +void CWE122_Heap_Based_Buffer_Overflow__cpp_CWE805_wchar_t_snprintf_01_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Allocate using new[] and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = new wchar_t[50]; + data[0] = L'\0'; /* null terminate */ + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L"%s", source); + printWLine(data); + delete [] data; + } +} + +/* classes used in some test cases as a custom type */ +class TwoIntsClass +{ + public: // Needed to access variables from label files + int intOne; + int intTwo; +}; + +class OneIntClass +{ + public: // Needed to access variables from label files + int intOne; +}; + +void *operator new(size_t size, void *ptr) throw(); // placement new (from #include ) + +void CWE122_Heap_Based_Buffer_Overflow__placement_new_01_bad() +{ + char * data; + char * dataBadBuffer = (char *)malloc(sizeof(OneIntClass)); + char * dataGoodBuffer = (char *)malloc(sizeof(TwoIntsClass)); + /* POTENTIAL FLAW: Initialize data to a buffer small than the sizeof(TwoIntsClass) */ + data = dataBadBuffer; + { + /* The Visual C++ compiler generates a warning if you initialize the class with (). + * This will cause the compile to default-initialize the object. + * See http://msdn.microsoft.com/en-us/library/wewb47ee%28v=VS.100%29.aspx + */ + /* POTENTIAL FLAW: data may not be large enough to hold a TwoIntsClass */ + TwoIntsClass * classTwo = new(data) TwoIntsClass; // [NOT DETECTED] + /* Initialize and make use of the class */ + classTwo->intOne = 5; + classTwo->intTwo = 10; /* POTENTIAL FLAW: If sizeof(data) < sizeof(TwoIntsClass) then this line will be a buffer overflow */ + printIntLine(classTwo->intOne); + /* skip printing classTwo->intTwo since that could be a buffer overread */ + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__sizeof_double_01_bad() +{ + double * data; + /* Initialize data */ + data = NULL; + /* INCIDENTAL: CWE-467 (Use of sizeof() on a pointer type) */ + /* FLAW: Using sizeof the pointer and not the data type in malloc() */ + data = (double *)malloc(sizeof(data)); // [NOT DETECTED] + *data = 1.7E300; + /* POTENTIAL FLAW: Attempt to use data, which may not have enough memory allocated */ + printDoubleLine(*data); + free(data); +} + +int rand(void); +#define RAND32() ((rand()<<30) ^ (rand()<<15) ^ rand()) + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_rand_01_bad() +{ + int data; + /* Initialize data */ + data = -1; + /* POTENTIAL FLAW: Set data to a random value */ + data = RAND32(); + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; // [NOT DETECTED] + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine("ERROR: Array index is negative."); + } + free(buffer); + } +} + +typedef struct FILE; +int fscanf(FILE *stream, const char *format, ...); +FILE *stdin; + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fscanf_01_bad() +{ + int data; + /* Initialize data */ + data = -1; + /* POTENTIAL FLAW: Read data from the console using fscanf() */ + fscanf(stdin, "%d", &data); + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; // [NOT DETECTED] + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine("ERROR: Array index is negative."); + } + free(buffer); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__cpp_CWE805_wchar_t_snprintf_31_bad() +{ + wchar_t * data; + data = NULL; + /* FLAW: Allocate using new[] and point data to a small buffer that is smaller than the large buffer used in the sinks */ + data = new wchar_t[50]; + data[0] = L'\0'; /* null terminate */ + { + wchar_t * dataCopy = data; + wchar_t * data = dataCopy; + { + wchar_t source[100]; + wmemset(source, L'C', 100-1); /* fill with L'C's */ + source[100-1] = L'\0'; /* null terminate */ + /* POTENTIAL FLAW: Possible buffer overflow if source is larger than data */ + SNPRINTF(data, 100, L"%s", source); + printWLine(data); + delete [] data; + } + } +} + +int rand(void); + +int globalReturnsTrueOrFalse() +{ + return (rand() % 2); +} + +#define SRC_STRING "AAAAAAAAAA" + +void CWE121_Stack_Based_Buffer_Overflow__CWE193_char_declare_cpy_12_bad() +{ + char * data; + char dataBadBuffer[10]; + char dataGoodBuffer[10+1]; + if(globalReturnsTrueOrFalse()) + { + /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing + * string copies in the sinks */ + data = dataBadBuffer; + data[0] = '\0'; /* null terminate */ + } + else + { + /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing + * string copies in the sinks */ + data = dataGoodBuffer; + data[0] = '\0'; /* null terminate */ + } + { + char source[10+1] = SRC_STRING; + /* POTENTIAL FLAW: data may not have enough space to hold source */ // [NOT DETECTED] + strcpy(data, source); + printLine(data); + } +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowBuffer.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowBuffer.expected index 614716b470d..795d83587c3 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowBuffer.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowBuffer.expected @@ -72,12 +72,9 @@ | unions.cpp:30:2:30:7 | call to memset | This 'memset' operation accesses 200 bytes but the $@ is only 100 bytes. | unions.cpp:15:7:15:11 | small | destination buffer | | unions.cpp:34:2:34:7 | call to memset | This 'memset' operation accesses 200 bytes but the $@ is only 100 bytes. | unions.cpp:16:7:16:11 | large | destination buffer | | unions.cpp:34:2:34:7 | call to memset | This 'memset' operation accesses 200 bytes but the $@ is only 100 bytes. | unions.cpp:34:14:34:18 | large | destination buffer | -| var_size_struct.cpp:54:5:54:14 | access to array | This array indexing operation accesses byte offset 1 but the $@ is only 1 byte. | var_size_struct.cpp:32:8:32:10 | str | array | -| var_size_struct.cpp:55:5:55:14 | access to array | This array indexing operation accesses byte offset 1 but the $@ is only 1 byte. | var_size_struct.cpp:38:8:38:10 | str | array | | var_size_struct.cpp:71:3:71:8 | call to memset | This 'memset' operation accesses 1025 bytes but the $@ is only 1024 bytes. | var_size_struct.cpp:63:8:63:11 | data | destination buffer | | var_size_struct.cpp:73:3:73:9 | call to strncpy | This 'strncpy' operation may access 1025 bytes but the $@ is only 1024 bytes. | var_size_struct.cpp:63:8:63:11 | data | destination buffer | | var_size_struct.cpp:87:3:87:19 | access to array | This array indexing operation accesses byte offset 67 but the $@ is only 64 bytes. | var_size_struct.cpp:78:7:78:14 | elements | array | | var_size_struct.cpp:99:3:99:8 | call to memset | This 'memset' operation accesses 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer | | var_size_struct.cpp:101:3:101:8 | call to memset | This 'memset' operation accesses 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer | | var_size_struct.cpp:103:3:103:9 | call to strncpy | This 'strncpy' operation may access 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer | -| var_size_struct.cpp:171:3:171:8 | call to memset | This 'memset' operation accesses 100 bytes but the $@ is only 1 byte. | var_size_struct.cpp:125:17:125:19 | arr | destination buffer | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowStatic.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowStatic.expected index ef334a73a2c..ac44bbf028d 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowStatic.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowStatic.expected @@ -3,8 +3,6 @@ | tests.cpp:163:3:163:11 | access to array | Potential buffer-overflow: counter 'k' <= 100 but 'buffer' has 100 elements. | | tests.cpp:164:8:164:16 | access to array | Potential buffer-overflow: counter 'k' <= 100 but 'buffer' has 100 elements. | | tests.cpp:245:42:245:42 | 6 | Potential buffer-overflow: 'global_array_5' has size 5 not 6. | -| tests.cpp:349:2:349:14 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' is accessed here. | -| tests.cpp:350:17:350:29 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' is accessed here. | -| var_size_struct.cpp:54:5:54:14 | access to array | Potential buffer-overflow: 'str' has size 1 but 'str[1]' is accessed here. | -| var_size_struct.cpp:55:5:55:14 | access to array | Potential buffer-overflow: 'str' has size 1 but 'str[1]' is accessed here. | +| tests.cpp:349:2:349:14 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' may be accessed here. | +| tests.cpp:350:17:350:29 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' may be accessed here. | | var_size_struct.cpp:103:39:103:41 | 129 | Potential buffer-overflow: 'str' has size 128 not 129. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/UnboundedWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/UnboundedWrite.expected index 58e3dda0964..7cefb7cfafc 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/UnboundedWrite.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/UnboundedWrite.expected @@ -1,3 +1,4 @@ edges +subpaths nodes #select diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/var_size_struct.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/var_size_struct.cpp index 00b433c60ef..a514135f348 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/var_size_struct.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/var_size_struct.cpp @@ -51,8 +51,8 @@ void testVarString(int n) { s1->str[1] = '?'; // GOOD s2->str[1] = '?'; // GOOD s3->str[1] = '?'; // GOOD - s4->str[1] = '?'; // BAD - s5->str[1] = '?'; // BAD + s4->str[1] = '?'; // BAD [NOT DETECTED] + s5->str[1] = '?'; // BAD [NOT DETECTED] } } @@ -161,14 +161,12 @@ void useVarStruct34(varStruct5 *vs5) { varStruct5 *vs5b = (varStruct5 *)malloc(sizeof(*vs5)); varStruct6 *vs6 = (varStruct6 *)malloc(offsetof(varStruct6, arr) + 9); // establish varStruct6 as variable size varStruct7 *vs7 = (varStruct7 *)malloc(sizeForVarStruct7(9)); // establish varStruct7 as variable size - varStruct8 *vs8a = (varStruct8 *)malloc(sizeof(varStruct8) + 9); // establish varStruct8 as variable size - varStruct8 *vs8b = (varStruct8 *)malloc(sizeof(varStruct8)); varStruct9 *vs9 = (varStruct9 *)malloc(__builtin_offsetof(varStruct9, arr) + 9); // establish varStruct9 as variable size } void testVarStruct34(varStruct3 *vs3, varStruct4 *vs4, varStruct5 *vs5, varStruct6 *vs6, varStruct7 *vs7, varStruct8 *vs8, varStruct9 *vs9) { memset(vs3->arr, 'x', 100); // GOOD: it's variable size, we don't know how big so shouldn't flag - memset(vs4->arr, 'x', 100); // BAD: it's not variable size, so this is a buffer overflow + memset(vs4->arr, 'x', 100); // BAD: [NOT DETECTED] it's not variable size, so this is a buffer overflow memset(vs5->arr, 'x', 100); // GOOD: it's variable size, we don't know how big so shouldn't flag memset(vs6->arr, 'x', 100); // GOOD: it's variable size, we don't know how big so shouldn't flag memset(vs7->arr, 'x', 100); // GOOD: it's variable size, we don't know how big so shouldn't flag diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/varsize.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/varsize.expected index d9e9effde62..79406c3eaef 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/varsize.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/varsize.expected @@ -1,12 +1,17 @@ | var_size_struct.cpp:13:8:13:17 | VarString1 | var_size_struct.cpp:15:8:15:10 | str | | var_size_struct.cpp:18:8:18:17 | VarString2 | var_size_struct.cpp:20:8:20:10 | str | | var_size_struct.cpp:24:8:24:17 | VarString3 | var_size_struct.cpp:26:8:26:10 | str | +| var_size_struct.cpp:30:8:30:17 | VarString4 | var_size_struct.cpp:32:8:32:10 | str | +| var_size_struct.cpp:36:8:36:17 | VarString5 | var_size_struct.cpp:38:8:38:10 | str | | var_size_struct.cpp:36:8:36:17 | VarString5 | var_size_struct.cpp:39:8:39:11 | str2 | | var_size_struct.cpp:61:8:61:17 | varStruct1 | var_size_struct.cpp:63:8:63:11 | data | | var_size_struct.cpp:76:8:76:17 | varStruct2 | var_size_struct.cpp:78:7:78:14 | elements | +| var_size_struct.cpp:106:8:106:20 | notVarStruct2 | var_size_struct.cpp:107:8:107:10 | str | | var_size_struct.cpp:119:8:119:17 | varStruct3 | var_size_struct.cpp:121:17:121:19 | arr | +| var_size_struct.cpp:123:8:123:17 | varStruct4 | var_size_struct.cpp:125:17:125:19 | arr | | var_size_struct.cpp:127:8:127:17 | varStruct5 | var_size_struct.cpp:129:17:129:19 | arr | | var_size_struct.cpp:131:8:131:17 | varStruct6 | var_size_struct.cpp:133:17:133:19 | arr | | var_size_struct.cpp:135:8:135:17 | varStruct7 | var_size_struct.cpp:137:17:137:19 | arr | | var_size_struct.cpp:139:8:139:17 | varStruct8 | var_size_struct.cpp:141:9:141:11 | arr | | var_size_struct.cpp:143:8:143:17 | varStruct9 | var_size_struct.cpp:145:17:145:19 | arr | +| var_size_struct.cpp:181:8:181:18 | PseudoUnion | var_size_struct.cpp:183:7:183:10 | data | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/UnboundedWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/UnboundedWrite.expected index 5255753b235..e98353732b9 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/UnboundedWrite.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/UnboundedWrite.expected @@ -49,6 +49,7 @@ edges | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array | | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array indirection | | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array indirection | +subpaths nodes | tests.c:28:22:28:25 | argv | semmle.label | argv | | tests.c:28:22:28:25 | argv | semmle.label | argv | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-129/SAMATE/ImproperArrayIndexValidation/CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c b/cpp/ql/test/query-tests/Security/CWE/CWE-129/SAMATE/ImproperArrayIndexValidation/CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c new file mode 100644 index 00000000000..2092902b665 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-129/SAMATE/ImproperArrayIndexValidation/CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c @@ -0,0 +1,65 @@ +// Snippet from a SAMATE Juliet test case for rule CWE-122 / CWE-129 +// CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c + +typedef unsigned long size_t; +void *malloc(size_t size); +void free(void *ptr); +#define NULL (0) + +typedef struct {} FILE; +FILE *stdin; +char *fgets(char *s, int n, FILE *stream); + +int atoi(const char *nptr); + +void printLine(const char *str); +void printIntLine(int val); + +// --- + +#define CHAR_ARRAY_SIZE (64) + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01_bad() +{ + int data; + /* Initialize data */ + data = -1; + { + char inputBuffer[CHAR_ARRAY_SIZE] = ""; + /* POTENTIAL FLAW: Read data from the console using fgets() */ + if (fgets(inputBuffer, CHAR_ARRAY_SIZE, stdin) != NULL) + { + /* Convert to int */ + data = atoi(inputBuffer); + } + else + { + printLine("fgets() failed."); + } + } + { + int i; + int * buffer = (int *)malloc(10 * sizeof(int)); + /* initialize buffer */ + for (i = 0; i < 10; i++) + { + buffer[i] = 0; + } + /* POTENTIAL FLAW: Attempt to write to an index of the array that is above the upper bound + * This code does check to see if the array index is negative */ + if (data >= 0) + { + buffer[data] = 1; + /* Print the array values */ + for(i = 0; i < 10; i++) + { + printIntLine(buffer[i]); + } + } + else + { + printLine("ERROR: Array index is negative."); + } + free(buffer); + } +} \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-129/SAMATE/ImproperArrayIndexValidation/ImproperArrayIndexValidation.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-129/SAMATE/ImproperArrayIndexValidation/ImproperArrayIndexValidation.expected new file mode 100644 index 00000000000..008ff07b800 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-129/SAMATE/ImproperArrayIndexValidation/ImproperArrayIndexValidation.expected @@ -0,0 +1 @@ +| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:52:20:52:23 | data | $@ flows to here and is used in an array indexing expression, potentially causing an invalid access. | CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:30:19:30:29 | inputBuffer | User-provided value | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-129/SAMATE/ImproperArrayIndexValidation/ImproperArrayIndexValidation.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-129/SAMATE/ImproperArrayIndexValidation/ImproperArrayIndexValidation.qlref new file mode 100644 index 00000000000..f1d46d8f8d6 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-129/SAMATE/ImproperArrayIndexValidation/ImproperArrayIndexValidation.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-129/ImproperArrayIndexValidation.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/UncontrolledFormatString.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/UncontrolledFormatString.expected new file mode 100644 index 00000000000..5bce7b8aa38 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/UncontrolledFormatString.expected @@ -0,0 +1,46 @@ +edges +| char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | +| char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | +| char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data indirection | +| char_connect_socket_w32_vsnprintf_01_bad.c:94:55:94:68 | ... + ... | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | +| char_connect_socket_w32_vsnprintf_01_bad.c:94:55:94:68 | ... + ... | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | +| char_connect_socket_w32_vsnprintf_01_bad.c:94:55:94:68 | ... + ... | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data indirection | +| char_console_fprintf_01_bad.c:30:23:30:35 | ... + ... | char_console_fprintf_01_bad.c:49:21:49:24 | (const char *)... | +| char_console_fprintf_01_bad.c:30:23:30:35 | ... + ... | char_console_fprintf_01_bad.c:49:21:49:24 | data | +| char_console_fprintf_01_bad.c:30:23:30:35 | ... + ... | char_console_fprintf_01_bad.c:49:21:49:24 | data indirection | +| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | (const char *)... | +| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | data | +| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | data indirection | +| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | (const char *)... | +| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | (const char *)... | +| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data | +| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data | +| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data indirection | +| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data indirection | +subpaths +nodes +| char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | semmle.label | recv output argument | +| char_connect_socket_w32_vsnprintf_01_bad.c:94:55:94:68 | ... + ... | semmle.label | ... + ... | +| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | semmle.label | data | +| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | semmle.label | data | +| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | semmle.label | data | +| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data indirection | semmle.label | data indirection | +| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data indirection | semmle.label | data indirection | +| char_console_fprintf_01_bad.c:30:23:30:35 | ... + ... | semmle.label | ... + ... | +| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | semmle.label | fgets output argument | +| char_console_fprintf_01_bad.c:49:21:49:24 | (const char *)... | semmle.label | (const char *)... | +| char_console_fprintf_01_bad.c:49:21:49:24 | (const char *)... | semmle.label | (const char *)... | +| char_console_fprintf_01_bad.c:49:21:49:24 | data | semmle.label | data | +| char_console_fprintf_01_bad.c:49:21:49:24 | data indirection | semmle.label | data indirection | +| char_console_fprintf_01_bad.c:49:21:49:24 | data indirection | semmle.label | data indirection | +| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | semmle.label | call to getenv | +| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | semmle.label | call to getenv | +| char_environment_fprintf_01_bad.c:36:21:36:24 | (const char *)... | semmle.label | (const char *)... | +| char_environment_fprintf_01_bad.c:36:21:36:24 | (const char *)... | semmle.label | (const char *)... | +| char_environment_fprintf_01_bad.c:36:21:36:24 | data | semmle.label | data | +| char_environment_fprintf_01_bad.c:36:21:36:24 | data indirection | semmle.label | data indirection | +| char_environment_fprintf_01_bad.c:36:21:36:24 | data indirection | semmle.label | data indirection | +#select +| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | char_connect_socket_w32_vsnprintf_01_bad.c:94:55:94:68 | ... + ... | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | The value of this argument may come from $@ and is being used as a formatting argument to badVaSink(data), which calls vsnprintf(format) | char_connect_socket_w32_vsnprintf_01_bad.c:94:55:94:68 | ... + ... | recv | +| char_console_fprintf_01_bad.c:49:21:49:24 | data | char_console_fprintf_01_bad.c:30:23:30:35 | ... + ... | char_console_fprintf_01_bad.c:49:21:49:24 | data | The value of this argument may come from $@ and is being used as a formatting argument to fprintf(format) | char_console_fprintf_01_bad.c:30:23:30:35 | ... + ... | fgets | +| char_environment_fprintf_01_bad.c:36:21:36:24 | data | char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data | The value of this argument may come from $@ and is being used as a formatting argument to fprintf(format) | char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | getenv | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/UncontrolledFormatString.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/UncontrolledFormatString.qlref new file mode 100644 index 00000000000..079e0c8a7c0 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/UncontrolledFormatString.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-134/UncontrolledFormatString.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/char_connect_socket_w32_vsnprintf_01_bad.c b/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/char_connect_socket_w32_vsnprintf_01_bad.c new file mode 100644 index 00000000000..ccba3e54840 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/char_connect_socket_w32_vsnprintf_01_bad.c @@ -0,0 +1,126 @@ +// External test case from SAMATE's Juliet Test Suite for C/C++ +// (http://samate.nist.gov/SRD/testsuite.php) +// Associated with CWE-134: Uncontrolled format string. http://cwe.mitre.org/data/definitions/134.html +// This is a snippet with added declarations, not the entire test case. + +typedef unsigned long size_t; + +typedef void *va_list; +#define va_start(ap, parmN) +#define va_end(ap) +#define va_arg(ap, type) ((type)0) + +int vsnprintf(char *s, size_t n, const char *format, va_list arg); + +size_t strlen(const char *s); + +#define SOCKET int +#define INVALID_SOCKET (0) +#define SOCKET_ERROR (1) +#define AF_INET (2) +#define SOCK_STREAM (3) +#define IPPROTO_TCP (4) +#define IP_ADDRESS (5) +#define TCP_PORT (6) +typedef int in_addr_t; +struct in_addr { + in_addr_t s_addr; +}; +struct sockaddr_in { + int sin_family; + int sin_port; + struct in_addr sin_addr; +}; +in_addr_t inet_addr(const char *cp); + +#define IP_ADDRESS "0.0.0.0" + +void printLine(char *); + +static void badVaSink(char * data, ...) +{ + { + char dest[100] = ""; + va_list args; + va_start(args, data); + /* POTENTIAL FLAW: Do not specify the format allowing a possible format string vulnerability */ + vsnprintf(dest, 100-1, data, args); + va_end(args); + printLine(dest); + } +} + +void CWE134_Uncontrolled_Format_String__char_connect_socket_w32_vsnprintf_01_bad() +{ + char * data; + char dataBuffer[100] = ""; + data = dataBuffer; + { +#ifdef _WIN32 + WSADATA wsaData; + int wsaDataInit = 0; +#endif + int recvResult; + struct sockaddr_in service; + char *replace; + SOCKET connectSocket = INVALID_SOCKET; + size_t dataLen = strlen(data); + do + { +#ifdef _WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) + { + break; + } + wsaDataInit = 1; +#endif + /* POTENTIAL FLAW: Read data using a connect socket */ + connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (connectSocket == INVALID_SOCKET) + { + break; + } + memset(&service, 0, sizeof(service)); + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(IP_ADDRESS); + service.sin_port = htons(TCP_PORT); + if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) + { + break; + } + /* Abort on error or the connection was closed, make sure to recv one + * less char than is in the recv_buf in order to append a terminator */ + /* Abort on error or the connection was closed */ + recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(char) * (100 - dataLen - 1), 0); + if (recvResult == SOCKET_ERROR || recvResult == 0) + { + break; + } + /* Append null terminator */ + data[dataLen + recvResult / sizeof(char)] = '\0'; + /* Eliminate CRLF */ + replace = strchr(data, '\r'); + if (replace) + { + *replace = '\0'; + } + replace = strchr(data, '\n'); + if (replace) + { + *replace = '\0'; + } + } + while (0); + if (connectSocket != INVALID_SOCKET) + { + CLOSE_SOCKET(connectSocket); + } +#ifdef _WIN32 + if (wsaDataInit) + { + WSACleanup(); + } +#endif + } + badVaSink(data, data); +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/char_console_fprintf_01_bad.c b/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/char_console_fprintf_01_bad.c new file mode 100644 index 00000000000..1af281b9f42 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/char_console_fprintf_01_bad.c @@ -0,0 +1,97 @@ +// External test case from SAMATE's Juliet Test Suite for C/C++ +// (http://samate.nist.gov/SRD/testsuite.php) +// Associated with CWE-134: Uncontrolled format string. http://cwe.mitre.org/data/definitions/134.html +// Examples amended to have all function declarations inlined. + +#define NULL 0 +typedef unsigned long size_t; +typedef struct {} FILE; +extern FILE * stdin; +extern FILE * stdout; +size_t strlen(const char *s); +char *fgets(char *s, int n, FILE *stream); +int fprintf(FILE *stream, const char *format, ...); +char *strcpy(char *s1, const char *s2); + +void printLine(char *); + +void CWE134_Uncontrolled_Format_String__char_console_fprintf_01_bad() +{ + char * data; + char data_buf[100] = ""; + data = data_buf; + { + /* Read input from the console */ + size_t data_len = strlen(data); + /* if there is room in data, read into it from the console */ + /* POTENTIAL FLAW: Read data from the console */ + if(100-data_len > 1) + { + if (fgets(data+data_len, (int)(100-data_len), stdin) != NULL) + { + /* The next 3 lines remove the carriage return from the string that is + * inserted by fgets() */ + data_len = strlen(data); + if (data_len > 0 && data[data_len-1] == '\n') + { + data[data_len-1] = '\0'; + } + } + else + { + printLine("fgets() failed"); + /* Restore NUL terminator if fgets fails */ + data[data_len] = '\0'; + } + } + } + /* POTENTIAL FLAW: Do not specify the format allowing a possible format string vulnerability */ + fprintf(stdout, data); +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char data_buf[100] = ""; + data = data_buf; + /* FIX: Use a fixed string that does not contain a format specifier */ + strcpy(data, "fixedstringtest"); + /* POTENTIAL FLAW: Do not specify the format allowing a possible format string vulnerability */ + fprintf(stdout, data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + char * data; + char data_buf[100] = ""; + data = data_buf; + { + /* Read input from the console */ + size_t data_len = strlen(data); + /* if there is room in data, read into it from the console */ + /* POTENTIAL FLAW: Read data from the console */ + if(100-data_len > 1) + { + if (fgets(data+data_len, (int)(100-data_len), stdin) != NULL) + { + /* The next 3 lines remove the carriage return from the string that is + * inserted by fgets() */ + data_len = strlen(data); + if (data_len > 0 && data[data_len-1] == '\n') + { + data[data_len-1] = '\0'; + } + } + else + { + printLine("fgets() failed"); + /* Restore NUL terminator if fgets fails */ + data[data_len] = '\0'; + } + } + } + /* FIX: Specify the format disallowing a format string vulnerability */ + fprintf(stdout, "%s\n", data); +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/char_environment_fprintf_01_bad.c b/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/char_environment_fprintf_01_bad.c new file mode 100644 index 00000000000..f759a9d8e61 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/SAMATE/char_environment_fprintf_01_bad.c @@ -0,0 +1,70 @@ +// External test case from SAMATE's Juliet Test Suite for C/C++ +// (http://samate.nist.gov/SRD/testsuite.php) +// Associated with CWE-134: Uncontrolled format string. http://cwe.mitre.org/data/definitions/134.html +// Examples amended to have all function declarations inlined. + +#define NULL 0 +typedef struct {} FILE; +typedef unsigned long size_t; +extern FILE * stdout; +size_t strlen(const char *s); +char *getenv(const char *name); +char *strcpy(char *s1, const char *s2); +char *strncat(char *s1, const char *s2, size_t n); +int fprintf(FILE *stream, const char *format, ...); + +#define ENV_VARIABLE "ADD" +#define GETENV getenv + +void CWE134_Uncontrolled_Format_String__char_environment_fprintf_01_bad() +{ + char * data; + char data_buf[100] = ""; + data = data_buf; + { + /* Append input from an environment variable to data */ + size_t data_len = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+data_len, environment, 100-data_len-1); + } + } + /* POTENTIAL FLAW: Do not specify the format allowing a possible format string vulnerability */ + fprintf(stdout, data); +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + char * data; + char data_buf[100] = ""; + data = data_buf; + /* FIX: Use a fixed string that does not contain a format specifier */ + strcpy(data, "fixedstringtest"); + /* POTENTIAL FLAW: Do not specify the format allowing a possible format string vulnerability */ + fprintf(stdout, data); +} + +/* goodB2G uses the BadSource with the GoodSink */ +static void goodB2G() +{ + char * data; + char data_buf[100] = ""; + data = data_buf; + { + /* Append input from an environment variable to data */ + size_t data_len = strlen(data); + char * environment = GETENV(ENV_VARIABLE); + /* If there is data in the environment variable */ + if (environment != NULL) + { + /* POTENTIAL FLAW: Read data from an environment variable */ + strncat(data+data_len, environment, 100-data_len-1); + } + } + /* FIX: Specify the format disallowing a format string vulnerability */ + fprintf(stdout, "%s\n", data); +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected index b1cf6fbaf8d..a5a17967f69 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected @@ -1,4 +1,5 @@ edges +| argvLocal.c:9:25:9:31 | correct | argvLocal.c:9:25:9:31 | *correct | | argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | (const char *)... | | argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | (const char *)... | | argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array | @@ -13,6 +14,7 @@ edges | argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array | | argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array indirection | | argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array indirection | +| argvLocal.c:96:15:96:21 | access to array indirection | argvLocal.c:9:25:9:31 | *correct | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | (const char *)... | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | (const char *)... | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | i1 | @@ -41,6 +43,7 @@ edges | argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 indirection | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 indirection | +| argvLocal.c:102:15:102:16 | i1 indirection | argvLocal.c:9:25:9:31 | *correct | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | (const char *)... | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | (const char *)... | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array | @@ -69,6 +72,8 @@ edges | argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... indirection | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... indirection | +| argvLocal.c:107:15:107:19 | access to array indirection | argvLocal.c:9:25:9:31 | *correct | +| argvLocal.c:111:15:111:17 | * ... indirection | argvLocal.c:9:25:9:31 | *correct | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | (const char *)... | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | (const char *)... | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 | @@ -113,7 +118,9 @@ edges | argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... indirection | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... indirection | +| argvLocal.c:117:2:117:13 | i3 | argvLocal.c:9:25:9:31 | correct | | argvLocal.c:117:2:117:13 | i3 | argvLocal.c:117:15:117:16 | printWrapper output argument | +| argvLocal.c:117:15:117:16 | i3 indirection | argvLocal.c:9:25:9:31 | *correct | | argvLocal.c:117:15:117:16 | i3 indirection | argvLocal.c:117:15:117:16 | printWrapper output argument | | argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | (const char *)... | | argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | i4 | @@ -129,7 +136,9 @@ edges | argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... | | argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... | | argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... indirection | +| argvLocal.c:122:2:122:13 | i4 | argvLocal.c:9:25:9:31 | correct | | argvLocal.c:122:2:122:13 | i4 | argvLocal.c:122:15:122:16 | printWrapper output argument | +| argvLocal.c:122:15:122:16 | i4 indirection | argvLocal.c:9:25:9:31 | *correct | | argvLocal.c:122:15:122:16 | i4 indirection | argvLocal.c:122:15:122:16 | printWrapper output argument | | argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | (const char *)... | | argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | ... ++ | @@ -165,7 +174,9 @@ edges | argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... indirection | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... indirection | +| argvLocal.c:128:2:128:13 | i5 | argvLocal.c:9:25:9:31 | correct | | argvLocal.c:128:2:128:13 | i5 | argvLocal.c:128:15:128:16 | printWrapper output argument | +| argvLocal.c:128:15:128:16 | i5 indirection | argvLocal.c:9:25:9:31 | *correct | | argvLocal.c:128:15:128:16 | i5 indirection | argvLocal.c:128:15:128:16 | printWrapper output argument | | argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:131:9:131:14 | (const char *)... | | argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:131:9:131:14 | ... + ... | @@ -173,6 +184,9 @@ edges | argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:132:15:132:20 | ... + ... | | argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:132:15:132:20 | ... + ... | | argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:132:15:132:20 | ... + ... indirection | +| argvLocal.c:132:15:132:20 | ... + ... indirection | argvLocal.c:9:25:9:31 | *correct | +| argvLocal.c:136:15:136:18 | -- ... indirection | argvLocal.c:9:25:9:31 | *correct | +| argvLocal.c:145:15:145:16 | i7 indirection | argvLocal.c:9:25:9:31 | *correct | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | (const char *)... | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | (const char *)... | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 | @@ -187,6 +201,7 @@ edges | argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 indirection | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 indirection | +| argvLocal.c:151:15:151:16 | i8 indirection | argvLocal.c:9:25:9:31 | *correct | | argvLocal.c:156:23:156:26 | argv | argvLocal.c:157:9:157:10 | (const char *)... | | argvLocal.c:156:23:156:26 | argv | argvLocal.c:157:9:157:10 | (const char *)... | | argvLocal.c:156:23:156:26 | argv | argvLocal.c:157:9:157:10 | i9 | @@ -199,6 +214,7 @@ edges | argvLocal.c:156:23:156:26 | argv | argvLocal.c:158:15:158:16 | i9 | | argvLocal.c:156:23:156:26 | argv | argvLocal.c:158:15:158:16 | i9 indirection | | argvLocal.c:156:23:156:26 | argv | argvLocal.c:158:15:158:16 | i9 indirection | +| argvLocal.c:158:15:158:16 | i9 indirection | argvLocal.c:9:25:9:31 | *correct | | argvLocal.c:163:22:163:25 | argv | argvLocal.c:164:9:164:11 | (const char *)... | | argvLocal.c:163:22:163:25 | argv | argvLocal.c:164:9:164:11 | (const char *)... | | argvLocal.c:163:22:163:25 | argv | argvLocal.c:164:9:164:11 | i91 | @@ -211,6 +227,7 @@ edges | argvLocal.c:163:22:163:25 | argv | argvLocal.c:165:15:165:17 | i91 | | argvLocal.c:163:22:163:25 | argv | argvLocal.c:165:15:165:17 | i91 indirection | | argvLocal.c:163:22:163:25 | argv | argvLocal.c:165:15:165:17 | i91 indirection | +| argvLocal.c:165:15:165:17 | i91 indirection | argvLocal.c:9:25:9:31 | *correct | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:9:169:20 | (char *)... | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:9:169:20 | (char *)... | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:9:169:20 | (const char *)... | @@ -229,6 +246,14 @@ edges | argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 | +| argvLocal.c:170:15:170:26 | i10 indirection | argvLocal.c:9:25:9:31 | *correct | +subpaths +| argvLocal.c:117:2:117:13 | i3 | argvLocal.c:9:25:9:31 | correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:117:15:117:16 | printWrapper output argument | +| argvLocal.c:117:15:117:16 | i3 indirection | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:117:15:117:16 | printWrapper output argument | +| argvLocal.c:122:2:122:13 | i4 | argvLocal.c:9:25:9:31 | correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:122:15:122:16 | printWrapper output argument | +| argvLocal.c:122:15:122:16 | i4 indirection | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:122:15:122:16 | printWrapper output argument | +| argvLocal.c:128:2:128:13 | i5 | argvLocal.c:9:25:9:31 | correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:128:15:128:16 | printWrapper output argument | +| argvLocal.c:128:15:128:16 | i5 indirection | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:128:15:128:16 | printWrapper output argument | nodes | argvLocal.c:9:25:9:31 | *correct | semmle.label | *correct | | argvLocal.c:9:25:9:31 | *correct | semmle.label | *correct | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected index ceaf0489ec6..0f78d29fd36 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected @@ -51,6 +51,7 @@ edges | funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | (const char *)... | | funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | i6 | | funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | i6 indirection | +subpaths nodes | funcsLocal.c:16:8:16:9 | fread output argument | semmle.label | fread output argument | | funcsLocal.c:16:8:16:9 | i1 | semmle.label | i1 | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatString.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatString.expected index 58e3dda0964..7cefb7cfafc 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatString.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatString.expected @@ -1,3 +1,4 @@ edges +subpaths nodes #select diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected index f095153f39c..8d957ee499c 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected @@ -46,6 +46,7 @@ edges | globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | (const char *)... | | globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 | | globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 indirection | +subpaths nodes | globalVars.c:8:7:8:10 | copy | semmle.label | copy | | globalVars.c:9:7:9:11 | copy2 | semmle.label | copy2 | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/ifs/ifs.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/ifs/ifs.expected index 8c2c89035e2..2805eed6ad0 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/ifs/ifs.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/ifs/ifs.expected @@ -71,6 +71,7 @@ edges | ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 | | ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 indirection | | ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 indirection | +subpaths nodes | ifs.c:61:8:61:11 | argv | semmle.label | argv | | ifs.c:61:8:61:11 | argv | semmle.label | argv | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticTainted.expected new file mode 100644 index 00000000000..690f5ed6550 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticTainted.expected @@ -0,0 +1,14 @@ +edges +| examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data | +| examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data | +| examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data | +| examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data | +subpaths +nodes +| examples.cpp:63:26:63:30 | & ... | semmle.label | & ... | +| examples.cpp:63:26:63:30 | fscanf output argument | semmle.label | fscanf output argument | +| examples.cpp:66:11:66:14 | data | semmle.label | data | +| examples.cpp:66:11:66:14 | data | semmle.label | data | +| examples.cpp:66:11:66:14 | data | semmle.label | data | +#select +| examples.cpp:66:11:66:14 | data | examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:63:26:63:30 | & ... | User-provided value | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticTainted.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticTainted.qlref new file mode 100644 index 00000000000..3939653db1c --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticTainted.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-190/ArithmeticTainted.ql diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticUncontrolled.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticUncontrolled.expected new file mode 100644 index 00000000000..c908f8789c4 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticUncontrolled.expected @@ -0,0 +1,78 @@ +edges +| examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | +| examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | +| examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | +| examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | +| examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | +| examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | +| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | +| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | +| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | +| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | +| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | +| examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | +| examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | +| examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | +| examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | +| examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | +| examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | +| examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | +| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | +| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | +| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | +| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | +| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | +| examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | +nodes +| examples.cpp:22:26:22:33 | (unsigned int)... | semmle.label | (unsigned int)... | +| examples.cpp:22:26:22:33 | (unsigned int)... | semmle.label | (unsigned int)... | +| examples.cpp:22:26:22:33 | (unsigned int)... | semmle.label | (unsigned int)... | +| examples.cpp:22:26:22:33 | (unsigned int)... | semmle.label | (unsigned int)... | +| examples.cpp:22:26:22:33 | (unsigned int)... | semmle.label | (unsigned int)... | +| examples.cpp:22:26:22:33 | (unsigned int)... | semmle.label | (unsigned int)... | +| examples.cpp:22:26:22:33 | call to rand | semmle.label | call to rand | +| examples.cpp:22:26:22:33 | call to rand | semmle.label | call to rand | +| examples.cpp:22:26:22:33 | call to rand | semmle.label | call to rand | +| examples.cpp:22:26:22:33 | call to rand | semmle.label | call to rand | +| examples.cpp:22:26:22:33 | call to rand | semmle.label | call to rand | +| examples.cpp:22:26:22:33 | call to rand | semmle.label | call to rand | +| examples.cpp:25:31:25:34 | data | semmle.label | data | +| examples.cpp:35:26:35:33 | (unsigned int)... | semmle.label | (unsigned int)... | +| examples.cpp:35:26:35:33 | (unsigned int)... | semmle.label | (unsigned int)... | +| examples.cpp:35:26:35:33 | (unsigned int)... | semmle.label | (unsigned int)... | +| examples.cpp:35:26:35:33 | (unsigned int)... | semmle.label | (unsigned int)... | +| examples.cpp:35:26:35:33 | (unsigned int)... | semmle.label | (unsigned int)... | +| examples.cpp:35:26:35:33 | (unsigned int)... | semmle.label | (unsigned int)... | +| examples.cpp:35:26:35:33 | call to rand | semmle.label | call to rand | +| examples.cpp:35:26:35:33 | call to rand | semmle.label | call to rand | +| examples.cpp:35:26:35:33 | call to rand | semmle.label | call to rand | +| examples.cpp:35:26:35:33 | call to rand | semmle.label | call to rand | +| examples.cpp:35:26:35:33 | call to rand | semmle.label | call to rand | +| examples.cpp:35:26:35:33 | call to rand | semmle.label | call to rand | +| examples.cpp:38:9:38:12 | data | semmle.label | data | +subpaths +#select +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | Uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | Uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | Uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | Uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | Uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | Uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | Uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | Uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | Uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | Uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | Uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | Uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | Uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | Uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | Uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | Uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | Uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | Uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | Uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | Uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | Uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | Uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | Uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | Uncontrolled value | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticUncontrolled.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticUncontrolled.qlref new file mode 100644 index 00000000000..1fcafc3ca1c --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticUncontrolled.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-190/ArithmeticUncontrolled.ql diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticWithExtremeValues.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticWithExtremeValues.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticWithExtremeValues.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticWithExtremeValues.qlref new file mode 100644 index 00000000000..ab2c35ce59b --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticWithExtremeValues.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/IntegerOverflowTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/IntegerOverflowTainted.expected new file mode 100644 index 00000000000..9d1fa5388ff --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/IntegerOverflowTainted.expected @@ -0,0 +1 @@ +| examples.cpp:66:9:66:14 | -- ... | $@ flows to here and is used in an expression which might overflow negatively. | examples.cpp:63:26:63:30 | & ... | User-provided value | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/IntegerOverflowTainted.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/IntegerOverflowTainted.qlref new file mode 100644 index 00000000000..df42008c632 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/IntegerOverflowTainted.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-190/IntegerOverflowTainted.ql diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/examples.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/examples.cpp new file mode 100644 index 00000000000..b2cdbbe7133 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/examples.cpp @@ -0,0 +1,70 @@ +// Some SAMATE Juliet test cases for rule CWE-190. + +///// Library functions ////// + +typedef struct {} FILE; +extern FILE *stdin; +int fscanf(FILE *stream, const char *format, ...); +int rand(void); + +#define URAND31() (((unsigned)rand()<<30) ^ ((unsigned)rand()<<15) ^ rand()) +#define RAND32() ((int)(rand() & 1 ? URAND31() : -URAND31() - 1)) + +void printUnsignedLine(unsigned unsignedNumber); + +//// Test code ///// + +void CWE191_Integer_Underflow__unsigned_int_rand_sub_01_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + { + /* POTENTIAL FLAW: Subtracting 1 from data could cause an underflow */ + unsigned int result = data - 1; + printUnsignedLine(result); + } +} + +void CWE191_Integer_Underflow__unsigned_int_rand_postdec_01_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a random value */ + data = (unsigned int)RAND32(); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } +} + +void CWE191_Integer_Underflow__unsigned_int_min_postdec_01_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use the minimum size of the data type */ + data = 0; + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow [NOT DETECTED] */ + data--; + unsigned int result = data; + printUnsignedLine(result); + } +} + +void CWE191_Integer_Underflow__unsigned_int_fscanf_predec_01_bad() +{ + unsigned int data; + data = 0; + /* POTENTIAL FLAW: Use a value input from the console */ + fscanf (stdin, "%u", &data); + { + /* POTENTIAL FLAW: Decrementing data could cause an underflow */ + --data; + unsigned int result = data; + printUnsignedLine(result); + } +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/ArithmeticUncontrolled.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/ArithmeticUncontrolled.expected index 11fb721c987..8f7f3aa2efa 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/ArithmeticUncontrolled.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/ArithmeticUncontrolled.expected @@ -105,6 +105,7 @@ nodes | test.cpp:223:20:223:23 | call to rand | semmle.label | call to rand | | test.cpp:223:20:223:25 | (unsigned int)... | semmle.label | (unsigned int)... | | test.cpp:227:8:227:8 | x | semmle.label | x | +subpaths #select | test.c:21:17:21:17 | r | test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:18:13:18:16 | call to rand | Uncontrolled value | | test.c:35:5:35:5 | r | test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:34:13:34:18 | call to rand | Uncontrolled value | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected index 694f46e1d26..7fe8651f89a 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected @@ -73,6 +73,7 @@ edges | test.cpp:305:18:305:21 | Chi | test.cpp:308:10:308:27 | ... * ... | | test.cpp:305:18:305:21 | Chi | test.cpp:308:10:308:27 | ... * ... | | test.cpp:305:18:305:21 | get_size output argument [[]] | test.cpp:305:18:305:21 | Chi | +subpaths nodes | test.cpp:40:21:40:24 | argv | semmle.label | argv | | test.cpp:40:21:40:24 | argv | semmle.label | argv | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/ArithmeticTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/ArithmeticTainted.expected index e2fefe4a442..e0f72bffd44 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/ArithmeticTainted.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/ArithmeticTainted.expected @@ -23,6 +23,7 @@ edges | test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 | | test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 | | test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 | +subpaths nodes | test2.cpp:12:21:12:21 | v | semmle.label | v | | test2.cpp:14:11:14:11 | v | semmle.label | v | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-197/SAMATE/IntegerOverflowTainted/IntegerOverflowTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-197/SAMATE/IntegerOverflowTainted/IntegerOverflowTainted.expected new file mode 100644 index 00000000000..88b0b206cda --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-197/SAMATE/IntegerOverflowTainted/IntegerOverflowTainted.expected @@ -0,0 +1 @@ +| tests.cpp:38:31:38:34 | data | $@ flows to here and is used in an expression which might overflow. | tests.cpp:57:27:57:31 | & ... | User-provided value | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-197/SAMATE/IntegerOverflowTainted/IntegerOverflowTainted.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-197/SAMATE/IntegerOverflowTainted/IntegerOverflowTainted.qlref new file mode 100644 index 00000000000..72ed7d53685 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-197/SAMATE/IntegerOverflowTainted/IntegerOverflowTainted.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-190/IntegerOverflowTainted.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-197/SAMATE/IntegerOverflowTainted/tests.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-197/SAMATE/IntegerOverflowTainted/tests.cpp new file mode 100644 index 00000000000..79f9a79c97f --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-197/SAMATE/IntegerOverflowTainted/tests.cpp @@ -0,0 +1,74 @@ +//semmle-extractor-options: --edg --target --edg win64 + +// A selection of tests from the SAMATE Juliet framework for rule CWE-197. + +// library types, functions etc +typedef struct {} FILE; +int fscanf(FILE *stream, const char *format, ...); +#define CHAR_MAX (127) +FILE *stdin; + +void printHexCharLine(char charHex); + +// ---------- + +class CWE197_Numeric_Truncation_Error__short_fscanf_82_base +{ +public: + /* pure virtual function */ + virtual void action(short data) = 0; +}; + +class CWE197_Numeric_Truncation_Error__short_fscanf_82_bad : public CWE197_Numeric_Truncation_Error__short_fscanf_82_base +{ +public: + void action(short data); +}; + +class CWE197_Numeric_Truncation_Error__short_fscanf_82_goodG2B : public CWE197_Numeric_Truncation_Error__short_fscanf_82_base +{ +public: + void action(short data); +}; + +void CWE197_Numeric_Truncation_Error__short_fscanf_82_bad::action(short data) +{ + { + /* POTENTIAL FLAW: Convert data to a char, possibly causing a truncation error */ + char charData = (char)data; + printHexCharLine(charData); + } +} + +void CWE197_Numeric_Truncation_Error__short_fscanf_82_goodG2B::action(short data) +{ + { + char charData = (char)data; + printHexCharLine(charData); + } +} + +void bad() +{ + short data; + /* Initialize data */ + data = -1; + /* FLAW: Use a number input from the console using fscanf() */ + fscanf (stdin, "%hd", &data); + CWE197_Numeric_Truncation_Error__short_fscanf_82_base* baseObject = new CWE197_Numeric_Truncation_Error__short_fscanf_82_bad; + baseObject->action(data); + delete baseObject; +} + +/* goodG2B uses the GoodSource with the BadSink */ +static void goodG2B() +{ + short data; + /* Initialize data */ + data = -1; + /* FIX: Use a positive integer less than CHAR_MAX*/ + data = CHAR_MAX-5; + CWE197_Numeric_Truncation_Error__short_fscanf_82_base* baseObject = new CWE197_Numeric_Truncation_Error__short_fscanf_82_goodG2B; + baseObject->action(data); + delete baseObject; +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-290/semmle/AuthenticationBypass/AuthenticationBypass.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-290/semmle/AuthenticationBypass/AuthenticationBypass.expected index 1ad31c3f9f7..360ced04144 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-290/semmle/AuthenticationBypass/AuthenticationBypass.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-290/semmle/AuthenticationBypass/AuthenticationBypass.expected @@ -17,6 +17,7 @@ edges | test.cpp:38:25:38:42 | (const char *)... | test.cpp:42:14:42:20 | address | | test.cpp:38:25:38:42 | (const char *)... | test.cpp:42:14:42:20 | address | | test.cpp:38:25:38:42 | (const char *)... | test.cpp:42:14:42:20 | address indirection | +subpaths nodes | test.cpp:16:25:16:30 | call to getenv | semmle.label | call to getenv | | test.cpp:16:25:16:42 | (const char *)... | semmle.label | (const char *)... | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected index e4f9bc918a4..400c49237ca 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected @@ -5,6 +5,7 @@ edges | test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input | | test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input indirection | | test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input indirection | +subpaths nodes | test.cpp:54:17:54:20 | argv | semmle.label | argv | | test.cpp:54:17:54:20 | argv | semmle.label | argv | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.expected new file mode 100644 index 00000000000..3534c2c7cad --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.expected @@ -0,0 +1,49 @@ +edges +| test3.cpp:68:21:68:29 | password1 | test3.cpp:70:15:70:17 | ptr | +| test3.cpp:75:15:75:22 | password | test3.cpp:77:15:77:17 | ptr | +| test3.cpp:106:20:106:25 | buffer | test3.cpp:108:14:108:19 | buffer | +| test3.cpp:111:28:111:33 | buffer | test3.cpp:113:9:113:14 | buffer | +| test3.cpp:120:9:120:23 | global_password | test3.cpp:138:16:138:29 | call to get_global_str | +| test3.cpp:128:11:128:18 | password | test3.cpp:106:20:106:25 | buffer | +| test3.cpp:132:21:132:22 | call to id | test3.cpp:134:15:134:17 | ptr | +| test3.cpp:132:24:132:32 | password1 | test3.cpp:111:28:111:33 | buffer | +| test3.cpp:132:24:132:32 | password1 | test3.cpp:132:21:132:22 | call to id | +| test3.cpp:138:16:138:29 | call to get_global_str | test3.cpp:140:15:140:18 | data | +| test3.cpp:151:19:151:26 | password | test3.cpp:153:15:153:20 | buffer | +nodes +| test3.cpp:20:15:20:23 | password1 | semmle.label | password1 | +| test3.cpp:24:15:24:23 | password2 | semmle.label | password2 | +| test3.cpp:41:15:41:22 | password | semmle.label | password | +| test3.cpp:49:15:49:22 | password | semmle.label | password | +| test3.cpp:68:21:68:29 | password1 | semmle.label | password1 | +| test3.cpp:70:15:70:17 | ptr | semmle.label | ptr | +| test3.cpp:75:15:75:22 | password | semmle.label | password | +| test3.cpp:77:15:77:17 | ptr | semmle.label | ptr | +| test3.cpp:95:12:95:19 | password | semmle.label | password | +| test3.cpp:106:20:106:25 | buffer | semmle.label | buffer | +| test3.cpp:108:14:108:19 | buffer | semmle.label | buffer | +| test3.cpp:111:28:111:33 | buffer | semmle.label | buffer | +| test3.cpp:113:9:113:14 | buffer | semmle.label | buffer | +| test3.cpp:120:9:120:23 | global_password | semmle.label | global_password | +| test3.cpp:128:11:128:18 | password | semmle.label | password | +| test3.cpp:132:21:132:22 | call to id | semmle.label | call to id | +| test3.cpp:132:24:132:32 | password1 | semmle.label | password1 | +| test3.cpp:134:15:134:17 | ptr | semmle.label | ptr | +| test3.cpp:138:16:138:29 | call to get_global_str | semmle.label | call to get_global_str | +| test3.cpp:140:15:140:18 | data | semmle.label | data | +| test3.cpp:151:19:151:26 | password | semmle.label | password | +| test3.cpp:153:15:153:20 | buffer | semmle.label | buffer | +subpaths +| test3.cpp:132:24:132:32 | password1 | test3.cpp:111:28:111:33 | buffer | test3.cpp:113:9:113:14 | buffer | test3.cpp:132:21:132:22 | call to id | +#select +| test3.cpp:20:3:20:6 | call to send | test3.cpp:20:15:20:23 | password1 | test3.cpp:20:15:20:23 | password1 | This operation transmits 'password1', which may contain unencrypted sensitive data from $@ | test3.cpp:20:15:20:23 | password1 | password1 | +| test3.cpp:24:3:24:6 | call to send | test3.cpp:24:15:24:23 | password2 | test3.cpp:24:15:24:23 | password2 | This operation transmits 'password2', which may contain unencrypted sensitive data from $@ | test3.cpp:24:15:24:23 | password2 | password2 | +| test3.cpp:41:3:41:6 | call to recv | test3.cpp:41:15:41:22 | password | test3.cpp:41:15:41:22 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test3.cpp:41:15:41:22 | password | password | +| test3.cpp:49:3:49:6 | call to recv | test3.cpp:49:15:49:22 | password | test3.cpp:49:15:49:22 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test3.cpp:49:15:49:22 | password | password | +| test3.cpp:70:3:70:6 | call to send | test3.cpp:68:21:68:29 | password1 | test3.cpp:70:15:70:17 | ptr | This operation transmits 'ptr', which may contain unencrypted sensitive data from $@ | test3.cpp:68:21:68:29 | password1 | password1 | +| test3.cpp:77:3:77:6 | call to recv | test3.cpp:75:15:75:22 | password | test3.cpp:77:15:77:17 | ptr | This operation receives into 'ptr', which may put unencrypted sensitive data into $@ | test3.cpp:75:15:75:22 | password | password | +| test3.cpp:95:3:95:6 | call to read | test3.cpp:95:12:95:19 | password | test3.cpp:95:12:95:19 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test3.cpp:95:12:95:19 | password | password | +| test3.cpp:108:2:108:5 | call to recv | test3.cpp:128:11:128:18 | password | test3.cpp:108:14:108:19 | buffer | This operation receives into 'buffer', which may put unencrypted sensitive data into $@ | test3.cpp:128:11:128:18 | password | password | +| test3.cpp:134:3:134:6 | call to send | test3.cpp:132:24:132:32 | password1 | test3.cpp:134:15:134:17 | ptr | This operation transmits 'ptr', which may contain unencrypted sensitive data from $@ | test3.cpp:132:24:132:32 | password1 | password1 | +| test3.cpp:140:3:140:6 | call to send | test3.cpp:120:9:120:23 | global_password | test3.cpp:140:15:140:18 | data | This operation transmits 'data', which may contain unencrypted sensitive data from $@ | test3.cpp:120:9:120:23 | global_password | global_password | +| test3.cpp:153:3:153:6 | call to send | test3.cpp:151:19:151:26 | password | test3.cpp:153:15:153:20 | buffer | This operation transmits 'buffer', which may contain unencrypted sensitive data from $@ | test3.cpp:151:19:151:26 | password | password | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.qlref new file mode 100644 index 00000000000..bb3fc66f1f1 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-311/CleartextTransmission.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test3.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test3.cpp new file mode 100644 index 00000000000..010ed2c8062 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test3.cpp @@ -0,0 +1,155 @@ + +typedef unsigned long size_t; +#define STDIN_FILENO (0) + +size_t strlen(const char *s); + +void send(int fd, const void *buf, size_t bufLen, int d); +void recv(int fd, void *buf, size_t bufLen, int d); +void read(int fd, void *buf, size_t bufLen); + +void LogonUserA(int a, int b, const char *password, int d, int e, int f); + +int val(); + +void test_send(const char *password1, const char *password2, const char *password_hash, const char *message) +{ + { + LogonUserA(val(), val(), password1, val(), val(), val()); // proof `password1` is plaintext + + send(val(), password1, strlen(password1), val()); // BAD: `password1` is sent plaintext (certainly) + } + + { + send(val(), password2, strlen(password2), val()); // BAD: `password2` is sent plaintext (probably) + } + + { + send(val(), password_hash, strlen(password_hash), val()); // GOOD: `password_hash` is sent encrypted + } + + { + send(val(), message, strlen(message), val()); // GOOD: `message` is not a password + } +} + +void test_receive() +{ + { + char password[256]; + + recv(val(), password, 256, val()); // BAD: `password` is received plaintext (certainly) + + LogonUserA(val(), val(), password, val(), val(), val()); // (proof `password` is plaintext) + } + + { + char password[256]; + + recv(val(), password, 256, val()); // BAD: `password` is received plaintext (probably) + } + + { + char password_hash[256]; + + recv(val(), password_hash, 256, val()); // GOOD: `password` is received encrypted + } + + { + char message[256]; + + recv(val(), message, 256, val()); // GOOD: `message` is not a password + } +} + +void test_dataflow(const char *password1) +{ + { + const char *ptr = password1; + + send(val(), ptr, strlen(ptr), val()); // BAD: `password` is sent plaintext + } + + { + char password[256]; + char *ptr = password; + + recv(val(), ptr, 256, val()); // BAD: `password` is received plaintext + } + + { + char buffer[256]; + + recv(val(), buffer, 256, val()); // BAD: `password` is received plaintext [NOT DETECTED] + + char *password = buffer; + } +} + +void test_read() +{ + { + char password[256]; + int fd = val(); + + read(fd, password, 256); // BAD: `password` is received plaintext + } + + { + char password[256]; + int fd = STDIN_FILENO; + + read(fd, password, 256); // GOOD: `password` is received from stdin, not a network socket + } +} + +void my_recv(char *buffer, size_t bufferSize) +{ + recv(val(), buffer, bufferSize, val()); +} + +const char *id(const char *buffer) +{ + return buffer; +} + +char *global_password; + +char *get_global_str() +{ + return global_password; +} + +void test_interprocedural(const char *password1) +{ + { + char password[256]; + + my_recv(password, 256); // BAD: `password` is received plaintext [detected on line 108] + } + + { + const char *ptr = id(password1); + + send(val(), ptr, strlen(ptr), val()); // BAD: `password1` is sent plaintext + } + + { + char *data = get_global_str(); + + send(val(), data, strlen(data), val()); // BAD: `global_password` is sent plaintext + } +} + +char *strncpy(char *s1, const char *s2, size_t n); + +void test_taint(const char *password) +{ + { + char buffer[16]; + + strncpy(buffer, password, 16); + buffer[15] = 0; + send(val(), buffer, 16, val()); // BAD: `password` is (partially) sent plaintext + } +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-497/SAMATE/ExposedSystemData.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-497/SAMATE/ExposedSystemData.expected new file mode 100644 index 00000000000..ffd6f77205e --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-497/SAMATE/ExposedSystemData.expected @@ -0,0 +1 @@ +| tests.c:70:9:70:15 | call to fprintf | This operation exposes system data from $@. | tests.c:54:13:54:22 | call to LogonUserA | call to LogonUserA | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-497/SAMATE/ExposedSystemData.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-497/SAMATE/ExposedSystemData.qlref new file mode 100644 index 00000000000..0c88835bf1f --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-497/SAMATE/ExposedSystemData.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-497/ExposedSystemData.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-497/SAMATE/OutputWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-497/SAMATE/OutputWrite.expected new file mode 100644 index 00000000000..fe7e5b34c77 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-497/SAMATE/OutputWrite.expected @@ -0,0 +1,7 @@ +| tests.c:29:9:29:14 | call to printf | tests.c:29:16:29:21 | %s\n | +| tests.c:29:9:29:14 | call to printf | tests.c:29:24:29:27 | line | +| tests.c:43:13:43:21 | call to printLine | tests.c:43:23:43:38 | fgets() failed | +| tests.c:62:13:62:21 | call to printLine | tests.c:62:23:62:52 | User logged in successfully. | +| tests.c:67:13:67:21 | call to printLine | tests.c:67:23:67:40 | Unable to login. | +| tests.c:70:9:70:15 | call to fprintf | tests.c:70:25:70:67 | User attempted access with password: %s\n | +| tests.c:70:9:70:15 | call to fprintf | tests.c:70:70:70:77 | password | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-497/SAMATE/OutputWrite.ql b/cpp/ql/test/query-tests/Security/CWE/CWE-497/SAMATE/OutputWrite.ql new file mode 100644 index 00000000000..d9e67a944e9 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-497/SAMATE/OutputWrite.ql @@ -0,0 +1,4 @@ +import semmle.code.cpp.security.OutputWrite + +from OutputWrite ow +select ow, ow.getASource() diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-497/SAMATE/tests.c b/cpp/ql/test/query-tests/Security/CWE/CWE-497/SAMATE/tests.c new file mode 100644 index 00000000000..4b1df2a96e1 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-497/SAMATE/tests.c @@ -0,0 +1,72 @@ +// SAMATE Juliet test cases for rule CWE-497. + +// library functions etc +typedef struct {} FILE; + +// define stdout, stderr in a similar style to MinGW +FILE std_files[2]; +#define stdin (&std_files[0]) +#define stderr (&std_files[1]) + +typedef unsigned long size_t; +size_t strlen(const char *s); +int printf(const char *format, ...); +int fprintf(FILE *stream, const char *format, ...); +char *fgets(char *s, int n, FILE *stream); + +typedef struct {} *HANDLE; +int LogonUserA(const char *lpszUserName, const char *lpszDomain, const char *lpszPassword, int dwLogonType, int dwLogonProvider, HANDLE *phToken); +void CloseHandle(HANDLE h); + +#define NULL (0) +#define LOGON32_LOGON_NETWORK (1) +#define LOGON32_PROVIDER_DEFAULT (2) + +void printLine(const char * line) +{ + if(line != NULL) + { + printf("%s\n", line); + } +} + +void CWE535_Info_Exposure_Shell_Error__w32_char_01_bad() +{ + { + char password[100] = ""; + size_t passwordLen = 0; + HANDLE pHandle; + char * username = "User"; + char * domain = "Domain"; + if (fgets(password, 100, stdin) == NULL) + { + printLine("fgets() failed"); + /* Restore NUL terminator if fgets fails */ + password[0] = '\0'; + } + /* Remove the carriage return from the string that is inserted by fgets() */ + passwordLen = strlen(password); + if (passwordLen > 0) + { + password[passwordLen-1] = '\0'; + } + /* Use the password in LogonUser() to establish that it is "sensitive" */ + if (LogonUserA( + username, + domain, + password, + LOGON32_LOGON_NETWORK, + LOGON32_PROVIDER_DEFAULT, + &pHandle) != 0) + { + printLine("User logged in successfully."); + CloseHandle(pHandle); + } + else + { + printLine("Unable to login."); + } + /* FLAW: Write sensitive data to stderr */ + fprintf(stderr, "User attempted access with password: %s\n", password); + } +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-675/semmle/tests/DoubleRelease.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-675/semmle/tests/DoubleRelease.expected new file mode 100644 index 00000000000..8bed519ab4a --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-675/semmle/tests/DoubleRelease.expected @@ -0,0 +1,3 @@ +| test.cpp:20:3:20:8 | call to fclose | Second call to the $@ function is possible. | test.cpp:21:3:21:8 | call to fclose | fclose | +| test.cpp:31:3:31:8 | call to fclose | Second call to the $@ function is possible. | test.cpp:32:3:32:8 | call to fclose | fclose | +| test.cpp:38:3:38:8 | call to fclose | Second call to the $@ function is possible. | test.cpp:44:3:44:8 | call to fclose | fclose | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-675/semmle/tests/DoubleRelease.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-675/semmle/tests/DoubleRelease.qlref new file mode 100644 index 00000000000..3edd226abaa --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-675/semmle/tests/DoubleRelease.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-675/DoubleRelease.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-675/semmle/tests/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-675/semmle/tests/test.cpp new file mode 100644 index 00000000000..986a95b1ce9 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-675/semmle/tests/test.cpp @@ -0,0 +1,83 @@ +#define NULL (0) +typedef int FILE; +FILE *fopen(const char *filename, const char *mode); +int fclose(FILE *stream); +extern FILE * fe; +void test1() +{ + FILE *f; + + f = fopen("myFile.txt", "wt"); + fclose(f); // GOOD + f = NULL; +} + +void test2() +{ + FILE *f; + + f = fopen("myFile.txt", "wt"); + fclose(f); // BAD + fclose(f); +} + +void test3() +{ + FILE *f; + FILE *g; + + f = fopen("myFile.txt", "wt"); + g = f; + fclose(f); // BAD + fclose(g); +} + +int fGtest4_1() +{ + fe = fopen("myFile.txt", "wt"); + fclose(fe); // BAD + return -1; +} + +int fGtest4_2() +{ + fclose(fe); + return -1; +} + +void Gtest4() +{ + fGtest4_1(); + fGtest4_2(); +} + +int fGtest5_1() +{ + fe = fopen("myFile.txt", "wt"); + fclose(fe); // GOOD + fe = NULL; + return -1; +} + +int fGtest5_2() +{ + fclose(fe); + return -1; +} + +void Gtest5() +{ + fGtest5_1(); + fGtest5_2(); +} + +int main(int argc, char *argv[]) +{ + test1(); + test2(); + test3(); + + Gtest4(); + Gtest5(); + return 0; +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-676/SAMATE/DangerousUseOfCin/DangerousUseOfCin.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-676/SAMATE/DangerousUseOfCin/DangerousUseOfCin.expected new file mode 100644 index 00000000000..f5c0b85e28f --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-676/SAMATE/DangerousUseOfCin/DangerousUseOfCin.expected @@ -0,0 +1 @@ +| test.cpp:59:17:59:17 | call to operator>> | Use of 'cin' without specifying the length of the input may be dangerous. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-676/SAMATE/DangerousUseOfCin/DangerousUseOfCin.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-676/SAMATE/DangerousUseOfCin/DangerousUseOfCin.qlref new file mode 100644 index 00000000000..5a35bf81fd9 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-676/SAMATE/DangerousUseOfCin/DangerousUseOfCin.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-676/DangerousUseOfCin.ql diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-676/SAMATE/DangerousUseOfCin/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-676/SAMATE/DangerousUseOfCin/test.cpp new file mode 100644 index 00000000000..704c2a87b3f --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-676/SAMATE/DangerousUseOfCin/test.cpp @@ -0,0 +1,81 @@ +// SAMATE Juliet test case for rule DangerousUseOfCin.ql / CWE-676. + +// --- library types, functions etc --- + +typedef unsigned long size_t; + +namespace std +{ + // --- std::istream --- + + // std::char_traits + template class char_traits; + + typedef size_t streamsize; + + class ios_base { + public: + streamsize width(streamsize wide); + }; + + template > + class basic_ios : public ios_base { + public: + }; + + // std::basic_istream + template > + class basic_istream : virtual public basic_ios { + }; + + // operator>> std::basic_istream -> char* + template basic_istream& operator>>(basic_istream&, charT*); + + // std::istream + typedef basic_istream istream; + + // --- std::cin --- + + extern istream cin; +} + +void printLine(const char *str); + +// --- test cases --- + +using namespace std; + +#define CHAR_BUFFER_SIZE 10 + +void CWE676_Use_of_Potentially_Dangerous_Function__basic_17_bad() +{ + int j; + for(j = 0; j < 1; j++) + { + { + char charBuffer[CHAR_BUFFER_SIZE]; + /* FLAW: using cin in an inherently dangerous fashion */ + /* INCIDENTAL CWE120 Buffer Overflow since cin extraction is unbounded. */ + cin >> charBuffer; // BAD + charBuffer[CHAR_BUFFER_SIZE-1] = '\0'; + printLine(charBuffer); + } + } +} + +/* good1() changes the conditions on the for statements */ +static void CWE676_Use_of_Potentially_Dangerous_Function__basic_17_good1() +{ + int k; + for(k = 0; k < 1; k++) + { + { + char charBuffer[CHAR_BUFFER_SIZE]; + /* FIX: Use cin after specifying the length of the input */ + cin.width(CHAR_BUFFER_SIZE); + cin >> charBuffer; // GOOD + charBuffer[CHAR_BUFFER_SIZE-1] = '\0'; + printLine(charBuffer); + } + } +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/FileMayNotBeClosed.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/FileMayNotBeClosed.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/FileMayNotBeClosed.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/FileMayNotBeClosed.qlref new file mode 100644 index 00000000000..fd711c007f0 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/FileMayNotBeClosed.qlref @@ -0,0 +1 @@ +Critical/FileMayNotBeClosed.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/FileNeverClosed.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/FileNeverClosed.expected new file mode 100644 index 00000000000..c328cee7ec9 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/FileNeverClosed.expected @@ -0,0 +1,3 @@ +| tests.cpp:220:12:220:16 | call to fopen | The file is never closed | +| tests.cpp:252:12:252:15 | call to open | The file is never closed | +| tests.cpp:278:12:278:21 | call to CreateFile | The file is never closed | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/FileNeverClosed.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/FileNeverClosed.qlref new file mode 100644 index 00000000000..825ac26f500 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/FileNeverClosed.qlref @@ -0,0 +1 @@ +Critical/FileNeverClosed.ql diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/MemoryMayNotBeFreed.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/MemoryMayNotBeFreed.expected new file mode 100644 index 00000000000..11a19a071d0 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/MemoryMayNotBeFreed.expected @@ -0,0 +1,2 @@ +| tests.cpp:198:31:198:36 | call to malloc | The memory allocated here may not be released at $@. | tests.cpp:212:1:212:1 | return ... | this exit point | +| tests.cpp:325:5:325:68 | ... = ... | The memory allocated here may not be released at $@. | tests.cpp:333:1:333:1 | return ... | this exit point | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/MemoryMayNotBeFreed.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/MemoryMayNotBeFreed.qlref new file mode 100644 index 00000000000..33da8e296e2 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/MemoryMayNotBeFreed.qlref @@ -0,0 +1 @@ +Critical/MemoryMayNotBeFreed.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/MemoryNeverFreed.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/MemoryNeverFreed.expected new file mode 100644 index 00000000000..087186d9dc6 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/MemoryNeverFreed.expected @@ -0,0 +1,2 @@ +| tests.cpp:71:20:71:26 | new | This memory is never freed | +| tests.cpp:136:24:136:29 | call to malloc | This memory is never freed | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/MemoryNeverFreed.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/MemoryNeverFreed.qlref new file mode 100644 index 00000000000..2d1336a55eb --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/MemoryNeverFreed.qlref @@ -0,0 +1 @@ +Critical/MemoryNeverFreed.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/tests.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/tests.cpp new file mode 100644 index 00000000000..e7b889deb08 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-772/SAMATE/tests.cpp @@ -0,0 +1,333 @@ +// Sample of SAMATE Juliet tests for CWE-772. + +// --- library types, functions etc --- + +#define NULL (0) +typedef unsigned long size_t; + +void *malloc(size_t size); +void *realloc(void *ptr, size_t size); +void *alloca(size_t size); +#define ALLOCA alloca +void free(void *ptr); + +typedef struct {} FILE; +FILE *fopen(const char *filename, const char *mode); +int fclose(FILE *stream); + +char *strcpy(char *s1, const char *s2); + +void printLine(const char *str); +void printIntLine(int val); + +// --- open --- + +typedef unsigned int mode_t; +int open(const char *path, int oflags, mode_t mode); +#define OPEN open +int close(int fd); +#define CLOSE close + +#define O_RDWR (1) +#define O_CREAT (2) +#define S_IREAD (3) +#define S_IWRITE (4) + +// --- Windows --- + +typedef unsigned int HANDLE; +#define INVALID_HANDLE_VALUE (-1) +typedef const char *LPCTSTR; +typedef unsigned long DWORD; +typedef struct _SECURITY_ATTRIBUTES {} *LPSECURITY_ATTRIBUTES; +typedef bool BOOL; +HANDLE CreateFile( + LPCTSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile); +BOOL CloseHandle(HANDLE hObject); + +#define GENERIC_READ (1) +#define GENERIC_WRITE (2) +#define OPEN_ALWAYS (3) +#define FILE_ATTRIBUTE_NORMAL (4) + +// --- test cases --- + +namespace CWE401_Memory_Leak__new_int_17 +{ + void bad() + { + int i,j; + int * data; + data = NULL; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Allocate memory on the heap */ + data = new int; // BAD + /* Initialize and make use of data */ + *data = 5; + printIntLine(*data); + } + for(j = 0; j < 1; j++) + { + /* POTENTIAL FLAW: No deallocation */ + ; /* empty statement needed for some flow variants */ + } + } + + /* goodB2G() - use badsource and goodsink in the for statements */ + static void goodB2G() + { + int i,k; + int * data; + data = NULL; + for(i = 0; i < 1; i++) + { + /* POTENTIAL FLAW: Allocate memory on the heap */ + data = new int; // GOOD + /* Initialize and make use of data */ + *data = 5; + printIntLine(*data); + } + for(k = 0; k < 1; k++) + { + /* FIX: Deallocate memory */ + delete data; + } + } + + /* goodG2B() - use goodsource and badsink in the for statements */ + static void goodG2B() + { + int h,j; + int * data; + data = NULL; + for(h = 0; h < 1; h++) + { + /* FIX: Use memory allocated on the stack */ + int dataGoodBuffer; // GOOD + data = &dataGoodBuffer; + /* Initialize and make use of data */ + *data = 5; + printIntLine(*data); + } + for(j = 0; j < 1; j++) + { + /* POTENTIAL FLAW: No deallocation */ + ; /* empty statement needed for some flow variants */ + } + } +} /* close namespace */ + +void CWE401_Memory_Leak__char_malloc_32_bad() +{ + char * data; + char * *dataPtr1 = &data; + char * *dataPtr2 = &data; + data = NULL; + { + char * data = *dataPtr1; + /* POTENTIAL FLAW: Allocate memory on the heap */ + data = (char *)malloc(100*sizeof(char)); // BAD + /* Initialize and make use of data */ + strcpy(data, "A String"); + printLine(data); + *dataPtr1 = data; + } + { + char * data = *dataPtr2; + /* POTENTIAL FLAW: No deallocation */ + ; /* empty statement needed for some flow variants */ + } +} + +/* goodG2B() uses the GoodSource with the BadSink */ +static void CWE401_Memory_Leak__char_malloc_32_goodG2B() +{ + char * data; + char * *dataPtr1 = &data; + char * *dataPtr2 = &data; + data = NULL; + { + char * data = *dataPtr1; + /* FIX: Use memory allocated on the stack with ALLOCA */ + data = (char *)ALLOCA(100*sizeof(char)); // GOOD + /* Initialize and make use of data */ + strcpy(data, "A String"); + printLine(data); + *dataPtr1 = data; + } + { + char * data = *dataPtr2; + /* POTENTIAL FLAW: No deallocation */ + ; /* empty statement needed for some flow variants */ + } +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void CWE401_Memory_Leak__char_malloc_32_goodB2G() +{ + char * data; + char * *dataPtr1 = &data; + char * *dataPtr2 = &data; + data = NULL; + { + char * data = *dataPtr1; + /* POTENTIAL FLAW: Allocate memory on the heap */ + data = (char *)malloc(100*sizeof(char)); // GOOD + /* Initialize and make use of data */ + strcpy(data, "A String"); + printLine(data); + *dataPtr1 = data; + } + { + char * data = *dataPtr2; + /* FIX: Deallocate memory */ + free(data); + } +} + +void CWE401_Memory_Leak__malloc_realloc_char_01_bad() +{ + { + char * data = (char *)malloc(100*sizeof(char)); // BAD + /* Initialize and make use of data */ + strcpy(data, "A String"); + printLine(data); + /* FLAW: If realloc() fails, the initial memory block will not be freed() */ + data = (char *)realloc(data, (130000)*sizeof(char)); + if (data != NULL) + { + /* Reinitialize and make use of data */ + strcpy(data, "New String"); + printLine(data); + free(data); + } + } +} + +void CWE775_Missing_Release_of_File_Descriptor_or_Handle__fopen_no_close_17_bad() +{ + int j; + FILE * data; + data = NULL; + /* POTENTIAL FLAW: Open a file without closing it */ + data = fopen("BadSource_fopen.txt", "w+"); // BAD + for(j = 0; j < 1; j++) + { + /* FLAW: No attempt to close the file */ + ; /* empty statement needed for some flow variants */ + } +} + +/* goodB2G() - use the goodsink in the for statement */ +static void CWE775_Missing_Release_of_File_Descriptor_or_Handle__fopen_no_close_17_goodB2G() +{ + int k; + FILE * data; + data = NULL; + /* POTENTIAL FLAW: Open a file without closing it */ + data = fopen("BadSource_fopen.txt", "w+"); // GOOD + for(k = 0; k < 1; k++) + { + /* FIX: If the file is still opened, close it */ + if (data != NULL) + { + fclose(data); + } + } +} + +void CWE775_Missing_Release_of_File_Descriptor_or_Handle__open_no_close_01_bad() +{ + int data; + /* Initialize data */ + data = -1; + /* POTENTIAL FLAW: Open a file without closing it */ + data = OPEN("BadSource_open.txt", O_RDWR|O_CREAT, S_IREAD|S_IWRITE); // BAD + /* FLAW: No attempt to close the file */ + ; /* empty statement needed for some flow variants */ +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void CWE775_Missing_Release_of_File_Descriptor_or_Handle__open_no_close_01_goodB2G() +{ + int data; + /* Initialize data */ + data = -1; + /* POTENTIAL FLAW: Open a file without closing it */ + data = OPEN("BadSource_open.txt", O_RDWR|O_CREAT, S_IREAD|S_IWRITE); // GOOD + /* FIX: If the file is still opened, close it */ + if (data != -1) + { + CLOSE(data); + } +} + +void CWE775_Missing_Release_of_File_Descriptor_or_Handle__w32CreateFile_no_close_01_bad() +{ + HANDLE data; + /* Initialize data */ + data = INVALID_HANDLE_VALUE; + /* POTENTIAL FLAW: Open a file without closing it */ + data = CreateFile("BadSource_w32CreateFile.txt", // BAD + (GENERIC_WRITE|GENERIC_READ), + 0, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + /* FLAW: No attempt to close the file */ + ; /* empty statement needed for some flow variants */ +} + +/* goodB2G() uses the BadSource with the GoodSink */ +static void CWE775_Missing_Release_of_File_Descriptor_or_Handle__w32CreateFile_no_close_01_goodB2G() +{ + HANDLE data; + /* Initialize data */ + data = INVALID_HANDLE_VALUE; + /* POTENTIAL FLAW: Open a file without closing it */ + data = CreateFile("BadSource_w32CreateFile.txt", // GOOD + (GENERIC_WRITE|GENERIC_READ), + 0, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + /* FIX: If the file is still opened, close it */ + if (data != INVALID_HANDLE_VALUE) + { + CloseHandle(data); + } +} + +void exit(int status); + +typedef struct _twoIntsStruct +{ + int intOne; + int intTwo; +} twoIntsStruct; + +void printStructLine(const twoIntsStruct * structTwoIntsStruct); + +void CWE401_Memory_Leak__twoIntsStruct_realloc_01_bad() +{ + twoIntsStruct * data; + data = NULL; + /* POTENTIAL FLAW: Allocate memory on the heap */ + data = (twoIntsStruct *)realloc(data, 100*sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + /* Initialize and make use of data */ + data[0].intOne = 0; + data[0].intTwo = 0; + printStructLine(&data[0]); + /* POTENTIAL FLAW: No deallocation */ + ; /* empty statement needed for some flow variants */ +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-807/semmle/TaintedCondition/TaintedCondition.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-807/semmle/TaintedCondition/TaintedCondition.expected index e04a20830d0..1fdb1497922 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-807/semmle/TaintedCondition/TaintedCondition.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-807/semmle/TaintedCondition/TaintedCondition.expected @@ -7,6 +7,7 @@ edges | test.cpp:20:29:20:47 | (const char *)... | test.cpp:24:11:24:16 | call to strcmp | | test.cpp:20:29:20:47 | (const char *)... | test.cpp:41:10:41:38 | ! ... | | test.cpp:20:29:20:47 | (const char *)... | test.cpp:41:11:41:16 | call to strcmp | +subpaths nodes | test.cpp:20:29:20:34 | call to getenv | semmle.label | call to getenv | | test.cpp:20:29:20:47 | (const char *)... | semmle.label | (const char *)... | diff --git a/cpp/ql/test/query-tests/Security/CWE/README.md b/cpp/ql/test/query-tests/Security/CWE/README.md new file mode 100644 index 00000000000..465f0cb3b3f --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/README.md @@ -0,0 +1,5 @@ +# CWE specific security tests + +## Source from the Juliet Test Suite + +Some of the the files in these tests contain source code copied or derived from the public domain "Juliet Test Suite for C/C++" (provided by NIST / SAMATE Team at https://samate.nist.gov/SARD/testsuite.php). Such tests are typically in subdirectories named "SAMATE". diff --git a/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/old.dbscheme b/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/old.dbscheme new file mode 100644 index 00000000000..7806a11dd7a --- /dev/null +++ b/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/old.dbscheme @@ -0,0 +1,2136 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The date of the snapshot. + */ +snapshotDate(unique date snapshotDate : date ref); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Data used by the 'duplicate code' detection. + */ +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +/** + * Data used by the 'similar code' detection. + */ +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +/** + * Data used by the 'duplicate code' and 'similar code' detection. + */ +@duplication_or_similarity = @duplication | @similarity + +/** + * Data used by the 'duplicate code' and 'similar code' detection. + */ +#keyset[id, offset] +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +/* + case @macroinvocations.kind of + 1 = macro expansion + | 2 = other macro reference + ; +*/ +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* + case @function.kind of + 1 = normal + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk + ; +*/ +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point(int id: @function ref, unique int entry_point: @stmt ref); + +function_return_type(int id: @function ref, int return_type: @type ref); + +/** If `function` is a coroutine, then this gives the + std::experimental::resumable_traits instance associated with it, + and the variables representing the `handle` and `promise` for it. */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type(unique int id: @function ref, int this_type: @type ref); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides(int new: @function ref, int old: @function ref); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/* + Built-in types are the fundamental types, e.g., integral, floating, and void. + + case @builtintype.kind of + 1 = error + | 2 = unknown + | 3 = void + | 4 = boolean + | 5 = char + | 6 = unsigned_char + | 7 = signed_char + | 8 = short + | 9 = unsigned_short + | 10 = signed_short + | 11 = int + | 12 = unsigned_int + | 13 = signed_int + | 14 = long + | 15 = unsigned_long + | 16 = signed_long + | 17 = long_long + | 18 = unsigned_long_long + | 19 = signed_long_long + | 20 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/* + Derived types are types that are directly derived from existing types and + point to, refer to, transform type data to return a new type. + + case @derivedtype.kind of + 1 = pointer + | 2 = reference + | 3 = type_with_specifiers + | 4 = array + | 5 = gnu_vector + | 6 = routineptr + | 7 = routinereference + | 8 = rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated + | 10 = block + ; +*/ +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* + case @usertype.kind of + 1 = struct + | 2 = class + | 3 = union + | 4 = enum + | 5 = typedef // classic C: typedef typedef type name + | 6 = template + | 7 = template_parameter + | 8 = template_template_parameter + | 9 = proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated + | 13 = scoped_enum + | 14 = using_alias // a using name = type style typedef + ; +*/ +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + unique string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall(unique int caller: @funbindexpr ref, int kind: int ref); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/semmlecode.cpp.dbscheme b/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..018f430097e --- /dev/null +++ b/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/semmlecode.cpp.dbscheme @@ -0,0 +1,2136 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The date of the snapshot. + */ +snapshotDate(unique date snapshotDate : date ref); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Data used by the 'duplicate code' detection. + */ +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +/** + * Data used by the 'similar code' detection. + */ +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +/** + * Data used by the 'duplicate code' and 'similar code' detection. + */ +@duplication_or_similarity = @duplication | @similarity + +/** + * Data used by the 'duplicate code' and 'similar code' detection. + */ +#keyset[id, offset] +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +/* + case @macroinvocations.kind of + 1 = macro expansion + | 2 = other macro reference + ; +*/ +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* + case @function.kind of + 1 = normal + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk + ; +*/ +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point(int id: @function ref, unique int entry_point: @stmt ref); + +function_return_type(int id: @function ref, int return_type: @type ref); + +/** If `function` is a coroutine, then this gives the + std::experimental::resumable_traits instance associated with it, + and the variables representing the `handle` and `promise` for it. */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type(unique int id: @function ref, int this_type: @type ref); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides(int new: @function ref, int old: @function ref); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/* + Built-in types are the fundamental types, e.g., integral, floating, and void. + + case @builtintype.kind of + 1 = error + | 2 = unknown + | 3 = void + | 4 = boolean + | 5 = char + | 6 = unsigned_char + | 7 = signed_char + | 8 = short + | 9 = unsigned_short + | 10 = signed_short + | 11 = int + | 12 = unsigned_int + | 13 = signed_int + | 14 = long + | 15 = unsigned_long + | 16 = signed_long + | 17 = long_long + | 18 = unsigned_long_long + | 19 = signed_long_long + | 20 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/* + Derived types are types that are directly derived from existing types and + point to, refer to, transform type data to return a new type. + + case @derivedtype.kind of + 1 = pointer + | 2 = reference + | 3 = type_with_specifiers + | 4 = array + | 5 = gnu_vector + | 6 = routineptr + | 7 = routinereference + | 8 = rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated + | 10 = block + ; +*/ +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* + case @usertype.kind of + 1 = struct + | 2 = class + | 3 = union + | 4 = enum + | 5 = typedef // classic C: typedef typedef type name + | 6 = template + | 7 = template_parameter + | 8 = template_template_parameter + | 9 = proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated + | 13 = scoped_enum + | 14 = using_alias // a using name = type style typedef + ; +*/ +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + unique string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall(unique int caller: @funbindexpr ref, int kind: int ref); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/upgrade.properties b/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/upgrade.properties new file mode 100644 index 00000000000..63872bd6f10 --- /dev/null +++ b/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/upgrade.properties @@ -0,0 +1,2 @@ +description: Non-functional change to dbscheme comments +compatibility: full diff --git a/cpp/upgrades/ddd31fd02e51ad270bc9e6712708e5a5b6881518/old.dbscheme b/cpp/upgrades/ddd31fd02e51ad270bc9e6712708e5a5b6881518/old.dbscheme new file mode 100644 index 00000000000..ddd31fd02e5 --- /dev/null +++ b/cpp/upgrades/ddd31fd02e51ad270bc9e6712708e5a5b6881518/old.dbscheme @@ -0,0 +1,2145 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The date of the snapshot. + */ +snapshotDate(unique date snapshotDate : date ref); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Data used by the 'duplicate code' detection. + */ +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +/** + * Data used by the 'similar code' detection. + */ +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +/** + * Data used by the 'duplicate code' and 'similar code' detection. + */ +@duplication_or_similarity = @duplication | @similarity + +/** + * Data used by the 'duplicate code' and 'similar code' detection. + */ +#keyset[id, offset] +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref +); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +/* + case @macroinvocations.kind of + 1 = macro expansion + | 2 = other macro reference + ; +*/ +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* + case @function.kind of + 1 = normal + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk + ; +*/ +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point(int id: @function ref, unique int entry_point: @stmt ref); + +function_return_type(int id: @function ref, int return_type: @type ref); + +/** If `function` is a coroutine, then this gives the + std::experimental::resumable_traits instance associated with it, + and the variables representing the `handle` and `promise` for it. */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type(unique int id: @function ref, int this_type: @type ref); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides(int new: @function ref, int old: @function ref); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/* + Built-in types are the fundamental types, e.g., integral, floating, and void. + + case @builtintype.kind of + 1 = error + | 2 = unknown + | 3 = void + | 4 = boolean + | 5 = char + | 6 = unsigned_char + | 7 = signed_char + | 8 = short + | 9 = unsigned_short + | 10 = signed_short + | 11 = int + | 12 = unsigned_int + | 13 = signed_int + | 14 = long + | 15 = unsigned_long + | 16 = signed_long + | 17 = long_long + | 18 = unsigned_long_long + | 19 = signed_long_long + | 20 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/* + Derived types are types that are directly derived from existing types and + point to, refer to, transform type data to return a new type. + + case @derivedtype.kind of + 1 = pointer + | 2 = reference + | 3 = type_with_specifiers + | 4 = array + | 5 = gnu_vector + | 6 = routineptr + | 7 = routinereference + | 8 = rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated + | 10 = block + ; +*/ +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* + case @usertype.kind of + 1 = struct + | 2 = class + | 3 = union + | 4 = enum + | 5 = typedef // classic C: typedef typedef type name + | 6 = template + | 7 = template_parameter + | 8 = template_template_parameter + | 9 = proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated + | 13 = scoped_enum + | 14 = using_alias // a using name = type style typedef + ; +*/ +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + unique string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall(unique int caller: @funbindexpr ref, int kind: int ref); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/upgrades/ddd31fd02e51ad270bc9e6712708e5a5b6881518/semmlecode.cpp.dbscheme b/cpp/upgrades/ddd31fd02e51ad270bc9e6712708e5a5b6881518/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..7806a11dd7a --- /dev/null +++ b/cpp/upgrades/ddd31fd02e51ad270bc9e6712708e5a5b6881518/semmlecode.cpp.dbscheme @@ -0,0 +1,2136 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The date of the snapshot. + */ +snapshotDate(unique date snapshotDate : date ref); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Data used by the 'duplicate code' detection. + */ +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +/** + * Data used by the 'similar code' detection. + */ +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +/** + * Data used by the 'duplicate code' and 'similar code' detection. + */ +@duplication_or_similarity = @duplication | @similarity + +/** + * Data used by the 'duplicate code' and 'similar code' detection. + */ +#keyset[id, offset] +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +/* + case @macroinvocations.kind of + 1 = macro expansion + | 2 = other macro reference + ; +*/ +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* + case @function.kind of + 1 = normal + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk + ; +*/ +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point(int id: @function ref, unique int entry_point: @stmt ref); + +function_return_type(int id: @function ref, int return_type: @type ref); + +/** If `function` is a coroutine, then this gives the + std::experimental::resumable_traits instance associated with it, + and the variables representing the `handle` and `promise` for it. */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type(unique int id: @function ref, int this_type: @type ref); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides(int new: @function ref, int old: @function ref); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/* + Built-in types are the fundamental types, e.g., integral, floating, and void. + + case @builtintype.kind of + 1 = error + | 2 = unknown + | 3 = void + | 4 = boolean + | 5 = char + | 6 = unsigned_char + | 7 = signed_char + | 8 = short + | 9 = unsigned_short + | 10 = signed_short + | 11 = int + | 12 = unsigned_int + | 13 = signed_int + | 14 = long + | 15 = unsigned_long + | 16 = signed_long + | 17 = long_long + | 18 = unsigned_long_long + | 19 = signed_long_long + | 20 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/* + Derived types are types that are directly derived from existing types and + point to, refer to, transform type data to return a new type. + + case @derivedtype.kind of + 1 = pointer + | 2 = reference + | 3 = type_with_specifiers + | 4 = array + | 5 = gnu_vector + | 6 = routineptr + | 7 = routinereference + | 8 = rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated + | 10 = block + ; +*/ +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* + case @usertype.kind of + 1 = struct + | 2 = class + | 3 = union + | 4 = enum + | 5 = typedef // classic C: typedef typedef type name + | 6 = template + | 7 = template_parameter + | 8 = template_template_parameter + | 9 = proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated + | 13 = scoped_enum + | 14 = using_alias // a using name = type style typedef + ; +*/ +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + unique string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall(unique int caller: @funbindexpr ref, int kind: int ref); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/upgrades/ddd31fd02e51ad270bc9e6712708e5a5b6881518/upgrade.properties b/cpp/upgrades/ddd31fd02e51ad270bc9e6712708e5a5b6881518/upgrade.properties new file mode 100644 index 00000000000..a0c4ba602a1 --- /dev/null +++ b/cpp/upgrades/ddd31fd02e51ad270bc9e6712708e5a5b6881518/upgrade.properties @@ -0,0 +1,4 @@ +description: Removed unused column from the `folders` and `files` relations +compatibility: full +files.rel: reorder files.rel (int id, string name, string simple, string ext, int fromSource) id name +folders.rel: reorder folders.rel (int id, string name, string simple) id name \ No newline at end of file diff --git a/cpp/upgrades/qlpack.yml b/cpp/upgrades/qlpack.yml index acc305bb6a2..7f18cb54c8e 100644 --- a/cpp/upgrades/qlpack.yml +++ b/cpp/upgrades/qlpack.yml @@ -1,3 +1,4 @@ name: codeql/cpp-upgrades upgrades: . version: 0.0.2 +library: true diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/BuildActions.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/BuildActions.cs index 9fd505d5457..1cf1d6253a5 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/BuildActions.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/BuildActions.cs @@ -161,8 +161,11 @@ namespace Semmle.Autobuild.Shared pi.WorkingDirectory = workingDirectory; // Environment variables can only be used when not redirecting stdout - if (!redirectStandardOutput && environment is not null) - environment.ForEach(kvp => pi.Environment[kvp.Key] = kvp.Value); + if (!redirectStandardOutput) + { + if (environment is not null) + environment.ForEach(kvp => pi.Environment[kvp.Key] = kvp.Value); + } return pi; } diff --git a/csharp/change-notes/2021-09-09-service-stack-support.md b/csharp/change-notes/2021-09-09-service-stack-support.md new file mode 100644 index 00000000000..1be10e7aafb --- /dev/null +++ b/csharp/change-notes/2021-09-09-service-stack-support.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* added support for ServiceStack framework with support for SQL injection, XSS and external API calls diff --git a/csharp/change-notes/2021-10-04-constand-condition.md b/csharp/change-notes/2021-10-04-constand-condition.md new file mode 100644 index 00000000000..70ad5b5ea75 --- /dev/null +++ b/csharp/change-notes/2021-10-04-constand-condition.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Discards in tuple patterns, for example `(_, string s)`, are no longer flagged by the query "Constant condition". \ No newline at end of file diff --git a/csharp/change-notes/2021-10-04-dead-store-of-local.md b/csharp/change-notes/2021-10-04-dead-store-of-local.md new file mode 100644 index 00000000000..307f10af654 --- /dev/null +++ b/csharp/change-notes/2021-10-04-dead-store-of-local.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* `using` declarations are no longer flagged by the query "Useless assignment to local variable". diff --git a/csharp/documentation/library-coverage/coverage.csv b/csharp/documentation/library-coverage/coverage.csv index dbac4906d86..32137cb6d38 100644 --- a/csharp/documentation/library-coverage/coverage.csv +++ b/csharp/documentation/library-coverage/coverage.csv @@ -1,2 +1,6 @@ -package,sink,source,summary,sink:html,sink:xss,source:local,summary:taint -System,5,3,13,4,1,3,13 +package,sink,source,summary,sink:code,sink:html,sink:remote,sink:sql,sink:xss,source:local,summary:taint +Dapper,55,,,,,,55,,, +Microsoft.ApplicationBlocks.Data,28,,,,,,28,,, +MySql.Data.MySqlClient,48,,,,,,48,,, +ServiceStack,194,,7,27,,75,92,,,7 +System,28,3,13,,4,,23,1,3,13 diff --git a/csharp/documentation/library-coverage/coverage.rst b/csharp/documentation/library-coverage/coverage.rst index 568eadb4cc6..367e7a35bd2 100644 --- a/csharp/documentation/library-coverage/coverage.rst +++ b/csharp/documentation/library-coverage/coverage.rst @@ -7,6 +7,8 @@ C# framework & library support :widths: auto Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting` - System,"``System.*``, ``System``",3,13,5,5 - Totals,,3,13,5,5 + `ServiceStack `_,"``ServiceStack.*``, ``ServiceStack``",,7,194, + System,"``System.*``, ``System``",3,13,28,5 + Others,"``Dapper``, ``Microsoft.ApplicationBlocks.Data``, ``MySql.Data.MySqlClient``",,,131, + Totals,,3,20,353,5 diff --git a/csharp/documentation/library-coverage/frameworks.csv b/csharp/documentation/library-coverage/frameworks.csv index d0cc09b4e9c..6539f78b265 100644 --- a/csharp/documentation/library-coverage/frameworks.csv +++ b/csharp/documentation/library-coverage/frameworks.csv @@ -1,2 +1,3 @@ Framework name,URL,Namespace prefixes System,,System.* System +ServiceStack,https://servicestack.net/,ServiceStack.* ServiceStack diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/File.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/File.cs index c2fd6837e3e..85ced50fe7e 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/File.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/File.cs @@ -37,7 +37,7 @@ namespace Semmle.Extraction.CIL.Entities yield return parent; yield return Tuples.containerparent(parent, this); } - yield return Tuples.files(this, TransformedPath.Value, TransformedPath.NameWithoutExtension, TransformedPath.Extension); + yield return Tuples.files(this, TransformedPath.Value); } } } diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/Folder.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/Folder.cs index 9c3fbadcf20..e854127137d 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/Folder.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/Folder.cs @@ -28,7 +28,7 @@ namespace Semmle.Extraction.CIL.Entities yield return parentFolder; yield return Tuples.containerparent(parentFolder, this); } - yield return Tuples.folders(this, transformedPath.Value, transformedPath.NameWithoutExtension); + yield return Tuples.folders(this, transformedPath.Value); } } diff --git a/csharp/extractor/Semmle.Extraction.CIL/Tuples.cs b/csharp/extractor/Semmle.Extraction.CIL/Tuples.cs index c8ed3445c6f..d58647aba77 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Tuples.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Tuples.cs @@ -203,14 +203,14 @@ namespace Semmle.Extraction.CIL internal static Tuple containerparent(Folder parent, IFileOrFolder child) => new Tuple("containerparent", parent, child); - internal static Tuple files(File file, string fullName, string name, string extension) => - new Tuple("files", file, fullName, name, extension, 0); + internal static Tuple files(File file, string fullName) => + new Tuple("files", file, fullName); internal static Tuple file_extraction_mode(File file, int mode) => new Tuple("file_extraction_mode", file, mode); - internal static Tuple folders(Folder folder, string path, string name) => - new Tuple("folders", folder, path, name); + internal static Tuple folders(Folder folder, string path) => + new Tuple("folders", folder, path); internal static Tuple locations_default(PdbSourceLocation label, File file, int startLine, int startCol, int endLine, int endCol) => new Tuple("locations_default", label, file, startLine, startCol, endLine, endCol); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Driver/Driver.cs b/csharp/extractor/Semmle.Extraction.CSharp.Driver/Driver.cs index e8a42b3f5a0..047a8ddb8ae 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Driver/Driver.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Driver/Driver.cs @@ -1,3 +1,7 @@ +using System; +using System.Text.RegularExpressions; +using System.Collections.Generic; + namespace Semmle.Extraction.CSharp { /// @@ -9,6 +13,31 @@ namespace Semmle.Extraction.CSharp { Extractor.SetInvariantCulture(); + Console.WriteLine($"Semmle.Extraction.CSharp.Driver: called with {string.Join(", ", args)}"); + + if (args.Length > 0 && args[0] == "--dotnetexec") + { + var compilerRegEx = new Regex(@"csc\.exe|mcs\.exe|csc\.dll", RegexOptions.Compiled); + var cil = args.Length > 1 && args[1] == "--cil"; + for (var i = cil ? 2 : 1; i < args.Length; i++) + { + if (compilerRegEx.IsMatch(args[i])) + { + var argsList = new List(); + if (cil) + argsList.Add("--cil"); + argsList.Add("--compiler"); + argsList.Add(args[i]); + if (i + 1 < args.Length) + argsList.AddRange(args[(i + 1)..]); + return (int)Extractor.Run(argsList.ToArray()); + } + } + + Console.WriteLine($"Semmle.Extraction.CSharp.Driver: not a compiler invocation"); + return 0; + } + return (int)Extractor.Run(args); } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/File.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/File.cs index f22edb158aa..fae77b033ad 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/File.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/File.cs @@ -17,7 +17,7 @@ namespace Semmle.Extraction.CSharp.Entities public override void Populate(TextWriter trapFile) { - trapFile.files(this, TransformedPath.Value, TransformedPath.NameWithoutExtension, TransformedPath.Extension); + trapFile.files(this, TransformedPath.Value); if (TransformedPath.ParentDirectory is PathTransformer.ITransformedPath dir) trapFile.containerparent(Extraction.Entities.Folder.Create(Context, dir), this); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Populators/CompilationUnitVisitor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Populators/CompilationUnitVisitor.cs index 6116c3511a1..be53e48f319 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Populators/CompilationUnitVisitor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Populators/CompilationUnitVisitor.cs @@ -59,8 +59,15 @@ namespace Semmle.Extraction.CSharp.Populators return; } - var entryPoint = Cx.Compilation.GetEntryPoint(System.Threading.CancellationToken.None)!; + var entryPoint = Cx.Compilation.GetEntryPoint(System.Threading.CancellationToken.None); var entryMethod = Method.Create(Cx, entryPoint); + if (entryMethod is null) + { + Cx.ExtractionError("No entry method found. Skipping the extraction of global statements.", + null, Cx.CreateLocation(globalStatements[0].GetLocation()), null, Severity.Info); + return; + } + var block = GlobalStatementsBlock.Create(Cx, entryMethod); for (var i = 0; i < globalStatements.Count; i++) diff --git a/csharp/extractor/Semmle.Extraction/Entities/Folder.cs b/csharp/extractor/Semmle.Extraction/Entities/Folder.cs index 2826ab49ed1..465d545d983 100644 --- a/csharp/extractor/Semmle.Extraction/Entities/Folder.cs +++ b/csharp/extractor/Semmle.Extraction/Entities/Folder.cs @@ -8,7 +8,7 @@ namespace Semmle.Extraction.Entities public override void Populate(TextWriter trapFile) { - trapFile.folders(this, Symbol.Value, Symbol.NameWithoutExtension); + trapFile.folders(this, Symbol.Value); if (Symbol.ParentDirectory is PathTransformer.ITransformedPath parent) trapFile.containerparent(Create(Context, parent), this); } diff --git a/csharp/extractor/Semmle.Extraction/Entities/GeneratedFile.cs b/csharp/extractor/Semmle.Extraction/Entities/GeneratedFile.cs index 7c0e5df7be9..b4a771f53db 100644 --- a/csharp/extractor/Semmle.Extraction/Entities/GeneratedFile.cs +++ b/csharp/extractor/Semmle.Extraction/Entities/GeneratedFile.cs @@ -10,7 +10,7 @@ namespace Semmle.Extraction.Entities public override void Populate(TextWriter trapFile) { - trapFile.files(this, "", "", ""); + trapFile.files(this, ""); } public override void WriteId(EscapingTextWriter trapFile) diff --git a/csharp/extractor/Semmle.Extraction/Tuples.cs b/csharp/extractor/Semmle.Extraction/Tuples.cs index 49c14df7643..2cff4bfbdf1 100644 --- a/csharp/extractor/Semmle.Extraction/Tuples.cs +++ b/csharp/extractor/Semmle.Extraction/Tuples.cs @@ -18,14 +18,14 @@ namespace Semmle.Extraction trapFile.WriteTuple("extractor_messages", error, (int)severity, origin, errorMessage, entityText, location, stackTrace); } - public static void files(this System.IO.TextWriter trapFile, File file, string fullName, string name, string extension) + public static void files(this System.IO.TextWriter trapFile, File file, string fullName) { - trapFile.WriteTuple("files", file, fullName, name, extension, 0); + trapFile.WriteTuple("files", file, fullName); } - internal static void folders(this System.IO.TextWriter trapFile, Folder folder, string path, string name) + internal static void folders(this System.IO.TextWriter trapFile, Folder folder, string path) { - trapFile.WriteTuple("folders", folder, path, name); + trapFile.WriteTuple("folders", folder, path); } public static void locations_default(this System.IO.TextWriter trapFile, SourceLocation label, Entities.File file, int startLine, int startCol, int endLine, int endCol) diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index b760898bf7c..43ea66c228e 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,7 +1,6 @@ name: codeql/csharp-all version: 0.0.2 dbscheme: semmlecode.csharp.dbscheme -suites: codeql-suites extractor: csharp library: true dependencies: diff --git a/csharp/ql/lib/semmle/code/csharp/Attribute.qll b/csharp/ql/lib/semmle/code/csharp/Attribute.qll index 2085c4c650a..06fbda2a150 100644 --- a/csharp/ql/lib/semmle/code/csharp/Attribute.qll +++ b/csharp/ql/lib/semmle/code/csharp/Attribute.qll @@ -25,7 +25,7 @@ class Attributable extends @attributable { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/csharp/ql/lib/semmle/code/csharp/File.qll b/csharp/ql/lib/semmle/code/csharp/File.qll index d8b23bb61f4..df9ce6f3cf6 100644 --- a/csharp/ql/lib/semmle/code/csharp/File.qll +++ b/csharp/ql/lib/semmle/code/csharp/File.qll @@ -33,7 +33,7 @@ class Container extends @container { /** * Gets a URL representing the location of this container. * - * For more information see [Providing URLs](https://help.semmle.com/QL/learn-ql/ql/locations.html#providing-urls). + * For more information see [Providing URLs](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/#providing-urls). */ string getURL() { none() } @@ -171,14 +171,14 @@ class Container extends @container { /** A folder. */ class Folder extends Container, @folder { - override string getAbsolutePath() { folders(this, result, _) } + override string getAbsolutePath() { folders(this, result) } override string getURL() { result = "folder://" + getAbsolutePath() } } /** A file. */ class File extends Container, @file { - override string getAbsolutePath() { files(this, result, _, _, _) } + override string getAbsolutePath() { files(this, result) } /** Gets the number of lines in this file. */ int getNumberOfLines() { numlines(this, result, _, _) } @@ -192,7 +192,7 @@ class File extends Container, @file { override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" } /** Holds if this file contains source code. */ - predicate fromSource() { files(this, _, _, "cs", _) } + predicate fromSource() { this.getExtension() = "cs" } /** Holds if this file is a library. */ predicate fromLibrary() { diff --git a/csharp/ql/lib/semmle/code/csharp/Implements.qll b/csharp/ql/lib/semmle/code/csharp/Implements.qll index c2d33d102dd..cc821b52823 100644 --- a/csharp/ql/lib/semmle/code/csharp/Implements.qll +++ b/csharp/ql/lib/semmle/code/csharp/Implements.qll @@ -398,6 +398,15 @@ private module Gvn { ) } + pragma[noinline] + private predicate toStringPart(int i, int j) { + exists(Unification::GenericType t, int children | + t = this.getConstructedGenericDeclaringTypeAt(i) and + children = t.getNumberOfArgumentsSelf() and + if children = 0 then j = 0 else j in [0 .. 2 * children] + ) + } + language[monotonicAggregates] string toString() { this.isFullyConstructed() and @@ -406,11 +415,7 @@ private module Gvn { or result = strictconcat(int i, int j | - exists(Unification::GenericType t, int children | - t = this.getConstructedGenericDeclaringTypeAt(i) and - children = t.getNumberOfArgumentsSelf() and - if children = 0 then j = 0 else j in [0 .. 2 * children] - ) + this.toStringPart(i, j) | this.toStringConstructedPart(i, j) order by i desc, j ) diff --git a/csharp/ql/lib/semmle/code/csharp/Location.qll b/csharp/ql/lib/semmle/code/csharp/Location.qll index 97f9302c474..22d87f42424 100644 --- a/csharp/ql/lib/semmle/code/csharp/Location.qll +++ b/csharp/ql/lib/semmle/code/csharp/Location.qll @@ -28,7 +28,7 @@ class Location extends @location { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/csharp/ql/lib/semmle/code/csharp/Unification.qll b/csharp/ql/lib/semmle/code/csharp/Unification.qll index 73f739a1f7b..3a2c6745f45 100644 --- a/csharp/ql/lib/semmle/code/csharp/Unification.qll +++ b/csharp/ql/lib/semmle/code/csharp/Unification.qll @@ -17,7 +17,7 @@ module Gvn { string getNameNested(Type t) { if not t instanceof NestedType or t.(NestedType).getDeclaringType() instanceof GenericType then result = t.getName() - else result = getNameNested(t.(NestedType).getDeclaringType()) + "." + t.getName() + else result = getNameNested(t.(NestedType).getDeclaringType()) + "+" + t.getName() } /** @@ -277,6 +277,18 @@ module Gvn { ) } + pragma[noinline] + private predicate toStringPart(int i, int j) { + exists(int offset | + exists(GenericType t, int children | + t = this.getConstructedGenericDeclaringTypeAt(i) and + children = t.getNumberOfArgumentsSelf() and + (if this.isDeclaringTypeAt(i) then offset = 1 else offset = 0) and + if children = 0 then j in [0 .. offset] else j in [0 .. 2 * children + offset] + ) + ) + } + language[monotonicAggregates] string toString() { this.isFullyConstructed() and @@ -284,13 +296,8 @@ module Gvn { result = k.toStringBuiltin(this.getArg(0).toString()) or result = - strictconcat(int i, int j, int offset | - exists(GenericType t, int children | - t = this.getConstructedGenericDeclaringTypeAt(i) and - children = t.getNumberOfArgumentsSelf() and - (if this.isDeclaringTypeAt(i) then offset = 1 else offset = 0) and - if children = 0 then j in [0 .. offset] else j in [0 .. 2 * children + offset] - ) + strictconcat(int i, int j | + toStringPart(i, j) | this.toStringConstructedPart(i, j) order by i desc, j ) @@ -326,79 +333,53 @@ module Gvn { getTypeArgument(k, t, i) = TTypeParameterGvnType() } - /** - * Hold if (non-type-parameters) `arg1` and `arg2` are unifiable, and both are - * the `i`th type argument of a compound type of kind `k`. - */ - pragma[nomagic] - private predicate unifiableNonTypeParameterTypeArguments( - CompoundTypeKind k, GvnTypeArgument arg1, GvnTypeArgument arg2, int i - ) { - exists(int j | - arg1 = getNonTypeParameterTypeArgument(k, _, i) and - arg2 = getNonTypeParameterTypeArgument(k, _, j) and - i <= j and - j <= i - | - arg1 = arg2 - or - unifiable(arg1, arg2) - ) - } - /** * Hold if `arg1` and `arg2` are unifiable, and both are the `i`th type argument * of a compound type of kind `k`. + * + * `subsumes` indicates whether `arg1` in fact subsumes `arg2`. */ pragma[nomagic] private predicate unifiableTypeArguments( - CompoundTypeKind k, GvnTypeArgument arg1, GvnTypeArgument arg2, int i + CompoundTypeKind k, GvnTypeArgument arg1, GvnTypeArgument arg2, int i, boolean subsumes ) { - unifiableNonTypeParameterTypeArguments(k, arg1, arg2, i) - or - exists(int j | - arg1 = TTypeParameterGvnType() and - typeArgumentIsTypeParameter(k, _, i) and - arg2 = getTypeArgument(k, _, j) and - i <= j and - j <= i + arg1 = getNonTypeParameterTypeArgument(k, _, pragma[only_bind_into](i)) and + arg2 = getNonTypeParameterTypeArgument(k, _, pragma[only_bind_into](i)) and + ( + arg1 = arg2 and + subsumes = true + or + unifiable(arg1, arg2, subsumes) ) or - exists(int j | - arg1 = getTypeArgument(k, _, i) and - typeArgumentIsTypeParameter(k, _, j) and - arg2 = TTypeParameterGvnType() and - i <= j and - j <= i - ) + arg1 = TTypeParameterGvnType() and + typeArgumentIsTypeParameter(k, _, pragma[only_bind_into](i)) and + arg2 = getTypeArgument(k, _, pragma[only_bind_into](i)) and + subsumes = true + or + arg1 = getNonTypeParameterTypeArgument(k, _, pragma[only_bind_into](i)) and + typeArgumentIsTypeParameter(k, _, pragma[only_bind_into](i)) and + arg2 = TTypeParameterGvnType() and + subsumes = false } pragma[nomagic] private predicate unifiableSingle0( - CompoundTypeKind k, ConstructedGvnType t2, GvnTypeArgument arg1, GvnTypeArgument arg2 + CompoundTypeKind k, ConstructedGvnType t2, GvnTypeArgument arg1, GvnTypeArgument arg2, + boolean subsumes ) { - unifiableTypeArguments(k, arg1, arg2, 0) and + unifiableTypeArguments(k, arg1, arg2, 0, subsumes) and arg2 = getTypeArgument(k, t2, 0) and k.getNumberOfTypeParameters() = 1 } - /** - * Holds if the type arguments of types `t1` and `t2` are unifiable, `t1` - * and `t2` are of the same kind, and the number of type arguments is 1. - */ - private predicate unifiableSingle(ConstructedGvnType t1, ConstructedGvnType t2) { - exists(CompoundTypeKind k, GvnTypeArgument arg1, GvnTypeArgument arg2 | - unifiableSingle0(k, t2, arg1, arg2) and - arg1 = getTypeArgument(k, t1, 0) - ) - } - pragma[nomagic] private predicate unifiableMultiple01Aux0( - CompoundTypeKind k, ConstructedGvnType t2, GvnTypeArgument arg10, GvnTypeArgument arg21 + CompoundTypeKind k, ConstructedGvnType t2, GvnTypeArgument arg10, GvnTypeArgument arg21, + boolean subsumes ) { exists(GvnTypeArgument arg20 | - unifiableTypeArguments(k, arg10, arg20, 0) and + unifiableTypeArguments(k, arg10, arg20, 0, subsumes) and arg20 = getTypeArgument(k, t2, 0) and arg21 = getTypeArgument(k, t2, 1) ) @@ -406,43 +387,24 @@ module Gvn { pragma[nomagic] private predicate unifiableMultiple01Aux1( - CompoundTypeKind k, ConstructedGvnType t1, GvnTypeArgument arg10, GvnTypeArgument arg21 + CompoundTypeKind k, ConstructedGvnType t1, GvnTypeArgument arg10, GvnTypeArgument arg21, + boolean subsumes ) { exists(GvnTypeArgument arg11 | - unifiableTypeArguments(k, arg11, arg21, 1) and + unifiableTypeArguments(k, arg11, arg21, 1, subsumes) and arg10 = getTypeArgument(k, t1, 0) and arg11 = getTypeArgument(k, t1, 1) ) } - /** - * Holds if the first two type arguments of types `t1` and `t2` are unifiable, - * and both `t1` and `t2` are of kind `k`. - */ - private predicate unifiableMultiple01( - CompoundTypeKind k, ConstructedGvnType t1, ConstructedGvnType t2 - ) { - exists(GvnTypeArgument arg10, GvnTypeArgument arg21 | - unifiableMultiple01Aux0(k, t2, arg10, arg21) and - unifiableMultiple01Aux1(k, t1, arg10, arg21) - ) - } - pragma[nomagic] private predicate unifiableMultiple2Aux( - CompoundTypeKind k, ConstructedGvnType t2, int i, GvnTypeArgument arg1, GvnTypeArgument arg2 + CompoundTypeKind k, ConstructedGvnType t2, int i, GvnTypeArgument arg1, boolean subsumes ) { - unifiableTypeArguments(k, arg1, arg2, i) and - arg2 = getTypeArgument(k, t2, i) and - i >= 2 - } - - private predicate unifiableMultiple2( - CompoundTypeKind k, ConstructedGvnType t1, ConstructedGvnType t2, int i - ) { - exists(GvnTypeArgument arg1, GvnTypeArgument arg2 | - unifiableMultiple2Aux(k, t2, i, arg1, arg2) and - arg1 = getTypeArgument(k, t1, i) + exists(GvnTypeArgument arg2 | + unifiableTypeArguments(k, arg1, arg2, i, subsumes) and + arg2 = getTypeArgument(k, t2, i) and + i >= 2 ) } @@ -452,43 +414,33 @@ module Gvn { */ pragma[nomagic] private predicate unifiableMultiple( - CompoundTypeKind k, ConstructedGvnType t1, ConstructedGvnType t2, int i + CompoundTypeKind k, ConstructedGvnType t1, ConstructedGvnType t2, int i, boolean subsumes ) { - unifiableMultiple01(k, t1, t2) and i = 1 + exists(GvnTypeArgument arg10, GvnTypeArgument arg21, boolean subsumes1, boolean subsumes2 | + unifiableMultiple01Aux0(k, t2, arg10, arg21, subsumes1) and + unifiableMultiple01Aux1(k, t1, arg10, arg21, subsumes2) and + subsumes = subsumes1.booleanAnd(subsumes2) + ) and + i = 1 or - unifiableMultiple(k, t1, t2, i - 1) and - unifiableMultiple2(k, t1, t2, i) - } - - private newtype TTypePath = - TTypePathNil() or - TTypePathCons(int head, TTypePath tail) { exists(getTypeAtCons(_, head, tail)) } - - /** - * Gets the GVN inside GVN `t`, by following the path `path`, if any. - */ - private GvnType getTypeAt(GvnType t, TTypePath path) { - path = TTypePathNil() and - result = t - or - exists(ConstructedGvnTypeList l, int head, TTypePath tail | - t = TConstructedGvnType(l) and - path = TTypePathCons(head, tail) and - result = getTypeAtCons(l, head, tail) + exists(GvnTypeArgument arg1, boolean subsumes1, boolean subsumes2 | + unifiableMultiple(k, t1, t2, i - 1, subsumes1) and + unifiableMultiple2Aux(k, t2, i, arg1, subsumes2) and + arg1 = getTypeArgument(k, t1, i) and + subsumes = subsumes1.booleanAnd(subsumes2) ) } - private GvnType getTypeAtCons(ConstructedGvnTypeList l, int head, TTypePath tail) { - result = getTypeAt(l.getArg(head), tail) - } - - /** - * Gets the leaf GVN inside GVN `t`, by following the path `path`, if any. - */ - pragma[noinline] - private GvnType getLeafTypeAt(GvnType t, TTypePath path) { - result = getTypeAt(t, path) and - not result instanceof ConstructedGvnType + pragma[nomagic] + private predicate unifiable(ConstructedGvnType t1, ConstructedGvnType t2, boolean subsumes) { + exists(CompoundTypeKind k, GvnTypeArgument arg1, GvnTypeArgument arg2 | + unifiableSingle0(k, t2, arg1, arg2, subsumes) and + arg1 = getTypeArgument(k, t1, 0) + ) + or + exists(CompoundTypeKind k | + unifiableMultiple(k, t1, t2, k.getNumberOfTypeParameters() - 1, subsumes) + ) } cached @@ -540,33 +492,20 @@ module Gvn { } /** - * Holds if GVNs `t1` and `t2` can be unified. That is, is it possible to + * Holds if GVNs `t1` and `t2` can be unified. That is, it is possible to * replace all type parameters in `t1` and `t2` with some GVNs (possibly * type parameters themselves) to make the two substituted terms equal. */ cached - predicate unifiable(ConstructedGvnType t1, ConstructedGvnType t2) { - unifiableSingle(t1, t2) - or - exists(CompoundTypeKind k | unifiableMultiple(k, t1, t2, k.getNumberOfTypeParameters() - 1)) - } + predicate unifiable(ConstructedGvnType t1, ConstructedGvnType t2) { unifiable(t1, t2, _) } /** - * Holds if GVN `t1` subsumes GVN `t2`. That is, is it possible to replace all + * Holds if GVN `t1` subsumes GVN `t2`. That is, it is possible to replace all * type parameters in `t1` with some GVNs (possibly type parameters themselves) * to make the two substituted terms equal. */ cached - predicate subsumes(ConstructedGvnType t1, ConstructedGvnType t2) { - unifiable(t1, t2) and // subsumption implies unification - forall(TTypePath path, GvnType leaf1 | leaf1 = getLeafTypeAt(t1, path) | - exists(GvnType child2 | child2 = getTypeAt(t2, path) | - leaf1 = TTypeParameterGvnType() - or - leaf1 = child2 - ) - ) - } + predicate subsumes(ConstructedGvnType t1, ConstructedGvnType t2) { unifiable(t1, t2, true) } } import Cached diff --git a/csharp/ql/lib/semmle/code/csharp/XML.qll b/csharp/ql/lib/semmle/code/csharp/XML.qll index 5871fed0ddd..4c762f4bf65 100755 --- a/csharp/ql/lib/semmle/code/csharp/XML.qll +++ b/csharp/ql/lib/semmle/code/csharp/XML.qll @@ -24,7 +24,7 @@ class XMLLocatable extends @xmllocatable, TXMLLocatable { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll index b129203db70..55a8b1f4c3f 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll @@ -30,7 +30,7 @@ abstract class Bound extends TBound { * The location spans column `sc` of line `sl` to * column `ec` of line `el` in file `path`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0 diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index f36e00403c1..c7140238213 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -88,6 +88,9 @@ private module Frameworks { private import semmle.code.csharp.security.dataflow.flowsinks.Html private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.security.dataflow.XSSSinks + private import semmle.code.csharp.frameworks.ServiceStack + private import semmle.code.csharp.frameworks.Sql + private import semmle.code.csharp.frameworks.EntityFramework } /** diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index 5c2dbb30084..4ca06c93362 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index 5c2dbb30084..4ca06c93362 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index 5c2dbb30084..4ca06c93362 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index 5c2dbb30084..4ca06c93362 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index 5c2dbb30084..4ca06c93362 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll index 728f7b56c42..f43a550af57 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll @@ -786,13 +786,18 @@ private module Cached { } /** - * Holds if the call context `call` either improves virtual dispatch in - * `callable` or if it allows us to prune unreachable nodes in `callable`. + * Holds if the call context `call` improves virtual dispatch in `callable`. */ cached - predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) { + predicate recordDataFlowCallSiteDispatch(DataFlowCall call, DataFlowCallable callable) { reducedViableImplInCallContext(_, callable, call) - or + } + + /** + * Holds if the call context `call` allows us to prune unreachable nodes in `callable`. + */ + cached + predicate recordDataFlowCallSiteUnreachable(DataFlowCall call, DataFlowCallable callable) { exists(Node n | getNodeEnclosingCallable(n) = callable | isUnreachableInCallCached(n, call)) } @@ -846,6 +851,15 @@ private module Cached { TAccessPathFrontSome(AccessPathFront apf) } +/** + * Holds if the call context `call` either improves virtual dispatch in + * `callable` or if it allows us to prune unreachable nodes in `callable`. + */ +predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) { + recordDataFlowCallSiteDispatch(call, callable) or + recordDataFlowCallSiteUnreachable(call, callable) +} + /** * A `Node` at which a cast can occur such that the type should be checked. */ @@ -1222,6 +1236,13 @@ class TypedContent extends MkTypedContent { /** Gets a textual representation of this content. */ string toString() { result = c.toString() } + + /** + * Holds if access paths with this `TypedContent` at their head always should + * be tracked at high precision. This disables adaptive access path precision + * for such access paths. + */ + predicate forceHighPrecision() { forceHighPrecision(c) } } /** diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index ca4d0fa98e7..d75afd20b6c 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -1918,6 +1918,12 @@ private predicate viableConstantBooleanParamArg( int accessPathLimit() { result = 5 } +/** + * Holds if access paths with `c` at their head always should be tracked at high + * precision. This disables adaptive access path precision for such access paths. + */ +predicate forceHighPrecision(Content c) { c instanceof ElementContent } + /** The unit type. */ private newtype TUnit = TMkUnit() diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll index bfc2f5469d0..56286903951 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll @@ -58,7 +58,7 @@ class Node extends TNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll index 523516e60f8..8bca0699e04 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll @@ -186,10 +186,17 @@ module Private { TArgumentSummaryComponent(int i) { parameterPosition(i) } or TReturnSummaryComponent(ReturnKind rk) + private TSummaryComponent thisParam() { + result = TParameterSummaryComponent(instanceParameterPosition()) + } + newtype TSummaryComponentStack = TSingletonSummaryComponentStack(SummaryComponent c) or TConsSummaryComponentStack(SummaryComponent head, SummaryComponentStack tail) { tail.(RequiredSummaryComponentStack).required(head) + or + tail.(RequiredSummaryComponentStack).required(TParameterSummaryComponent(_)) and + head = thisParam() } pragma[nomagic] @@ -198,21 +205,63 @@ module Private { boolean preservesValue ) { c.propagatesFlow(input, output, preservesValue) + or + // observe side effects of callbacks on input arguments + c.propagatesFlow(output, input, preservesValue) and + preservesValue = true and + isCallbackParameter(input) and + isContentOfArgument(output) + or + // flow from the receiver of a callback into the instance-parameter + exists(SummaryComponentStack s, SummaryComponentStack callbackRef | + c.propagatesFlow(s, _, _) or c.propagatesFlow(_, s, _) + | + callbackRef = s.drop(_) and + (isCallbackParameter(callbackRef) or callbackRef.head() = TReturnSummaryComponent(_)) and + input = callbackRef.tail() and + output = TConsSummaryComponentStack(thisParam(), input) and + preservesValue = true + ) + } + + private predicate isCallbackParameter(SummaryComponentStack s) { + s.head() = TParameterSummaryComponent(_) and exists(s.tail()) + } + + private predicate isContentOfArgument(SummaryComponentStack s) { + s.head() = TContentSummaryComponent(_) and isContentOfArgument(s.tail()) + or + s = TSingletonSummaryComponentStack(TArgumentSummaryComponent(_)) + } + + private predicate outputState(SummarizedCallable c, SummaryComponentStack s) { + summary(c, _, s, _) + or + exists(SummaryComponentStack out | + outputState(c, out) and + out.head() = TContentSummaryComponent(_) and + s = out.tail() + ) + or + // Add the argument node corresponding to the requested post-update node + inputState(c, s) and isCallbackParameter(s) + } + + private predicate inputState(SummarizedCallable c, SummaryComponentStack s) { + summary(c, s, _, _) + or + exists(SummaryComponentStack inp | inputState(c, inp) and s = inp.tail()) + or + exists(SummaryComponentStack out | + outputState(c, out) and + out.head() = TParameterSummaryComponent(_) and + s = out.tail() + ) } private newtype TSummaryNodeState = - TSummaryNodeInputState(SummaryComponentStack s) { - exists(SummaryComponentStack input | - summary(_, input, _, _) and - s = input.drop(_) - ) - } or - TSummaryNodeOutputState(SummaryComponentStack s) { - exists(SummaryComponentStack output | - summary(_, _, output, _) and - s = output.drop(_) - ) - } + TSummaryNodeInputState(SummaryComponentStack s) { inputState(_, s) } or + TSummaryNodeOutputState(SummaryComponentStack s) { outputState(_, s) } /** * A state used to break up (complex) flow summaries into atomic flow steps. @@ -238,20 +287,14 @@ module Private { pragma[nomagic] predicate isInputState(SummarizedCallable c, SummaryComponentStack s) { this = TSummaryNodeInputState(s) and - exists(SummaryComponentStack input | - summary(c, input, _, _) and - s = input.drop(_) - ) + inputState(c, s) } /** Holds if this state is a valid output state for `c`. */ pragma[nomagic] predicate isOutputState(SummarizedCallable c, SummaryComponentStack s) { this = TSummaryNodeOutputState(s) and - exists(SummaryComponentStack output | - summary(c, _, output, _) and - s = output.drop(_) - ) + outputState(c, s) } /** Gets a textual representation of this state. */ @@ -331,19 +374,12 @@ module Private { receiver = summaryNodeInputState(c, s.drop(1)) } - private Node pre(Node post) { - summaryPostUpdateNode(post, result) - or - not summaryPostUpdateNode(post, _) and - result = post - } - private predicate callbackInput( SummarizedCallable c, SummaryComponentStack s, Node receiver, int i ) { any(SummaryNodeState state).isOutputState(c, s) and s.head() = TParameterSummaryComponent(i) and - receiver = pre(summaryNodeOutputState(c, s.drop(1))) + receiver = summaryNodeInputState(c, s.drop(1)) } /** Holds if a call targeting `receiver` should be synthesized inside `c`. */ @@ -395,7 +431,7 @@ module Private { or exists(int i | head = TParameterSummaryComponent(i) | result = - getCallbackParameterType(getNodeType(summaryNodeOutputState(pragma[only_bind_out](c), + getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c), s.drop(1))), i) ) ) @@ -421,10 +457,16 @@ module Private { } /** Holds if summary node `post` is a post-update node with pre-update node `pre`. */ - predicate summaryPostUpdateNode(Node post, ParamNode pre) { + predicate summaryPostUpdateNode(Node post, Node pre) { exists(SummarizedCallable c, int i | isParameterPostUpdate(post, c, i) and - pre.isParameterOf(c, i) + pre.(ParamNode).isParameterOf(c, i) + ) + or + exists(SummarizedCallable callable, SummaryComponentStack s | + callbackInput(callable, s, _, _) and + pre = summaryNodeOutputState(callable, s) and + post = summaryNodeInputState(callable, s) ) } @@ -462,7 +504,11 @@ module Private { // for `StringBuilder.append(x)` with a specified value flow from qualifier to // return value and taint flow from argument 0 to the qualifier, then this // allows us to infer taint flow from argument 0 to the return value. - summaryPostUpdateNode(pred, succ) and preservesValue = true + succ instanceof ParamNode and summaryPostUpdateNode(pred, succ) and preservesValue = true + or + // Similarly we would like to chain together summaries where values get passed + // into callbacks along the way. + pred instanceof ArgNode and summaryPostUpdateNode(succ, pred) and preservesValue = true } /** diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll index b0f67e8692f..822822a24c6 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll @@ -16,6 +16,9 @@ private import semmle.code.csharp.dataflow.ExternalFlow /** Holds is `i` is a valid parameter position. */ predicate parameterPosition(int i) { i in [-1 .. any(Parameter p).getPosition()] } +/** Gets the parameter position of the instance parameter. */ +int instanceParameterPosition() { none() } // disables implicit summary flow to `this` for callbacks + /** Gets the synthesized summary data-flow node for the given values. */ Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = TSummaryNode(c, state) } diff --git a/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll b/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll index 80066392c1c..d0b4ef45ce8 100644 --- a/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll +++ b/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll @@ -508,7 +508,7 @@ private module Internal { override RuntimeCallable getADynamicTarget() { result = getAViableInherited() or - result = getAViableOverrider() and strictcount(getAViableOverrider()) < 1000 + result = getAViableOverrider() or // Simple case: target method cannot be overridden result = getAStaticTarget() and diff --git a/csharp/ql/lib/semmle/code/csharp/dispatch/RuntimeCallable.qll b/csharp/ql/lib/semmle/code/csharp/dispatch/RuntimeCallable.qll index 22758fce4ab..bb279fcb4fb 100644 --- a/csharp/ql/lib/semmle/code/csharp/dispatch/RuntimeCallable.qll +++ b/csharp/ql/lib/semmle/code/csharp/dispatch/RuntimeCallable.qll @@ -15,7 +15,10 @@ private import dotnet class RuntimeCallable extends DotNet::Callable { RuntimeCallable() { not this.(Modifiable).isAbstract() and - not getDeclaringType() instanceof Interface + ( + not getDeclaringType() instanceof Interface or + this.(Virtualizable).isVirtual() + ) } } diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll index 29939efccdb..36882d3b12e 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll @@ -9,6 +9,7 @@ private import semmle.code.csharp.frameworks.system.data.Entity private import semmle.code.csharp.frameworks.system.collections.Generic private import semmle.code.csharp.frameworks.Sql private import semmle.code.csharp.dataflow.FlowSummary +private import semmle.code.csharp.dataflow.ExternalFlow private import semmle.code.csharp.dataflow.internal.DataFlowPrivate as DataFlowPrivate /** @@ -234,26 +235,29 @@ module EntityFramework { override Expr getSql() { result = this.getArgumentForParameter(sqlParam) } } - /** A call to `System.Data.Entity.DbSet.SqlQuery`. */ - class SystemDataEntityDbSetSqlExpr extends SqlExpr, MethodCall { - SystemDataEntityDbSetSqlExpr() { - this.getTarget() = any(SystemDataEntity::DbSet dbSet).getSqlQueryMethod() + /** The sink method `System.Data.Entity.DbSet.SqlQuery`. */ + private class SystemDataEntityDbSetSqlQuerySinkModelCsv extends SinkModelCsv { + override predicate row(string row) { + row = + ["System.Data.Entity;DbSet;false;SqlQuery;(System.String,System.Object[]);;Argument[0];sql"] } - - override Expr getSql() { result = this.getArgumentForName("sql") } } - /** A call to a method in `System.Data.Entity.Database` that executes SQL. */ - class SystemDataEntityDatabaseSqlExpr extends SqlExpr, MethodCall { - SystemDataEntityDatabaseSqlExpr() { - exists(SystemDataEntity::Database db | - this.getTarget() = db.getSqlQueryMethod() or - this.getTarget() = db.getExecuteSqlCommandMethod() or - this.getTarget() = db.getExecuteSqlCommandAsyncMethod() - ) + /** A sink method in `System.Data.Entity.Database` that executes SQL. */ + private class SystemDataEntityDatabaseSinkModelCsv extends SinkModelCsv { + override predicate row(string row) { + row = + [ + "System.Data.Entity;Database;false;SqlQuery;(System.Type,System.String,System.Object[]);;Argument[1];sql", + "System.Data.Entity;Database;false;SqlQuery<>;(System.String,System.Object[]);;Argument[0];sql", + "System.Data.Entity;Database;false;ExecuteSqlCommand;(System.String,System.Object[]);;Argument[0];sql", + "System.Data.Entity;Database;false;ExecuteSqlCommand;(System.Data.Entity.TransactionalBehavior,System.String,System.Object[]);;Argument[1];sql", + "System.Data.Entity;Database;false;ExecuteSqlCommandAsync;(System.Data.Entity.TransactionalBehavior,System.String,System.Threading.CancellationToken,System.Object[]);;Argument[1];sql", + "System.Data.Entity;Database;false;ExecuteSqlCommandAsync;(System.String,System.Threading.CancellationToken,System.Object[]);;Argument[0];sql", + "System.Data.Entity;Database;false;ExecuteSqlCommandAsync;(System.String,System.Object[]);;Argument[0];sql", + "System.Data.Entity;Database;false;ExecuteSqlCommandAsync;(System.Data.Entity.TransactionalBehavior,System.String,System.Object[]);;Argument[1];sql" + ] } - - override Expr getSql() { result = this.getArgumentForName("sql") } } /** Holds if `t` is compatible with a DB column type. */ diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/ServiceStack.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/ServiceStack.qll new file mode 100644 index 00000000000..6604597d9bc --- /dev/null +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/ServiceStack.qll @@ -0,0 +1,321 @@ +/** + * General modelling of ServiceStack framework including separate modules for: + * - flow sources + * - SQLi sinks + * - XSS sinks + */ + +import csharp +private import semmle.code.csharp.dataflow.ExternalFlow + +/** A class representing a Service */ +private class ServiceClass extends Class { + ServiceClass() { + this.getBaseClass+().hasQualifiedName("ServiceStack", "Service") or + this.getABaseType*().getABaseInterface().hasQualifiedName("ServiceStack", "IService") + } + + /** Get a method that handles incoming requests */ + Method getARequestMethod() { + exists(string name | + result = this.getAMethod(name) and + name.regexpMatch("(Get|Post|Put|Delete|Any|Option|Head|Patch)(Async|Json|Xml|Jsv|Csv|Html|Protobuf|Msgpack|Wire)?") + ) + } +} + +/** Top-level Request DTO types */ +private class RequestDTO extends Class { + RequestDTO() { + this.getABaseType*().getABaseInterface().hasQualifiedName("ServiceStack", "IReturn") + } +} + +/** Flow sources for the ServiceStack framework */ +module Sources { + private import semmle.code.csharp.security.dataflow.flowsources.Remote + + /** + * Remote flow sources for ServiceStack. Parameters of well-known `request` methods. + */ + private class ServiceStackSource extends RemoteFlowSource { + ServiceStackSource() { + exists(ServiceClass service | + service.getARequestMethod().getAParameter() = this.asParameter() + ) + } + + override string getSourceType() { result = "ServiceStack request parameter" } + } +} + +private class ServiceStackRemoteSinkModelCsv extends SinkModelCsv { + override predicate row(string row) { + row = + [ + // IRestClient + "ServiceStack;IRestClient;true;Send<>;(System.String,System.String,System.Object);;Argument[2];remote", + "ServiceStack;IRestClient;true;Patch<>;(System.String,System.Object);;Argument[1];remote", + "ServiceStack;IRestClient;true;Post<>;(System.String,System.Object);;Argument[1];remote", + "ServiceStack;IRestClient;true;Put<>;(System.String,System.Object);;Argument[1];remote", + // IRestClientSync + "ServiceStack;IRestClientSync;true;CustomMethod;(System.String,ServiceStack.IReturnVoid);;Argument[1];remote", + "ServiceStack;IRestClientSync;true;CustomMethod<>;(System.String,System.Object);;Argument[1];remote", + "ServiceStack;IRestClientSync;true;CustomMethod<>;(System.String,ServiceStack.IReturn);;Argument[1];remote", + "ServiceStack;IRestClientSync;true;Delete;(ServiceStack.IReturnVoid);;Argument[0];remote", + "ServiceStack;IRestClientSync;true;Delete<>;(System.Object);;Argument[0];remote", + "ServiceStack;IRestClientSync;true;Delete<>;(ServiceStack.IReturn);;Argument[0];remote", + "ServiceStack;IRestClientSync;true;Get;(ServiceStack.IReturnVoid);;Argument[0];remote", + "ServiceStack;IRestClientSync;true;Get<>;(System.Object);;Argument[0];remote", + "ServiceStack;IRestClientSync;true;Get<>;(ServiceStack.IReturn);;Argument[0];remote", + "ServiceStack;IRestClientSync;true;Patch;(ServiceStack.IReturnVoid);;Argument[0];remote", + "ServiceStack;IRestClientSync;true;Patch<>;(System.Object);;Argument[0];remote", + "ServiceStack;IRestClientSync;true;Patch<>;(ServiceStack.IReturn);;Argument[0];remote", + "ServiceStack;IRestClientSync;true;Post;(ServiceStack.IReturnVoid);;Argument[0];remote", + "ServiceStack;IRestClientSync;true;Post<>;(System.Object);;Argument[0];remote", + "ServiceStack;IRestClientSync;true;Post<>;(ServiceStack.IReturn);;Argument[0];remote", + "ServiceStack;IRestClientSync;true;Put;(ServiceStack.IReturnVoid);;Argument[0];remote", + "ServiceStack;IRestClientSync;true;Put<>;(System.Object);;Argument[0];remote", + "ServiceStack;IRestClientSync;true;Put<>;(ServiceStack.IReturn);;Argument[0];remote", + // IRestGateway + "ServiceStack;IRestGateway;true;Delete<>;(ServiceStack.IReturn);;Argument[0];remote", + "ServiceStack;IRestGateway;true;Get<>;(ServiceStack.IReturn);;Argument[0];remote", + "ServiceStack;IRestGateway;true;Post<>;(ServiceStack.IReturn);;Argument[0];remote", + "ServiceStack;IRestGateway;true;Put<>;(ServiceStack.IReturn);;Argument[0];remote", + "ServiceStack;IRestGateway;true;Send<>;(ServiceStack.IReturn);;Argument[0];remote", + // IOneWayClient + "ServiceStack;IOneWayClient;true;SendAllOneWay;(System.Collections.Generic.IEnumerable);;Element of Argument[1];remote", + "ServiceStack;IOneWayClient;true;SendOneWay;(System.String,System.Object);;Argument[1];remote", + "ServiceStack;IOneWayClient;true;SendOneWay;(System.Object);;Argument[0];remote", + // IServiceGateway + "ServiceStack;IServiceGateway;true;Publish;(System.Object);;Argument[0];remote", + "ServiceStack;IServiceGateway;true;PublishAll;(System.Collections.Generic.IEnumerable);;Element of Argument[0];remote", + "ServiceStack;IServiceGateway;true;Send<>;(System.Object);;Argument[0];remote", + "ServiceStack;IServiceGateway;true;SendAll<>;(System.Collections.Generic.IEnumerable);;Element of Argument[0];remote", + // IRestClientAsync + "ServiceStack;IRestClientAsync;true;CustomMethodAsync;(System.String,ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[1];remote", + "ServiceStack;IRestClientAsync;true;CustomMethodAsync<>;(System.String,System.Object,System.Threading.CancellationToken);;Argument[1];remote", + "ServiceStack;IRestClientAsync;true;CustomMethodAsync<>;(System.String,ServiceStack.IReturn,System.Threading.CancellationToken);;Argument[1];remote", + "ServiceStack;IRestClientAsync;true;DeleteAsync;(ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestClientAsync;true;DeleteAsync<>;(System.Object,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestClientAsync;true;DeleteAsync<>;(ServiceStack.IReturn,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestClientAsync;true;GetAsync;(ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestClientAsync;true;GetAsync<>;(System.Object,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestClientAsync;true;GetAsync<>;(ServiceStack.IReturn,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestClientAsync;true;PatchAsync;(ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestClientAsync;true;PatchAsync<>;(System.Object,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestClientAsync;true;PatchAsync<>;(ServiceStack.IReturn,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestClientAsync;true;PostAsync;(ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestClientAsync;true;PostAsync<>;(System.Object,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestClientAsync;true;PostAsync<>;(ServiceStack.IReturn,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestClientAsync;true;PutAsync;(ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestClientAsync;true;PutAsync<>;(System.Object,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestClientAsync;true;PutAsync<>;(ServiceStack.IReturn,System.Threading.CancellationToken);;Argument[0];remote", + // IRestGatewayAsync + "ServiceStack;IRestGatewayAsync;true;DeleteAsync<>;(ServiceStack.IReturn,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestGatewayAsync;true;GetAsync<>;(ServiceStack.IReturn,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestGatewayAsync;true;PostAsync<>;(ServiceStack.IReturn,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestGatewayAsync;true;PutAsync<>;(ServiceStack.IReturn,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IRestGatewayAsync;true;SendAsync<>;(ServiceStack.IReturn,System.Threading.CancellationToken);;Argument[0];remote", + // IServiceGatewayAsync + "ServiceStack;IServiceGatewayAsync;true;PublishAsync;(System.Object,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IServiceGatewayAsync;true;PublishAllAsync;(System.Collections.Generic.IEnumerable,System.Threading.CancellationToken);;Element of Argument[0];remote", + "ServiceStack;IServiceGatewayAsync;true;SendAsync<>;(System.Object,System.Threading.CancellationToken);;Argument[0];remote", + "ServiceStack;IServiceGatewayAsync;true;SendAllAsync<>;(System.Collections.Generic.IEnumerable,System.Threading.CancellationToken);;Element of Argument[0];remote", + // ServiceClientBase + "ServiceStack;ServiceClientBase;true;Publish<>;(T);;Argument[0];remote", + "ServiceStack;ServiceClientBase;true;Publish<>;(ServiceStack.Messaging.IMessage);;Argument[0];remote", + "ServiceStack;ServiceClientBase;true;Delete;(System.Object);;Argument[0];remote", + "ServiceStack;ServiceClientBase;true;Get;(System.Object);;Argument[0];remote", + "ServiceStack;ServiceClientBase;true;Patch;(System.Object);;Argument[0];remote", + "ServiceStack;ServiceClientBase;true;Post;(System.Object);;Argument[0];remote", + "ServiceStack;ServiceClientBase;true;Put;(System.Object);;Argument[0];remote", + "ServiceStack;ServiceClientBase;true;Head;(System.Object);;Argument[0];remote", + "ServiceStack;ServiceClientBase;true;Head;(ServiceStack.IReturn);;Argument[0];remote", + "ServiceStack;ServiceClientBase;true;CustomMethod;(System.String,System.String,System.Object);;Argument[2];remote", + "ServiceStack;ServiceClientBase;true;CustomMethod<>;(System.String,System.String,System.Object);;Argument[2];remote", + "ServiceStack;ServiceClientBase;true;CustomMethodAsync<>;(System.String,System.String,System.Object,System.Threading.CancellationToken);;Argument[2];remote", + "ServiceStack;ServiceClientBase;true;DownloadBytes;(System.String,System.String,System.Object);;Argument[2];remote", + "ServiceStack;ServiceClientBase;true;DownloadBytesAsync;(System.String,System.String,System.Object);;Argument[2];remote" + ] + } +} + +private class ServiceStackSqlSinkModelCsv extends SinkModelCsv { + override predicate row(string row) { + row = + [ + // SqlExpression + "ServiceStack.OrmLite;SqlExpression<>;true;UnsafeAnd;(System.String,System.Object[]);;Argument[0];sql", + "ServiceStack.OrmLite;SqlExpression<>;true;UnsafeFrom;(System.String);;Argument[0];sql", + "ServiceStack.OrmLite;SqlExpression<>;true;UnsafeGroupBy;(System.String);;Argument[0];sql", + "ServiceStack.OrmLite;SqlExpression<>;true;UnsafeHaving;(System.String,System.Object[]);;Argument[0];sql", + "ServiceStack.OrmLite;SqlExpression<>;true;UnsafeOr;(System.String,System.Object[]);;Argument[0];sql", + "ServiceStack.OrmLite;SqlExpression<>;true;UnsafeOrderBy;(System.String);;Argument[0];sql", + "ServiceStack.OrmLite;SqlExpression<>;true;UnsafeSelect;(System.String,System.Boolean);;Argument[0];sql", + "ServiceStack.OrmLite;SqlExpression<>;true;UnsafeSelect;(System.String);;Argument[0];sql", + "ServiceStack.OrmLite;SqlExpression<>;true;UnsafeWhere;(System.String,System.Object[]);;Argument[0];sql", + // IUntypedSqlExpression + "ServiceStack.OrmLite;IUntypedSqlExpression;true;UnsafeAnd;(System.String,System.Object[]);;Argument[0];sql", + "ServiceStack.OrmLite;IUntypedSqlExpression;true;UnsafeFrom;(System.String);;Argument[0];sql", + "ServiceStack.OrmLite;IUntypedSqlExpression;true;UnsafeOr;(System.String,System.Object[]);;Argument[0];sql", + "ServiceStack.OrmLite;IUntypedSqlExpression;true;UnsafeSelect;(System.String);;Argument[0];sql", + "ServiceStack.OrmLite;IUntypedSqlExpression;true;UnsafeWhere;(System.String,System.Object[]);;Argument[0];sql", + // OrmLiteReadApi + "ServiceStack.OrmLite;OrmLiteReadApi;false;ExecuteNonQuery;(System.Data.IDbConnection,System.String);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;ExecuteNonQuery;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;ExecuteNonQuery;(System.Data.IDbConnection,System.String,System.Action);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;ExecuteNonQuery;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;Exists<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;Dictionary<,>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;Lookup<,>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;Lookup<,>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;KeyValuePairs;(System.Data.IDbConnection,System.String,System.System.Object);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;Scalar<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;Scalar<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;Select<>;(System.Data.IDbConnection,System.Type,System.String,System.Object);;Argument[2];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;Select<>;(System.Data.IDbConnection,System.String);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;Select<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;Select<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;Select<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;SelectLazy<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;SelectNonDefaults<>;(System.Data.IDbConnection,System.String,T);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;Single<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;Single<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;SqlColumn<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;SqlColumn<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;SqlColumn<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;SqlList<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;SqlList<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;SqlList<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;SqlList<>;(System.Data.IDbConnection,System.String,System.Action);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;SqlScalar<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;SqlScalar<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;SqlScalar<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;Column<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;Column<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;ColumnDistinct<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;ColumnDistinct<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;ColumnLazy<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApi;false;ColumnLazy<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable);;Argument[1];sql", + // OrmLiteReadExpressionsApi + "ServiceStack.OrmLite;OrmLiteReadExpressionsApi;false;RowCount;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadExpressionsApi;false;RowCount;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable);;Argument[1];sql", + // OrmLiteReadExpressionsApiAsync + "ServiceStack.OrmLite;OrmLiteReadExpressionsApiAsync;false;RowCountAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql", + // OrmLiteReadApiAsync + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ColumnAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ColumnAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ColumnDistinctAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ColumnDistinctAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;DictionaryAsync<,>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ExecuteNonQueryAsync;(System.Data.IDbConnection,System.String,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ExecuteNonQueryAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ExecuteNonQueryAsync;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ExistsAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;KeyValuePairsAsync<,>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;KeyValuePairsAsync<,>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;LookupAsync<,>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;LookupAsync<,>;(System.Data.IDbCommand,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;LookupAsync<,>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ScalarAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ScalarAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectAsync<>;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Threading.CancellationToken);;Argument[2];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectAsync<>;(System.Data.IDbConnection,System.String,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectNonDefaultsAsync<>;(System.Data.IDbConnection,System.String,T,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SingleAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SingleAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlColumnAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlColumnAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlColumnAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlListAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlListAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlListAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlListAsync<>;(System.Data.IDbConnection,System.String,System.Action,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlScalarAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlScalarAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlScalarAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql", + // Write API + "ServiceStack.OrmLite;OrmLiteWriteApi;false;ExecuteSql;(System.Data.IDbConnection,System.String);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteWriteApi;false;ExecuteSql;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteWriteApi;false;ExecuteSql;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteWriteApiAsync;false;ExecuteSqlAsync;(System.Data.IDbConnection,System.String,System.Threading.CancellationToken);;Argument[1];sql", + "ServiceStack.OrmLite;OrmLiteWriteApiAsync;false;ExecuteSqlAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql" + ] + } +} + +private class ServiceStackCodeInjectionSinkModelCsv extends SinkModelCsv { + override predicate row(string row) { + row = + [ + // Redis API + "ServiceStack.Redis;IRedisClient;true;Custom;(System.Object[]);;Argument[0];code", + "ServiceStack.Redis;IRedisClient;true;ExecCachedLua;(System.String,System.Func);;Argument[0];code", + "ServiceStack.Redis;IRedisClient;true;ExecLua;(System.String,System.String[],System.String[]);;Argument[0];code", + "ServiceStack.Redis;IRedisClient;true;ExecLua;(System.String,System.String[]);;Argument[0];code", + "ServiceStack.Redis;IRedisClient;true;ExecLuaAsInt;(System.String,System.String[],System.String[]);;Argument[0];code", + "ServiceStack.Redis;IRedisClient;true;ExecLuaAsInt;(System.String,System.String[]);;Argument[0];code", + "ServiceStack.Redis;IRedisClient;true;ExecLuaAsList;(System.String,System.String[],System.String[]);;Argument[0];code", + "ServiceStack.Redis;IRedisClient;true;ExecLuaAsList;(System.String,System.String[]);;Argument[0];code", + "ServiceStack.Redis;IRedisClient;true;ExecLuaAsString;(System.String,System.String[],System.String[]);;Argument[0];code", + "ServiceStack.Redis;IRedisClient;true;ExecLuaAsString;(System.String,System.String[]);;Argument[0];code", + "ServiceStack.Redis;IRedisClient;true;LoadLuaScript;(System.String);;Argument[0];code", + // IRedisClientAsync + "ServiceStack.Redis;IRedisClientAsync;true;CustomAsync;(System.Object[]);;Argument[0];code", + "ServiceStack.Redis;IRedisClientAsync;true;CustomAsync;(System.Object[],System.Threading.CancellationToken);;Element of Argument[0];code", + "ServiceStack.Redis;IRedisClientAsync;true;ExecCachedLuaAsync;(System.String,System.Func>,System.Threading.CancellationToken);;Argument[0];code", + "ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsync;(System.String,System.String[],System.String[],System.Threading.CancellationToken);;Argument[0];code", + "ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsync;(System.String,System.String[],System.Threading.CancellationToken);;Argument[0];code", + "ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsync;(System.String,System.String[]);;Argument[0];code", + "ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsIntAsync;(System.String,System.String[],System.String[],System.Threading.CancellationToken);;Argument[0];code", + "ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsIntAsync;(System.String,System.String[],System.Threading.CancellationToken);;Argument[0];code", + "ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsIntAsync;(System.String,System.String[]);;Argument[0];code", + "ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsStringAsync;(System.String,System.String[],System.String[],System.Threading.CancellationToken);;Argument[0];code", + "ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsStringAsync;(System.String,System.String[],System.Threading.CancellationToken);;Argument[0];code", + "ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsStringAsync;(System.String,System.String[]);;Argument[0];code", + "ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsListAsync;(System.String,System.String[],System.String[],System.Threading.CancellationToken);;Argument[0];code", + "ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsListAsync;(System.String,System.String[],System.Threading.CancellationToken);;Argument[0];code", + "ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsListAsync;(System.String,System.String[]);;Argument[0];code", + "ServiceStack.Redis;IRedisClientAsync;true;LoadLuaScriptAsync;(System.String,System.Threading.CancellationToken);;Argument[0];code" + ] + } +} + +private class ServiceStackXssSummaryModelCsv extends SummaryModelCsv { + override predicate row(string row) { + row = + [ + "ServiceStack;HttpResult;false;HttpResult;(System.String,System.String);;Argument[0];ReturnValue;taint", + "ServiceStack;HttpResult;false;HttpResult;(System.Object,System.String,System.Net.HttpStatusCode);;Argument[0];ReturnValue;taint", + "ServiceStack;HttpResult;false;HttpResult;(System.Object,System.String);;Argument[0];ReturnValue;taint", + "ServiceStack;HttpResult;false;HttpResult;(System.Object,System.Net.HttpStatusCode);;Argument[0];ReturnValue;taint", + "ServiceStack;HttpResult;false;HttpResult;(System.Object);;Argument[0];ReturnValue;taint", + "ServiceStack;HttpResult;false;HttpResult;(System.IO.Stream,System.String);;Argument[0];ReturnValue;taint", + "ServiceStack;HttpResult;false;HttpResult;(System.Byte[],System.String);;Argument[0];ReturnValue;taint" + ] + } +} + +/** XSS support for ServiceStack framework */ +module XSS { + private import semmle.code.csharp.security.dataflow.XSSSinks + + /** XSS sinks for ServiceStack */ + class XssSink extends Sink { + XssSink() { + exists(ServiceClass service, Method m, Expr e | + service.getARequestMethod() = m and + this.asExpr() = e and + m.canReturn(e) and + ( + e.getType() instanceof StringType or + e.getType().hasQualifiedName("ServiceStack", "HttpResult") + ) + ) + } + } +} diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll index 1a727030bea..78975527af6 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll @@ -7,6 +7,7 @@ private import semmle.code.csharp.frameworks.EntityFramework private import semmle.code.csharp.frameworks.NHibernate private import semmle.code.csharp.frameworks.Dapper private import semmle.code.csharp.dataflow.DataFlow4 +private import semmle.code.csharp.dataflow.ExternalFlow /** An expression containing a SQL command. */ abstract class SqlExpr extends Expr { @@ -28,71 +29,236 @@ class CommandTextAssignmentSqlExpr extends SqlExpr, AssignExpr { override Expr getSql() { result = this.getRValue() } } -/** A construction of an `IDbCommand` object. */ +/** A construction of an unknown `IDbCommand` object. */ class IDbCommandConstructionSqlExpr extends SqlExpr, ObjectCreation { IDbCommandConstructionSqlExpr() { exists(InstanceConstructor ic | ic = this.getTarget() | ic.getDeclaringType().getABaseType*() instanceof SystemDataIDbCommandInterface and - ic.getParameter(0).getType() instanceof StringType + ic.getParameter(0).getType() instanceof StringType and + not ic.getDeclaringType() + .hasQualifiedName([ + // Known sealed classes: + "System.Data.SqlClient.SqlCommand", "System.Data.Odbc.OdbcCommand", + "System.Data.OleDb.OleDbCommand", "System.Data.EntityClient.EntityCommand" + ]) ) } override Expr getSql() { result = this.getArgument(0) } } +/** A construction of a known `IDbCommand` object. */ +private class IDbCommandConstructionSinkModelCsv extends SinkModelCsv { + override predicate row(string row) { + row = + [ + // SqlCommand + "System.Data.SqlClient;SqlCommand;false;SqlCommand;(System.String);;Argument[0];sql", + "System.Data.SqlClient;SqlCommand;false;SqlCommand;(System.String,System.Data.SqlClient.SqlConnection);;Argument[0];sql", + "System.Data.SqlClient;SqlCommand;false;SqlCommand;(System.String,System.Data.SqlClient.SqlConnection,System.Data.SqlClient.SqlTransaction);;Argument[0];sql", + // OdbcCommand + "System.Data.Odbc;OdbcCommand;false;OdbcCommand;(System.String);;Argument[0];sql", + "System.Data.Odbc;OdbcCommand;false;OdbcCommand;(System.String,System.Data.Odbc.OdbcConnection);;Argument[0];sql", + "System.Data.Odbc;OdbcCommand;false;OdbcCommand;(System.String,System.Data.Odbc.OdbcConnection,System.Data.Odbc.OdbcTransaction);;Argument[0];sql", + // OleDbCommand + "System.Data.OleDb;OleDbCommand;false;OleDbCommand;(System.String);;Argument[0];sql", + "System.Data.OleDb;OleDbCommand;false;OleDbCommand;(System.String,System.Data.OleDb.OleDbConnection);;Argument[0];sql", + "System.Data.OleDb;OleDbCommand;false;OleDbCommand;(System.String,System.Data.OleDb.OleDbConnection,System.Data.OleDb.OleDbTransaction);;Argument[0];sql", + // EntityCommand + "System.Data.EntityClient;EntityCommand;false;EntityCommand;(System.String);;Argument[0];sql", + "System.Data.EntityClient;EntityCommand;false;EntityCommand;(System.String,System.Data.EntityClient.EntityConnection);;Argument[0];sql", + "System.Data.EntityClient;EntityCommand;false;EntityCommand;(System.String,System.Data.EntityClient.EntityConnection,System.Data.EntityClient.EntityTransaction);;Argument[0];sql" + ] + } +} + /** A construction of an `SqlDataAdapter` object. */ -class SqlDataAdapterConstructionSqlExpr extends SqlExpr, ObjectCreation { - SqlDataAdapterConstructionSqlExpr() { - exists(InstanceConstructor ic | - ic = this.getTarget() and - ic.getDeclaringType() instanceof SystemDataSqlClientSqlDataAdapterClass and - ic.getParameter(0).getType() instanceof StringType - ) +private class SqlDataAdapterConstructionSinkModelCsv extends SinkModelCsv { + override predicate row(string row) { + row = + [ + "System.Data.SqlClient;SqlDataAdapter;false;SqlDataAdapter;(System.String,System.String);;Argument[0];sql", + "System.Data.SqlClient;SqlDataAdapter;false;SqlDataAdapter;(System.String,System.Data.SqlClient.SqlConnection);;Argument[0];sql" + ] } - - override Expr getSql() { result = this.getArgument(0) } } /** A `MySql.Data.MySqlClient.MySqlHelper` method. */ -class MySqlHelperMethodCallSqlExpr extends SqlExpr, MethodCall { - MySqlHelperMethodCallSqlExpr() { - this.getQualifier().getType().(Class).hasQualifiedName("MySql.Data.MySqlClient", "MySqlHelper") - } - - override Expr getSql() { - exists(int i | - result = getArgument(i) and - this.getTarget().getParameter(i).hasName("commandText") and - this.getTarget().getParameter(i).getType() instanceof StringType - ) +private class MySqlHelperMethodCallSinkModelCsv extends SinkModelCsv { + override predicate row(string row) { + row = + [ + // ExecuteDataRow/Async + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDataRow;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDataRowAsync;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDataRowAsync;(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + // ExecuteDataset + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDataset;(System.String,System.String);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDataset;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDataset;(MySql.Data.MySqlClient.MySqlConnection,System.String);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDataset;(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + // ExecuteDatasetAsync + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDatasetAsync;(System.String,System.String);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDatasetAsync;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDatasetAsync;(System.String,System.String,System.Threading.CancellationToken);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDatasetAsync;(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDatasetAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDatasetAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDatasetAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDatasetAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + // ExecuteNonQuery + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteNonQuery;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteNonQuery;(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + // ExecuteNonQueryAsync + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteNonQueryAsync;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteNonQueryAsync;(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteNonQueryAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteNonQueryAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + // ExecuteReader + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReader;(System.String,System.String);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReader;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReader;(MySql.Data.MySqlClient.MySqlConnection,System.String);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReader;(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + // ExecuteReaderAsync + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReaderAsync;(System.String,System.String);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReaderAsync;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReaderAsync;(System.String,System.String,System.Threading.CancellationToken);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReaderAsync;(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReaderAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReaderAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReaderAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReaderAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + // ExecuteScalar + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalar;(System.String,System.String);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalar;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalar;(MySql.Data.MySqlClient.MySqlConnection,System.String);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalar;(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + // ExecuteScalarAsync + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalarAsync;(System.String,System.String);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalarAsync;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalarAsync;(System.String,System.String,System.Threading.CancellationToken);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalarAsync;(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalarAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalarAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalarAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalarAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql", + // UpdateDataset/Async + "MySql.Data.MySqlClient;MySqlHelper;false;UpdateDataset;(System.String,System.String,System.Data.DataSet,System.String);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;UpdateDatasetAsync;(System.String,System.String,System.Data.DataSet,System.String);;Argument[1];sql", + "MySql.Data.MySqlClient;MySqlHelper;false;UpdateDatasetAsync;(System.String,System.String,System.Data.DataSet,System.String,System.Threading.CancellationToken);;Argument[1];sql" + ] } } /** A `Microsoft.ApplicationBlocks.Data.SqlHelper` method. */ -class MicrosoftSqlHelperMethodCallSqlExpr extends SqlExpr, MethodCall { - MicrosoftSqlHelperMethodCallSqlExpr() { - this.getQualifier() - .getType() - .(Class) - .hasQualifiedName("Microsoft.ApplicationBlocks.Data", "SqlHelper") - } - - override Expr getSql() { - exists(int i | - result = getArgument(i) and - this.getTarget().getParameter(i).hasName("commandText") and - this.getTarget().getParameter(i).getType() instanceof StringType - ) +private class MicrosoftSqlHelperSinkModelCsv extends SinkModelCsv { + override predicate row(string row) { + row = + [ + // ExecuteNonQuery + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteNonQuery;(System.String,System.Data.CommandType,System.String);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteNonQuery;(System.String,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteNonQuery;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteNonQuery;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteNonQuery;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteNonQuery;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql", + // ExecuteDataset + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteDataset;(System.String,System.Data.CommandType,System.String);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteDataset;(System.String,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteDataset;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteDataset;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteDataset;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteDataset;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql", + // ExecuteReader + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteReader;(System.String,System.Data.CommandType,System.String);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteReader;(System.String,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteReader;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteReader;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteReader;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteReader;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql", + // ExecuteScalar + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteScalar;(System.String,System.Data.CommandType,System.String);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteScalar;(System.String,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteScalar;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteScalar;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteScalar;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteScalar;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql", + // ExecuteXmlReader + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteXmlReader;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteXmlReader;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteXmlReader;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String);;Argument[2];sql", + "Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteXmlReader;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql" + ] } } /** A `Dapper.SqlMapper` method that is taking a SQL string argument. */ -class DapperSqlMethodCallSqlExpr extends SqlExpr, MethodCall { - DapperSqlMethodCallSqlExpr() { - this.getTarget() = any(Dapper::SqlMapperClass c).getAQueryMethod() +private class DapperSqlMapperSinkModelCsv extends SinkModelCsv { + override predicate row(string row) { + row = + [ + // Execute* + "Dapper;SqlMapper;false;Execute;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;ExecuteAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;ExecuteScalar;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;ExecuteScalarAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;ExecuteScalar<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;ExecuteScalarAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;ExecuteReader;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;ExecuteReaderAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;ExecuteReaderAsync;(System.Data.DbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + // Query* + "Dapper;SqlMapper;false;Query;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Boolean,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;Query<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Boolean,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryMultiple;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryMultipleAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryFirst;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryFirstAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryFirst<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryFirstAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryFirstOrDefault;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryFirstOrDefaultAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryFirstOrDefault<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryFirstOrDefaultAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QuerySingle;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QuerySingleAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QuerySingle<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QuerySingleAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QuerySingleOrDefault;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QuerySingleOrDefaultAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QuerySingleOrDefault<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QuerySingleOrDefaultAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[1];sql", + // Query* with System.Type parameter + "Dapper;SqlMapper;false;Query;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Boolean,System.Nullable,System.Nullable);;Argument[2];sql", + "Dapper;SqlMapper;false;QueryAsync;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Boolean,System.Nullable,System.Nullable);;Argument[2];sql", + "Dapper;SqlMapper;false;QueryFirst;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[2];sql", + "Dapper;SqlMapper;false;QueryFirstAsync;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[2];sql", + "Dapper;SqlMapper;false;QueryFirstOrDefault;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[2];sql", + "Dapper;SqlMapper;false;QueryFirstOrDefaultAsync;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[2];sql", + "Dapper;SqlMapper;false;QuerySingle;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[2];sql", + "Dapper;SqlMapper;false;QuerySingleAsync;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[2];sql", + "Dapper;SqlMapper;false;QuerySingleOrDefault;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[2];sql", + "Dapper;SqlMapper;false;QuerySingleOrDefaultAsync;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable);;Argument[2];sql", + // Query with multiple type parameters + "Dapper;SqlMapper;false;Query<,,>;(System.Data.IDbConnection,System.String,System.Func,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryAsync<,,>;(System.Data.IDbConnection,System.String,System.Func,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;Query<,,,>;(System.Data.IDbConnection,System.String,System.Func,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryAsync<,,,>;(System.Data.IDbConnection,System.String,System.Func,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;Query<,,,,>;(System.Data.IDbConnection,System.String,System.Func,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryAsync<,,,,>;(System.Data.IDbConnection,System.String,System.Func,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;Query<,,,,,>;(System.Data.IDbConnection,System.String,System.Func,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryAsync<,,,,,>;(System.Data.IDbConnection,System.String,System.Func,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;Query<,,,,,,>;(System.Data.IDbConnection,System.String,System.Func,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryAsync<,,,,,,>;(System.Data.IDbConnection,System.String,System.Func,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;Query<,,,,,,,>;(System.Data.IDbConnection,System.String,System.Func,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryAsync<,,,,,,,>;(System.Data.IDbConnection,System.String,System.Func,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable,System.Nullable);;Argument[1];sql", + // Query with System.Type[] parameter + "Dapper;SqlMapper;false;Query<>;(System.Data.IDbConnection,System.String,System.Type[],System.Func,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable,System.Nullable);;Argument[1];sql", + "Dapper;SqlMapper;false;QueryAsync<>;(System.Data.IDbConnection,System.String,System.Type[],System.Func,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable,System.Nullable);;Argument[1];sql" + ] } - - override Expr getSql() { result = this.getArgumentForName("sql") } } /** A `Dapper.CommandDefinition` creation that is taking a SQL string argument and is passed to a `Dapper.SqlMapper` method. */ diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll index 39254fe6072..758fbf50b16 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll @@ -7,6 +7,7 @@ private import semmle.code.csharp.security.dataflow.flowsources.Remote private import semmle.code.csharp.security.dataflow.flowsources.Local private import semmle.code.csharp.frameworks.system.codedom.Compiler private import semmle.code.csharp.security.Sanitizers +private import semmle.code.csharp.dataflow.ExternalFlow /** * A data flow source for user input treated as code vulnerabilities. @@ -79,3 +80,8 @@ class RoslynCSharpScriptSink extends Sink { ) } } + +/** Code injection sinks defined through CSV models. */ +private class ExternalCodeInjectionExprSink extends Sink { + ExternalCodeInjectionExprSink() { sinkNode(this, "code") } +} diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll index 37b2d7fd7c3..f4184a391b9 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll @@ -7,6 +7,7 @@ private import semmle.code.csharp.security.dataflow.flowsources.Remote private import semmle.code.csharp.security.dataflow.flowsources.Local private import semmle.code.csharp.frameworks.Sql private import semmle.code.csharp.security.Sanitizers +private import semmle.code.csharp.dataflow.ExternalFlow /** * A source specific to SQL injection vulnerabilities. @@ -51,6 +52,11 @@ class SqlInjectionExprSink extends Sink { SqlInjectionExprSink() { exists(SqlExpr s | this.getExpr() = s.getSql()) } } +/** SQL sinks defined through CSV models. */ +private class ExternalSqlInjectionExprSink extends Sink { + ExternalSqlInjectionExprSink() { sinkNode(this, "sql") } +} + private class SimpleTypeSanitizer extends Sanitizer, SimpleTypeSanitizedExpr { } private class GuidSanitizer extends Sanitizer, GuidSanitizedExpr { } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSQuery.qll index 055726a7bc3..a216ce5e9d2 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSQuery.qll @@ -62,6 +62,16 @@ module PathGraph { key = "semmle.label" and val = n.(XssAspNode).toString() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + query predicate subpaths(XssNode arg, XssNode par, XssNode ret, XssNode out) { + DataFlow2::PathGraph::subpaths(arg.asDataFlowNode(), par.asDataFlowNode(), ret.asDataFlowNode(), + out.asDataFlowNode()) + } } private newtype TXssNode = diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSSinks.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSSinks.qll index 3d3858d974a..4be005be4de 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSSinks.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSSinks.qll @@ -10,6 +10,7 @@ private import semmle.code.csharp.frameworks.system.web.UI private import semmle.code.csharp.security.dataflow.flowsinks.Html private import semmle.code.csharp.security.dataflow.flowsinks.Remote private import semmle.code.csharp.dataflow.ExternalFlow +private import semmle.code.csharp.frameworks.ServiceStack::XSS /** * A data flow sink for cross-site scripting (XSS) vulnerabilities. diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ExternalLocationSink.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ExternalLocationSink.qll index 25a50f3733c..673473eb49b 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ExternalLocationSink.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ExternalLocationSink.qll @@ -6,6 +6,7 @@ import csharp private import Remote private import semmle.code.csharp.commons.Loggers private import semmle.code.csharp.frameworks.system.Web +private import semmle.code.csharp.dataflow.ExternalFlow /** * An external location sink. @@ -16,6 +17,10 @@ private import semmle.code.csharp.frameworks.system.Web */ abstract class ExternalLocationSink extends DataFlow::ExprNode { } +private class ExternalModelSink extends ExternalLocationSink { + ExternalModelSink() { sinkNode(this, "remote") } +} + /** * An argument to a call to a method on a logger class. */ diff --git a/csharp/ql/lib/semmlecode.csharp.dbscheme b/csharp/ql/lib/semmlecode.csharp.dbscheme index 0f562410898..73b4f980116 100644 --- a/csharp/ql/lib/semmlecode.csharp.dbscheme +++ b/csharp/ql/lib/semmlecode.csharp.dbscheme @@ -276,22 +276,13 @@ assemblies( string name: string ref, string version: string ref); -/* - fromSource(0) = unknown, - fromSource(1) = from source, - fromSource(2) = from library -*/ files( unique int id: @file, - string name: string ref, - string simple: string ref, - string ext: string ref, - int fromSource: int ref); + string name: string ref); folders( unique int id: @folder, - string name: string ref, - string simple: string ref); + string name: string ref); @container = @folder | @file ; diff --git a/csharp/ql/lib/semmlecode.csharp.dbscheme.stats b/csharp/ql/lib/semmlecode.csharp.dbscheme.stats index f1fbd130ff8..a192af2bce3 100644 --- a/csharp/ql/lib/semmlecode.csharp.dbscheme.stats +++ b/csharp/ql/lib/semmlecode.csharp.dbscheme.stats @@ -11522,18 +11522,6 @@ name 47336 - -simple -26591 - - -ext -43 - - -fromSource -4 - @@ -11553,54 +11541,6 @@ -id -simple - - -12 - - -1 -2 -47336 - - - - - - -id -ext - - -12 - - -1 -2 -47336 - - - - - - -id -fromSource - - -12 - - -1 -2 -47336 - - - - - - name id @@ -11616,376 +11556,6 @@ - -name -simple - - -12 - - -1 -2 -47336 - - - - - - -name -ext - - -12 - - -1 -2 -47336 - - - - - - -name -fromSource - - -12 - - -1 -2 -47336 - - - - - - -simple -id - - -12 - - -1 -2 -24857 - - -2 -154 -1734 - - - - - - -simple -name - - -12 - - -1 -2 -24857 - - -2 -154 -1734 - - - - - - -simple -ext - - -12 - - -1 -2 -25597 - - -2 -5 -994 - - - - - - -simple -fromSource - - -12 - - -1 -2 -26591 - - - - - - -ext -id - - -12 - - -1 -2 -4 - - -2 -3 -4 - - -6 -7 -4 - - -166 -167 -4 - - -173 -174 -4 - - -861 -862 -4 - - -995 -996 -4 - - -2875 -2876 -4 - - -4635 -4636 -4 - - - - - - -ext -name - - -12 - - -1 -2 -4 - - -2 -3 -4 - - -6 -7 -4 - - -166 -167 -4 - - -173 -174 -4 - - -861 -862 -4 - - -995 -996 -4 - - -2875 -2876 -4 - - -4635 -4636 -4 - - - - - - -ext -simple - - -12 - - -1 -2 -4 - - -2 -3 -9 - - -166 -167 -4 - - -169 -170 -4 - - -214 -215 -4 - - -650 -651 -4 - - -790 -791 -4 - - -3818 -3819 -4 - - - - - - -ext -fromSource - - -12 - - -1 -2 -43 - - - - - - -fromSource -id - - -12 - - -9714 -9715 -4 - - - - - - -fromSource -name - - -12 - - -9714 -9715 -4 - - - - - - -fromSource -simple - - -12 - - -5457 -5458 -4 - - - - - - -fromSource -ext - - -12 - - -9 -10 -4 - - - - - @@ -12000,10 +11570,6 @@ name 15622 - -simple -2777 - @@ -12023,22 +11589,6 @@ -id -simple - - -12 - - -1 -2 -17839 - - - - - - name id @@ -12054,99 +11604,6 @@ - -name -simple - - -12 - - -1 -2 -13405 - - -2 -3 -2217 - - - - - - -simple -id - - -12 - - -1 -2 -1637 - - -2 -3 -540 - - -3 -4 -209 - - -4 -10 -209 - - -10 -383 -180 - - - - - - -simple -name - - -12 - - -1 -2 -1637 - - -2 -3 -540 - - -3 -4 -209 - - -4 -10 -209 - - -10 -383 -180 - - - - - diff --git a/csharp/ql/src/AlertSuppression.ql b/csharp/ql/src/AlertSuppression.ql index 1467731809b..3cb6d759b6e 100644 --- a/csharp/ql/src/AlertSuppression.ql +++ b/csharp/ql/src/AlertSuppression.ql @@ -55,7 +55,7 @@ class SuppressionScope extends @commentline { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql b/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql index 0b4f4fd99b8..a0542a94735 100644 --- a/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql +++ b/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql @@ -123,6 +123,8 @@ class ConstantMatchingCondition extends ConstantCondition { se.getCase(i).getPattern() = this.(DiscardExpr) and i > 0 ) + or + this = any(PositionalPatternExpr ppe).getPattern(_) } override string getMessage() { diff --git a/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql b/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql index 1064a76c2e0..19766a550ec 100644 --- a/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql +++ b/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql @@ -72,7 +72,8 @@ predicate mayEscape(LocalVariable v) { class RelevantDefinition extends AssignableDefinition { RelevantDefinition() { - this instanceof AssignableDefinitions::AssignmentDefinition + this.(AssignableDefinitions::AssignmentDefinition).getAssignment() = + any(Assignment a | not a = any(UsingDeclStmt uds).getAVariableDeclExpr()) or this instanceof AssignableDefinitions::MutationDefinition or diff --git a/csharp/ql/src/definitions.qll b/csharp/ql/src/definitions.qll index ade40435e18..559bc0d3908 100644 --- a/csharp/ql/src/definitions.qll +++ b/csharp/ql/src/definitions.qll @@ -13,7 +13,7 @@ abstract class Use extends @type_mention_parent { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll index 453838215ff..6f471d8a7e8 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll @@ -821,7 +821,7 @@ class ReturnIndirectionInstruction extends VariableInstruction { * * There are several different copy instructions, depending on the source and destination of the * copy operation: - * - `CopyInstruction` - Copies a register operand to a register result. + * - `CopyValueInstruction` - Copies a register operand to a register result. * - `LoadInstruction` - Copies a memory operand to a register result. * - `StoreInstruction` - Copies a register operand to a memory result. */ @@ -1856,12 +1856,12 @@ class InitializeDynamicAllocationInstruction extends SideEffectInstruction { } /** - * Gets the address of the allocation this instruction is initializing. + * Gets the operand that represents the address of the allocation this instruction is initializing. */ final AddressOperand getAllocationAddressOperand() { result = getAnOperand() } /** - * Gets the operand for the allocation this instruction is initializing. + * Gets the address for the allocation this instruction is initializing. */ final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() } } diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll index 453838215ff..6f471d8a7e8 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll @@ -821,7 +821,7 @@ class ReturnIndirectionInstruction extends VariableInstruction { * * There are several different copy instructions, depending on the source and destination of the * copy operation: - * - `CopyInstruction` - Copies a register operand to a register result. + * - `CopyValueInstruction` - Copies a register operand to a register result. * - `LoadInstruction` - Copies a memory operand to a register result. * - `StoreInstruction` - Copies a register operand to a memory result. */ @@ -1856,12 +1856,12 @@ class InitializeDynamicAllocationInstruction extends SideEffectInstruction { } /** - * Gets the address of the allocation this instruction is initializing. + * Gets the operand that represents the address of the allocation this instruction is initializing. */ final AddressOperand getAllocationAddressOperand() { result = getAnOperand() } /** - * Gets the operand for the allocation this instruction is initializing. + * Gets the address for the allocation this instruction is initializing. */ final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() } } diff --git a/csharp/ql/test/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.expected b/csharp/ql/test/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.expected index 58e3dda0964..e217064d1df 100644 --- a/csharp/ql/test/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.expected +++ b/csharp/ql/test/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.expected @@ -1,3 +1,4 @@ edges nodes +subpaths #select diff --git a/csharp/ql/test/library-tests/cil/dataflow/DataFlow.expected b/csharp/ql/test/library-tests/cil/dataflow/DataFlow.expected index 36dce892092..b85301eb52a 100644 --- a/csharp/ql/test/library-tests/cil/dataflow/DataFlow.expected +++ b/csharp/ql/test/library-tests/cil/dataflow/DataFlow.expected @@ -1,4 +1,23 @@ edges +| DataFlow.dll:0:0:0:0 | Parameter 1 of Taint1 : String | DataFlow.dll:0:0:0:0 | ldarg.1 : String | +| DataFlow.dll:0:0:0:0 | Parameter 1 of Taint1 : String | DataFlow.dll:0:0:0:0 | ldarg.1 : String | +| DataFlow.dll:0:0:0:0 | Parameter 1 of Taint2 : String | DataFlow.dll:0:0:0:0 | ldarg.1 : String | +| DataFlow.dll:0:0:0:0 | Parameter 1 of Taint3 : String | DataFlow.dll:0:0:0:0 | ldarg.1 : String | +| DataFlow.dll:0:0:0:0 | Parameter 1 of Taint5 : String | DataFlow.dll:0:0:0:0 | ldarg.1 : String | +| DataFlow.dll:0:0:0:0 | Parameter 1 of Taint6 : String | DataFlow.dll:0:0:0:0 | ldarg.1 : String | +| DataFlow.dll:0:0:0:0 | Parameter 1 of TaintIndirect : String | DataFlow.dll:0:0:0:0 | ldarg.1 : String | +| DataFlow.dll:0:0:0:0 | Parameter 2 of Taint1 : String | DataFlow.dll:0:0:0:0 | ldarg.2 : String | +| DataFlow.dll:0:0:0:0 | Parameter 2 of TaintIndirect : String | DataFlow.dll:0:0:0:0 | ldarg.2 : String | +| DataFlow.dll:0:0:0:0 | ldarg.1 : String | DataFlow.dll:0:0:0:0 | Parameter 1 of Taint1 : String | +| DataFlow.dll:0:0:0:0 | ldarg.1 : String | DataFlow.dll:0:0:0:0 | Parameter 1 of Taint5 : String | +| DataFlow.dll:0:0:0:0 | ldarg.1 : String | DataFlow.dll:0:0:0:0 | Parameter 1 of Taint6 : String | +| DataFlow.dll:0:0:0:0 | ldarg.1 : String | DataFlow.dll:0:0:0:0 | call : String | +| DataFlow.dll:0:0:0:0 | ldarg.1 : String | DataFlow.dll:0:0:0:0 | call : String | +| DataFlow.dll:0:0:0:0 | ldarg.1 : String | DataFlow.dll:0:0:0:0 | call : String | +| DataFlow.dll:0:0:0:0 | ldarg.1 : String | DataFlow.dll:0:0:0:0 | call : String | +| DataFlow.dll:0:0:0:0 | ldarg.2 : String | DataFlow.dll:0:0:0:0 | Parameter 2 of Taint1 : String | +| DataFlow.dll:0:0:0:0 | ldarg.2 : String | DataFlow.dll:0:0:0:0 | call : String | +| DataFlow.dll:0:0:0:0 | ldarg.2 : String | DataFlow.dll:0:0:0:0 | call : String | | dataflow.cs:16:18:16:26 | "tainted" : String | dataflow.cs:16:18:16:37 | call to method ToString | | dataflow.cs:18:27:18:27 | 2 : Int32 | dataflow.cs:18:18:18:31 | call to method Max | | dataflow.cs:18:30:18:30 | 3 : Int32 | dataflow.cs:18:18:18:31 | call to method Max | @@ -6,12 +25,19 @@ edges | dataflow.cs:20:45:20:53 | "tainted" : String | dataflow.cs:20:18:20:54 | call to method GetFullPath | | dataflow.cs:27:44:27:46 | 1 : Double | dataflow.cs:27:18:27:52 | call to method IEEERemainder | | dataflow.cs:27:49:27:51 | 2 : Double | dataflow.cs:27:18:27:52 | call to method IEEERemainder | +| dataflow.cs:38:34:38:37 | "d1" : String | DataFlow.dll:0:0:0:0 | Parameter 1 of Taint1 : String | | dataflow.cs:38:34:38:37 | "d1" : String | dataflow.cs:38:18:38:38 | call to method Taint1 | +| dataflow.cs:39:34:39:37 | "d2" : String | DataFlow.dll:0:0:0:0 | Parameter 1 of Taint2 : String | | dataflow.cs:39:34:39:37 | "d2" : String | dataflow.cs:39:18:39:38 | call to method Taint2 | +| dataflow.cs:40:34:40:37 | "d3" : String | DataFlow.dll:0:0:0:0 | Parameter 1 of Taint3 : String | | dataflow.cs:40:34:40:37 | "d3" : String | dataflow.cs:40:18:40:38 | call to method Taint3 | +| dataflow.cs:44:28:44:32 | "t1a" : String | DataFlow.dll:0:0:0:0 | Parameter 1 of Taint1 : String | | dataflow.cs:44:28:44:32 | "t1a" : String | dataflow.cs:44:18:44:40 | call to method Taint1 | +| dataflow.cs:44:35:44:39 | "t1b" : String | DataFlow.dll:0:0:0:0 | Parameter 2 of Taint1 : String | | dataflow.cs:44:35:44:39 | "t1b" : String | dataflow.cs:44:18:44:40 | call to method Taint1 | +| dataflow.cs:47:35:47:38 | "t6" : String | DataFlow.dll:0:0:0:0 | Parameter 1 of TaintIndirect : String | | dataflow.cs:47:35:47:38 | "t6" : String | dataflow.cs:47:18:47:45 | call to method TaintIndirect | +| dataflow.cs:47:41:47:44 | "t6" : String | DataFlow.dll:0:0:0:0 | Parameter 2 of TaintIndirect : String | | dataflow.cs:47:41:47:44 | "t6" : String | dataflow.cs:47:18:47:45 | call to method TaintIndirect | | dataflow.cs:72:21:72:34 | call to method NullFunction : null | dataflow.cs:72:21:72:52 | ... ?? ... | | dataflow.cs:72:39:72:52 | call to method IndirectNull : null | dataflow.cs:72:21:72:52 | ... ?? ... | @@ -24,6 +50,30 @@ edges | dataflow.cs:108:16:108:16 | access to local variable x : null | dataflow.cs:72:21:72:34 | call to method NullFunction : null | | dataflow.cs:108:16:108:16 | access to local variable x : null | dataflow.cs:87:31:87:44 | call to method NullFunction : null | nodes +| DataFlow.dll:0:0:0:0 | Parameter 1 of Taint1 : String | semmle.label | Parameter 1 of Taint1 : String | +| DataFlow.dll:0:0:0:0 | Parameter 1 of Taint1 : String | semmle.label | Parameter 1 of Taint1 : String | +| DataFlow.dll:0:0:0:0 | Parameter 1 of Taint2 : String | semmle.label | Parameter 1 of Taint2 : String | +| DataFlow.dll:0:0:0:0 | Parameter 1 of Taint3 : String | semmle.label | Parameter 1 of Taint3 : String | +| DataFlow.dll:0:0:0:0 | Parameter 1 of Taint5 : String | semmle.label | Parameter 1 of Taint5 : String | +| DataFlow.dll:0:0:0:0 | Parameter 1 of Taint6 : String | semmle.label | Parameter 1 of Taint6 : String | +| DataFlow.dll:0:0:0:0 | Parameter 1 of TaintIndirect : String | semmle.label | Parameter 1 of TaintIndirect : String | +| DataFlow.dll:0:0:0:0 | Parameter 2 of Taint1 : String | semmle.label | Parameter 2 of Taint1 : String | +| DataFlow.dll:0:0:0:0 | Parameter 2 of TaintIndirect : String | semmle.label | Parameter 2 of TaintIndirect : String | +| DataFlow.dll:0:0:0:0 | call : String | semmle.label | call : String | +| DataFlow.dll:0:0:0:0 | call : String | semmle.label | call : String | +| DataFlow.dll:0:0:0:0 | call : String | semmle.label | call : String | +| DataFlow.dll:0:0:0:0 | call : String | semmle.label | call : String | +| DataFlow.dll:0:0:0:0 | call : String | semmle.label | call : String | +| DataFlow.dll:0:0:0:0 | call : String | semmle.label | call : String | +| DataFlow.dll:0:0:0:0 | ldarg.1 : String | semmle.label | ldarg.1 : String | +| DataFlow.dll:0:0:0:0 | ldarg.1 : String | semmle.label | ldarg.1 : String | +| DataFlow.dll:0:0:0:0 | ldarg.1 : String | semmle.label | ldarg.1 : String | +| DataFlow.dll:0:0:0:0 | ldarg.1 : String | semmle.label | ldarg.1 : String | +| DataFlow.dll:0:0:0:0 | ldarg.1 : String | semmle.label | ldarg.1 : String | +| DataFlow.dll:0:0:0:0 | ldarg.1 : String | semmle.label | ldarg.1 : String | +| DataFlow.dll:0:0:0:0 | ldarg.1 : String | semmle.label | ldarg.1 : String | +| DataFlow.dll:0:0:0:0 | ldarg.2 : String | semmle.label | ldarg.2 : String | +| DataFlow.dll:0:0:0:0 | ldarg.2 : String | semmle.label | ldarg.2 : String | | dataflow.cs:16:18:16:26 | "tainted" : String | semmle.label | "tainted" : String | | dataflow.cs:16:18:16:37 | call to method ToString | semmle.label | call to method ToString | | dataflow.cs:18:18:18:31 | call to method Max | semmle.label | call to method Max | @@ -58,6 +108,18 @@ nodes | dataflow.cs:106:20:106:33 | call to method IndirectNull : null | semmle.label | call to method IndirectNull : null | | dataflow.cs:107:23:107:26 | null : null | semmle.label | null : null | | dataflow.cs:108:16:108:16 | access to local variable x : null | semmle.label | access to local variable x : null | +subpaths +| DataFlow.dll:0:0:0:0 | ldarg.1 : String | DataFlow.dll:0:0:0:0 | Parameter 1 of Taint1 : String | DataFlow.dll:0:0:0:0 | call : String | DataFlow.dll:0:0:0:0 | call : String | +| DataFlow.dll:0:0:0:0 | ldarg.1 : String | DataFlow.dll:0:0:0:0 | Parameter 1 of Taint5 : String | DataFlow.dll:0:0:0:0 | call : String | DataFlow.dll:0:0:0:0 | call : String | +| DataFlow.dll:0:0:0:0 | ldarg.1 : String | DataFlow.dll:0:0:0:0 | Parameter 1 of Taint6 : String | DataFlow.dll:0:0:0:0 | ldarg.1 : String | DataFlow.dll:0:0:0:0 | call : String | +| DataFlow.dll:0:0:0:0 | ldarg.2 : String | DataFlow.dll:0:0:0:0 | Parameter 2 of Taint1 : String | DataFlow.dll:0:0:0:0 | call : String | DataFlow.dll:0:0:0:0 | call : String | +| dataflow.cs:38:34:38:37 | "d1" : String | DataFlow.dll:0:0:0:0 | Parameter 1 of Taint1 : String | DataFlow.dll:0:0:0:0 | ldarg.1 : String | dataflow.cs:38:18:38:38 | call to method Taint1 : String | +| dataflow.cs:39:34:39:37 | "d2" : String | DataFlow.dll:0:0:0:0 | Parameter 1 of Taint2 : String | DataFlow.dll:0:0:0:0 | call : String | dataflow.cs:39:18:39:38 | call to method Taint2 : String | +| dataflow.cs:40:34:40:37 | "d3" : String | DataFlow.dll:0:0:0:0 | Parameter 1 of Taint3 : String | DataFlow.dll:0:0:0:0 | ldarg.1 : String | dataflow.cs:40:18:40:38 | call to method Taint3 : String | +| dataflow.cs:44:28:44:32 | "t1a" : String | DataFlow.dll:0:0:0:0 | Parameter 1 of Taint1 : String | DataFlow.dll:0:0:0:0 | call : String | dataflow.cs:44:18:44:40 | call to method Taint1 : String | +| dataflow.cs:44:35:44:39 | "t1b" : String | DataFlow.dll:0:0:0:0 | Parameter 2 of Taint1 : String | DataFlow.dll:0:0:0:0 | call : String | dataflow.cs:44:18:44:40 | call to method Taint1 : String | +| dataflow.cs:47:35:47:38 | "t6" : String | DataFlow.dll:0:0:0:0 | Parameter 1 of TaintIndirect : String | DataFlow.dll:0:0:0:0 | call : String | dataflow.cs:47:18:47:45 | call to method TaintIndirect : String | +| dataflow.cs:47:41:47:44 | "t6" : String | DataFlow.dll:0:0:0:0 | Parameter 2 of TaintIndirect : String | DataFlow.dll:0:0:0:0 | call : String | dataflow.cs:47:18:47:45 | call to method TaintIndirect : String | #select | dataflow.cs:16:18:16:26 | "tainted" : String | dataflow.cs:16:18:16:37 | call to method ToString | dataflow.cs:16:18:16:37 | call to method ToString | $@ | dataflow.cs:16:18:16:37 | call to method ToString | call to method ToString | | dataflow.cs:18:27:18:27 | 2 : Int32 | dataflow.cs:18:18:18:31 | call to method Max | dataflow.cs:18:18:18:31 | call to method Max | $@ | dataflow.cs:18:18:18:31 | call to method Max | call to method Max | diff --git a/csharp/ql/test/library-tests/cil/dataflow/DataFlow.ql b/csharp/ql/test/library-tests/cil/dataflow/DataFlow.ql index 676efa29df8..001b91901f6 100644 --- a/csharp/ql/test/library-tests/cil/dataflow/DataFlow.ql +++ b/csharp/ql/test/library-tests/cil/dataflow/DataFlow.ql @@ -4,7 +4,33 @@ import csharp import DataFlow -import DataFlow::PathGraph + +private predicate relevantPathNode(PathNode n) { + exists(File f | f = n.getNode().getLocation().getFile() | + f.fromSource() + or + f.getBaseName() = "DataFlow.dll" + ) +} + +query predicate edges(PathNode a, PathNode b) { + PathGraph::edges(a, b) and + relevantPathNode(a) and + relevantPathNode(b) +} + +query predicate nodes(PathNode n, string key, string val) { + PathGraph::nodes(n, key, val) and + relevantPathNode(n) +} + +query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) { + PathGraph::subpaths(arg, par, ret, out) and + relevantPathNode(arg) and + relevantPathNode(par) and + relevantPathNode(ret) and + relevantPathNode(out) +} class FlowConfig extends Configuration { FlowConfig() { this = "FlowConfig" } @@ -16,6 +42,6 @@ class FlowConfig extends Configuration { } } -from DataFlow::PathNode source, DataFlow::PathNode sink, FlowConfig config +from PathNode source, PathNode sink, FlowConfig config where config.hasFlowPath(source, sink) select source, sink, sink, "$@", sink, sink.toString() diff --git a/csharp/ql/test/library-tests/csharp7/GlobalFlow.expected b/csharp/ql/test/library-tests/csharp7/GlobalFlow.expected index 68c4963db45..12f1c5edecd 100644 --- a/csharp/ql/test/library-tests/csharp7/GlobalFlow.expected +++ b/csharp/ql/test/library-tests/csharp7/GlobalFlow.expected @@ -1,25 +1,41 @@ edges | CSharp7.cs:39:9:39:21 | SSA def(x) : String | CSharp7.cs:49:22:49:23 | SSA def(t1) : String | | CSharp7.cs:39:13:39:21 | "tainted" : String | CSharp7.cs:39:9:39:21 | SSA def(x) : String | +| CSharp7.cs:42:19:42:19 | x : String | CSharp7.cs:44:9:44:13 | SSA def(y) : String | | CSharp7.cs:49:22:49:23 | SSA def(t1) : String | CSharp7.cs:51:18:51:19 | access to local variable t1 | +| CSharp7.cs:55:11:55:19 | "tainted" : String | CSharp7.cs:42:19:42:19 | x : String | | CSharp7.cs:55:11:55:19 | "tainted" : String | CSharp7.cs:55:30:55:31 | SSA def(t4) : String | | CSharp7.cs:55:30:55:31 | SSA def(t4) : String | CSharp7.cs:56:18:56:19 | access to local variable t4 | +| CSharp7.cs:80:21:80:21 | x : String | CSharp7.cs:82:20:82:20 | access to parameter x : String | +| CSharp7.cs:82:16:82:24 | (..., ...) [field Item1] : String | CSharp7.cs:82:16:82:26 | access to field Item1 : String | +| CSharp7.cs:82:20:82:20 | access to parameter x : String | CSharp7.cs:82:16:82:24 | (..., ...) [field Item1] : String | | CSharp7.cs:87:18:87:34 | (..., ...) [field Item1] : String | CSharp7.cs:90:20:90:21 | access to local variable t1 [field Item1] : String | | CSharp7.cs:87:19:87:27 | "tainted" : String | CSharp7.cs:87:18:87:34 | (..., ...) [field Item1] : String | | CSharp7.cs:90:20:90:21 | access to local variable t1 [field Item1] : String | CSharp7.cs:90:20:90:27 | access to field Item1 : String | +| CSharp7.cs:90:20:90:27 | access to field Item1 : String | CSharp7.cs:80:21:80:21 | x : String | | CSharp7.cs:90:20:90:27 | access to field Item1 : String | CSharp7.cs:90:18:90:28 | call to method I | | CSharp7.cs:175:22:175:30 | "tainted" : String | CSharp7.cs:181:23:181:25 | access to local variable src : String | | CSharp7.cs:175:22:175:30 | "tainted" : String | CSharp7.cs:182:23:182:25 | access to local variable src : String | +| CSharp7.cs:177:25:177:25 | s : String | CSharp7.cs:177:31:177:31 | access to parameter s : String | +| CSharp7.cs:178:25:178:25 | s : String | CSharp7.cs:178:37:178:37 | access to parameter s : String | +| CSharp7.cs:181:23:181:25 | access to local variable src : String | CSharp7.cs:177:25:177:25 | s : String | | CSharp7.cs:181:23:181:25 | access to local variable src : String | CSharp7.cs:181:21:181:26 | call to local function g | +| CSharp7.cs:182:23:182:25 | access to local variable src : String | CSharp7.cs:178:25:178:25 | s : String | | CSharp7.cs:182:23:182:25 | access to local variable src : String | CSharp7.cs:182:21:182:26 | call to local function h | nodes | CSharp7.cs:39:9:39:21 | SSA def(x) : String | semmle.label | SSA def(x) : String | | CSharp7.cs:39:13:39:21 | "tainted" : String | semmle.label | "tainted" : String | +| CSharp7.cs:42:19:42:19 | x : String | semmle.label | x : String | +| CSharp7.cs:44:9:44:13 | SSA def(y) : String | semmle.label | SSA def(y) : String | | CSharp7.cs:49:22:49:23 | SSA def(t1) : String | semmle.label | SSA def(t1) : String | | CSharp7.cs:51:18:51:19 | access to local variable t1 | semmle.label | access to local variable t1 | | CSharp7.cs:55:11:55:19 | "tainted" : String | semmle.label | "tainted" : String | | CSharp7.cs:55:30:55:31 | SSA def(t4) : String | semmle.label | SSA def(t4) : String | | CSharp7.cs:56:18:56:19 | access to local variable t4 | semmle.label | access to local variable t4 | +| CSharp7.cs:80:21:80:21 | x : String | semmle.label | x : String | +| CSharp7.cs:82:16:82:24 | (..., ...) [field Item1] : String | semmle.label | (..., ...) [field Item1] : String | +| CSharp7.cs:82:16:82:26 | access to field Item1 : String | semmle.label | access to field Item1 : String | +| CSharp7.cs:82:20:82:20 | access to parameter x : String | semmle.label | access to parameter x : String | | CSharp7.cs:87:18:87:34 | (..., ...) [field Item1] : String | semmle.label | (..., ...) [field Item1] : String | | CSharp7.cs:87:19:87:27 | "tainted" : String | semmle.label | "tainted" : String | | CSharp7.cs:90:18:90:28 | call to method I | semmle.label | call to method I | @@ -27,10 +43,19 @@ nodes | CSharp7.cs:90:20:90:27 | access to field Item1 : String | semmle.label | access to field Item1 : String | | CSharp7.cs:175:22:175:30 | "tainted" | semmle.label | "tainted" | | CSharp7.cs:175:22:175:30 | "tainted" : String | semmle.label | "tainted" : String | +| CSharp7.cs:177:25:177:25 | s : String | semmle.label | s : String | +| CSharp7.cs:177:31:177:31 | access to parameter s : String | semmle.label | access to parameter s : String | +| CSharp7.cs:178:25:178:25 | s : String | semmle.label | s : String | +| CSharp7.cs:178:37:178:37 | access to parameter s : String | semmle.label | access to parameter s : String | | CSharp7.cs:181:21:181:26 | call to local function g | semmle.label | call to local function g | | CSharp7.cs:181:23:181:25 | access to local variable src : String | semmle.label | access to local variable src : String | | CSharp7.cs:182:21:182:26 | call to local function h | semmle.label | call to local function h | | CSharp7.cs:182:23:182:25 | access to local variable src : String | semmle.label | access to local variable src : String | +subpaths +| CSharp7.cs:55:11:55:19 | "tainted" : String | CSharp7.cs:42:19:42:19 | x : String | CSharp7.cs:44:9:44:13 | SSA def(y) : String | CSharp7.cs:55:30:55:31 | SSA def(t4) : String | +| CSharp7.cs:90:20:90:27 | access to field Item1 : String | CSharp7.cs:80:21:80:21 | x : String | CSharp7.cs:82:16:82:26 | access to field Item1 : String | CSharp7.cs:90:18:90:28 | call to method I : String | +| CSharp7.cs:181:23:181:25 | access to local variable src : String | CSharp7.cs:177:25:177:25 | s : String | CSharp7.cs:177:31:177:31 | access to parameter s : String | CSharp7.cs:181:21:181:26 | call to local function g : String | +| CSharp7.cs:182:23:182:25 | access to local variable src : String | CSharp7.cs:178:25:178:25 | s : String | CSharp7.cs:178:37:178:37 | access to parameter s : String | CSharp7.cs:182:21:182:26 | call to local function h : String | #select | CSharp7.cs:39:13:39:21 | "tainted" : String | CSharp7.cs:39:13:39:21 | "tainted" : String | CSharp7.cs:51:18:51:19 | access to local variable t1 | $@ | CSharp7.cs:51:18:51:19 | access to local variable t1 | access to local variable t1 | | CSharp7.cs:55:11:55:19 | "tainted" : String | CSharp7.cs:55:11:55:19 | "tainted" : String | CSharp7.cs:56:18:56:19 | access to local variable t4 | $@ | CSharp7.cs:56:18:56:19 | access to local variable t4 | access to local variable t4 | diff --git a/csharp/ql/test/library-tests/csharp7/GlobalTaintTracking.expected b/csharp/ql/test/library-tests/csharp7/GlobalTaintTracking.expected index 26c34a6483d..7e0632be14a 100644 --- a/csharp/ql/test/library-tests/csharp7/GlobalTaintTracking.expected +++ b/csharp/ql/test/library-tests/csharp7/GlobalTaintTracking.expected @@ -1,27 +1,48 @@ edges | CSharp7.cs:39:9:39:21 | SSA def(x) : String | CSharp7.cs:49:22:49:23 | SSA def(t1) : String | | CSharp7.cs:39:13:39:21 | "tainted" : String | CSharp7.cs:39:9:39:21 | SSA def(x) : String | +| CSharp7.cs:42:19:42:19 | x : String | CSharp7.cs:44:9:44:13 | SSA def(y) : String | | CSharp7.cs:49:22:49:23 | SSA def(t1) : String | CSharp7.cs:51:18:51:19 | access to local variable t1 | +| CSharp7.cs:55:11:55:19 | "tainted" : String | CSharp7.cs:42:19:42:19 | x : String | | CSharp7.cs:55:11:55:19 | "tainted" : String | CSharp7.cs:55:30:55:31 | SSA def(t4) : String | | CSharp7.cs:55:30:55:31 | SSA def(t4) : String | CSharp7.cs:56:18:56:19 | access to local variable t4 | +| CSharp7.cs:80:21:80:21 | x : String | CSharp7.cs:82:20:82:20 | access to parameter x : String | +| CSharp7.cs:82:16:82:24 | (..., ...) [field Item1] : String | CSharp7.cs:82:16:82:26 | access to field Item1 : String | +| CSharp7.cs:82:20:82:20 | access to parameter x : String | CSharp7.cs:82:16:82:24 | (..., ...) [field Item1] : String | | CSharp7.cs:87:18:87:34 | (..., ...) [field Item1] : String | CSharp7.cs:90:20:90:21 | access to local variable t1 [field Item1] : String | | CSharp7.cs:87:19:87:27 | "tainted" : String | CSharp7.cs:87:18:87:34 | (..., ...) [field Item1] : String | | CSharp7.cs:90:20:90:21 | access to local variable t1 [field Item1] : String | CSharp7.cs:90:20:90:27 | access to field Item1 : String | +| CSharp7.cs:90:20:90:27 | access to field Item1 : String | CSharp7.cs:80:21:80:21 | x : String | | CSharp7.cs:90:20:90:27 | access to field Item1 : String | CSharp7.cs:90:18:90:28 | call to method I | | CSharp7.cs:175:22:175:30 | "tainted" : String | CSharp7.cs:180:23:180:25 | access to local variable src : String | | CSharp7.cs:175:22:175:30 | "tainted" : String | CSharp7.cs:181:23:181:25 | access to local variable src : String | | CSharp7.cs:175:22:175:30 | "tainted" : String | CSharp7.cs:182:23:182:25 | access to local variable src : String | +| CSharp7.cs:176:25:176:25 | s : String | CSharp7.cs:176:33:176:33 | access to parameter s : String | +| CSharp7.cs:176:31:176:34 | call to local function g : String | CSharp7.cs:176:31:176:39 | ... + ... : String | +| CSharp7.cs:176:33:176:33 | access to parameter s : String | CSharp7.cs:176:31:176:34 | call to local function g : String | +| CSharp7.cs:176:33:176:33 | access to parameter s : String | CSharp7.cs:177:25:177:25 | s : String | +| CSharp7.cs:177:25:177:25 | s : String | CSharp7.cs:177:31:177:31 | access to parameter s : String | +| CSharp7.cs:178:25:178:25 | s : String | CSharp7.cs:178:37:178:37 | access to parameter s : String | +| CSharp7.cs:180:23:180:25 | access to local variable src : String | CSharp7.cs:176:25:176:25 | s : String | | CSharp7.cs:180:23:180:25 | access to local variable src : String | CSharp7.cs:180:21:180:26 | call to local function f | +| CSharp7.cs:181:23:181:25 | access to local variable src : String | CSharp7.cs:177:25:177:25 | s : String | | CSharp7.cs:181:23:181:25 | access to local variable src : String | CSharp7.cs:181:21:181:26 | call to local function g | +| CSharp7.cs:182:23:182:25 | access to local variable src : String | CSharp7.cs:178:25:178:25 | s : String | | CSharp7.cs:182:23:182:25 | access to local variable src : String | CSharp7.cs:182:21:182:26 | call to local function h | nodes | CSharp7.cs:39:9:39:21 | SSA def(x) : String | semmle.label | SSA def(x) : String | | CSharp7.cs:39:13:39:21 | "tainted" : String | semmle.label | "tainted" : String | +| CSharp7.cs:42:19:42:19 | x : String | semmle.label | x : String | +| CSharp7.cs:44:9:44:13 | SSA def(y) : String | semmle.label | SSA def(y) : String | | CSharp7.cs:49:22:49:23 | SSA def(t1) : String | semmle.label | SSA def(t1) : String | | CSharp7.cs:51:18:51:19 | access to local variable t1 | semmle.label | access to local variable t1 | | CSharp7.cs:55:11:55:19 | "tainted" : String | semmle.label | "tainted" : String | | CSharp7.cs:55:30:55:31 | SSA def(t4) : String | semmle.label | SSA def(t4) : String | | CSharp7.cs:56:18:56:19 | access to local variable t4 | semmle.label | access to local variable t4 | +| CSharp7.cs:80:21:80:21 | x : String | semmle.label | x : String | +| CSharp7.cs:82:16:82:24 | (..., ...) [field Item1] : String | semmle.label | (..., ...) [field Item1] : String | +| CSharp7.cs:82:16:82:26 | access to field Item1 : String | semmle.label | access to field Item1 : String | +| CSharp7.cs:82:20:82:20 | access to parameter x : String | semmle.label | access to parameter x : String | | CSharp7.cs:87:18:87:34 | (..., ...) [field Item1] : String | semmle.label | (..., ...) [field Item1] : String | | CSharp7.cs:87:19:87:27 | "tainted" : String | semmle.label | "tainted" : String | | CSharp7.cs:90:18:90:28 | call to method I | semmle.label | call to method I | @@ -29,12 +50,27 @@ nodes | CSharp7.cs:90:20:90:27 | access to field Item1 : String | semmle.label | access to field Item1 : String | | CSharp7.cs:175:22:175:30 | "tainted" | semmle.label | "tainted" | | CSharp7.cs:175:22:175:30 | "tainted" : String | semmle.label | "tainted" : String | +| CSharp7.cs:176:25:176:25 | s : String | semmle.label | s : String | +| CSharp7.cs:176:31:176:34 | call to local function g : String | semmle.label | call to local function g : String | +| CSharp7.cs:176:31:176:39 | ... + ... : String | semmle.label | ... + ... : String | +| CSharp7.cs:176:33:176:33 | access to parameter s : String | semmle.label | access to parameter s : String | +| CSharp7.cs:177:25:177:25 | s : String | semmle.label | s : String | +| CSharp7.cs:177:31:177:31 | access to parameter s : String | semmle.label | access to parameter s : String | +| CSharp7.cs:178:25:178:25 | s : String | semmle.label | s : String | +| CSharp7.cs:178:37:178:37 | access to parameter s : String | semmle.label | access to parameter s : String | | CSharp7.cs:180:21:180:26 | call to local function f | semmle.label | call to local function f | | CSharp7.cs:180:23:180:25 | access to local variable src : String | semmle.label | access to local variable src : String | | CSharp7.cs:181:21:181:26 | call to local function g | semmle.label | call to local function g | | CSharp7.cs:181:23:181:25 | access to local variable src : String | semmle.label | access to local variable src : String | | CSharp7.cs:182:21:182:26 | call to local function h | semmle.label | call to local function h | | CSharp7.cs:182:23:182:25 | access to local variable src : String | semmle.label | access to local variable src : String | +subpaths +| CSharp7.cs:55:11:55:19 | "tainted" : String | CSharp7.cs:42:19:42:19 | x : String | CSharp7.cs:44:9:44:13 | SSA def(y) : String | CSharp7.cs:55:30:55:31 | SSA def(t4) : String | +| CSharp7.cs:90:20:90:27 | access to field Item1 : String | CSharp7.cs:80:21:80:21 | x : String | CSharp7.cs:82:16:82:26 | access to field Item1 : String | CSharp7.cs:90:18:90:28 | call to method I : String | +| CSharp7.cs:176:33:176:33 | access to parameter s : String | CSharp7.cs:177:25:177:25 | s : String | CSharp7.cs:177:31:177:31 | access to parameter s : String | CSharp7.cs:176:31:176:34 | call to local function g : String | +| CSharp7.cs:180:23:180:25 | access to local variable src : String | CSharp7.cs:176:25:176:25 | s : String | CSharp7.cs:176:31:176:39 | ... + ... : String | CSharp7.cs:180:21:180:26 | call to local function f : String | +| CSharp7.cs:181:23:181:25 | access to local variable src : String | CSharp7.cs:177:25:177:25 | s : String | CSharp7.cs:177:31:177:31 | access to parameter s : String | CSharp7.cs:181:21:181:26 | call to local function g : String | +| CSharp7.cs:182:23:182:25 | access to local variable src : String | CSharp7.cs:178:25:178:25 | s : String | CSharp7.cs:178:37:178:37 | access to parameter s : String | CSharp7.cs:182:21:182:26 | call to local function h : String | #select | CSharp7.cs:39:13:39:21 | "tainted" : String | CSharp7.cs:39:13:39:21 | "tainted" : String | CSharp7.cs:51:18:51:19 | access to local variable t1 | $@ | CSharp7.cs:51:18:51:19 | access to local variable t1 | access to local variable t1 | | CSharp7.cs:55:11:55:19 | "tainted" : String | CSharp7.cs:55:11:55:19 | "tainted" : String | CSharp7.cs:56:18:56:19 | access to local variable t4 | $@ | CSharp7.cs:56:18:56:19 | access to local variable t4 | access to local variable t4 | diff --git a/csharp/ql/test/library-tests/dataflow/async/Async.expected b/csharp/ql/test/library-tests/dataflow/async/Async.expected index 08fc1925ae5..a6928aa6937 100644 --- a/csharp/ql/test/library-tests/dataflow/async/Async.expected +++ b/csharp/ql/test/library-tests/dataflow/async/Async.expected @@ -1,6 +1,8 @@ edges | Async.cs:9:37:9:41 | input : String | Async.cs:11:21:11:25 | access to parameter input : String | | Async.cs:11:21:11:25 | access to parameter input : String | Async.cs:11:14:11:26 | call to method Return | +| Async.cs:11:21:11:25 | access to parameter input : String | Async.cs:14:34:14:34 | x : String | +| Async.cs:14:34:14:34 | x : String | Async.cs:16:16:16:16 | access to parameter x : String | | Async.cs:14:34:14:34 | x : String | Async.cs:16:16:16:16 | access to parameter x : String | | Async.cs:16:16:16:16 | access to parameter x : String | Async.cs:11:14:11:26 | call to method Return | | Async.cs:19:41:19:45 | input : String | Async.cs:21:32:21:36 | access to parameter input : String | @@ -19,9 +21,12 @@ edges | Async.cs:41:33:41:37 | input : String | Async.cs:43:25:43:29 | access to parameter input : String | | Async.cs:43:14:43:30 | call to method ReturnTask [property Result] : String | Async.cs:43:14:43:37 | access to property Result | | Async.cs:43:25:43:29 | access to parameter input : String | Async.cs:43:14:43:30 | call to method ReturnTask [property Result] : String | +| Async.cs:43:25:43:29 | access to parameter input : String | Async.cs:46:44:46:44 | x : String | +| Async.cs:46:44:46:44 | x : String | Async.cs:48:32:48:32 | access to parameter x : String | | Async.cs:46:44:46:44 | x : String | Async.cs:48:32:48:32 | access to parameter x : String | | Async.cs:48:16:48:33 | call to method FromResult [property Result] : String | Async.cs:43:14:43:30 | call to method ReturnTask [property Result] : String | | Async.cs:48:32:48:32 | access to parameter x : String | Async.cs:48:16:48:33 | call to method FromResult [property Result] : String | +| Async.cs:48:32:48:32 | access to parameter x : String | Async.cs:48:16:48:33 | call to method FromResult [property Result] : String | | Async.cs:51:52:51:52 | x : String | Async.cs:51:58:51:58 | access to parameter x : String | | Async.cs:51:58:51:58 | access to parameter x : String | Async.cs:32:14:32:32 | call to method ReturnAwait2 [property Result] : String | nodes @@ -29,6 +34,8 @@ nodes | Async.cs:11:14:11:26 | call to method Return | semmle.label | call to method Return | | Async.cs:11:21:11:25 | access to parameter input : String | semmle.label | access to parameter input : String | | Async.cs:14:34:14:34 | x : String | semmle.label | x : String | +| Async.cs:14:34:14:34 | x : String | semmle.label | x : String | +| Async.cs:16:16:16:16 | access to parameter x : String | semmle.label | access to parameter x : String | | Async.cs:16:16:16:16 | access to parameter x : String | semmle.label | access to parameter x : String | | Async.cs:19:41:19:45 | input : String | semmle.label | input : String | | Async.cs:21:14:21:37 | await ... | semmle.label | await ... | @@ -50,10 +57,16 @@ nodes | Async.cs:43:14:43:37 | access to property Result | semmle.label | access to property Result | | Async.cs:43:25:43:29 | access to parameter input : String | semmle.label | access to parameter input : String | | Async.cs:46:44:46:44 | x : String | semmle.label | x : String | +| Async.cs:46:44:46:44 | x : String | semmle.label | x : String | | Async.cs:48:16:48:33 | call to method FromResult [property Result] : String | semmle.label | call to method FromResult [property Result] : String | +| Async.cs:48:16:48:33 | call to method FromResult [property Result] : String | semmle.label | call to method FromResult [property Result] : String | +| Async.cs:48:32:48:32 | access to parameter x : String | semmle.label | access to parameter x : String | | Async.cs:48:32:48:32 | access to parameter x : String | semmle.label | access to parameter x : String | | Async.cs:51:52:51:52 | x : String | semmle.label | x : String | | Async.cs:51:58:51:58 | access to parameter x : String | semmle.label | access to parameter x : String | +subpaths +| Async.cs:11:21:11:25 | access to parameter input : String | Async.cs:14:34:14:34 | x : String | Async.cs:16:16:16:16 | access to parameter x : String | Async.cs:11:14:11:26 | call to method Return : String | +| Async.cs:43:25:43:29 | access to parameter input : String | Async.cs:46:44:46:44 | x : String | Async.cs:48:16:48:33 | call to method FromResult [property Result] : String | Async.cs:43:14:43:30 | call to method ReturnTask [property Result] : String | #select | Async.cs:11:14:11:26 | call to method Return | Async.cs:9:37:9:41 | input : String | Async.cs:11:14:11:26 | call to method Return | $@ flows to here and is used. | Async.cs:9:37:9:41 | input | User-provided value | | Async.cs:11:14:11:26 | call to method Return | Async.cs:14:34:14:34 | x : String | Async.cs:11:14:11:26 | call to method Return | $@ flows to here and is used. | Async.cs:14:34:14:34 | x | User-provided value | diff --git a/csharp/ql/test/library-tests/dataflow/call-sensitivity/CallSensitivityFlow.expected b/csharp/ql/test/library-tests/dataflow/call-sensitivity/CallSensitivityFlow.expected index 7d87f84d155..4b3bc74f280 100644 --- a/csharp/ql/test/library-tests/dataflow/call-sensitivity/CallSensitivityFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/call-sensitivity/CallSensitivityFlow.expected @@ -1,4 +1,6 @@ edges +| CallSensitivityFlow.cs:7:38:7:38 | o : Object | CallSensitivityFlow.cs:11:20:11:20 | access to parameter o : Object | +| CallSensitivityFlow.cs:7:38:7:38 | o : Object | CallSensitivityFlow.cs:11:20:11:20 | access to parameter o : Object | | CallSensitivityFlow.cs:19:39:19:39 | o : Object | CallSensitivityFlow.cs:23:18:23:18 | access to parameter o | | CallSensitivityFlow.cs:27:40:27:40 | o : Object | CallSensitivityFlow.cs:31:18:31:18 | access to parameter o | | CallSensitivityFlow.cs:27:40:27:40 | o : Object | CallSensitivityFlow.cs:31:18:31:18 | access to parameter o | @@ -15,12 +17,14 @@ edges | CallSensitivityFlow.cs:82:31:82:42 | object creation of type Object : Object | CallSensitivityFlow.cs:56:46:56:46 | o : Object | | CallSensitivityFlow.cs:83:31:83:42 | object creation of type Object : Object | CallSensitivityFlow.cs:56:46:56:46 | o : Object | | CallSensitivityFlow.cs:84:31:84:42 | object creation of type Object : Object | CallSensitivityFlow.cs:56:46:56:46 | o : Object | +| CallSensitivityFlow.cs:85:26:85:37 | object creation of type Object : Object | CallSensitivityFlow.cs:7:38:7:38 | o : Object | | CallSensitivityFlow.cs:85:26:85:37 | object creation of type Object : Object | CallSensitivityFlow.cs:85:14:85:44 | call to method FlowThrough | | CallSensitivityFlow.cs:87:31:87:42 | object creation of type Object : Object | CallSensitivityFlow.cs:56:46:56:46 | o : Object | | CallSensitivityFlow.cs:101:24:101:35 | object creation of type Object : Object | CallSensitivityFlow.cs:19:39:19:39 | o : Object | | CallSensitivityFlow.cs:102:25:102:36 | object creation of type Object : Object | CallSensitivityFlow.cs:27:40:27:40 | o : Object | | CallSensitivityFlow.cs:103:26:103:37 | object creation of type Object : Object | CallSensitivityFlow.cs:35:41:35:41 | o : Object | | CallSensitivityFlow.cs:104:30:104:41 | object creation of type Object : Object | CallSensitivityFlow.cs:43:45:43:45 | o : Object | +| CallSensitivityFlow.cs:105:26:105:37 | object creation of type Object : Object | CallSensitivityFlow.cs:7:38:7:38 | o : Object | | CallSensitivityFlow.cs:105:26:105:37 | object creation of type Object : Object | CallSensitivityFlow.cs:105:14:105:41 | call to method FlowThrough | | CallSensitivityFlow.cs:117:26:117:37 | object creation of type Object : Object | CallSensitivityFlow.cs:124:43:124:43 | o : Object | | CallSensitivityFlow.cs:118:27:118:38 | object creation of type Object : Object | CallSensitivityFlow.cs:132:44:132:44 | o : Object | @@ -38,6 +42,10 @@ edges | CallSensitivityFlow.cs:187:17:187:30 | call to method CallMOut : Object | CallSensitivityFlow.cs:188:14:188:14 | access to local variable o | | CallSensitivityFlow.cs:205:40:205:40 | o : Object | CallSensitivityFlow.cs:208:18:208:18 | access to parameter o | nodes +| CallSensitivityFlow.cs:7:38:7:38 | o : Object | semmle.label | o : Object | +| CallSensitivityFlow.cs:7:38:7:38 | o : Object | semmle.label | o : Object | +| CallSensitivityFlow.cs:11:20:11:20 | access to parameter o : Object | semmle.label | access to parameter o : Object | +| CallSensitivityFlow.cs:11:20:11:20 | access to parameter o : Object | semmle.label | access to parameter o : Object | | CallSensitivityFlow.cs:19:39:19:39 | o : Object | semmle.label | o : Object | | CallSensitivityFlow.cs:23:18:23:18 | access to parameter o | semmle.label | access to parameter o | | CallSensitivityFlow.cs:27:40:27:40 | o : Object | semmle.label | o : Object | @@ -89,6 +97,9 @@ nodes | CallSensitivityFlow.cs:188:14:188:14 | access to local variable o | semmle.label | access to local variable o | | CallSensitivityFlow.cs:205:40:205:40 | o : Object | semmle.label | o : Object | | CallSensitivityFlow.cs:208:18:208:18 | access to parameter o | semmle.label | access to parameter o | +subpaths +| CallSensitivityFlow.cs:85:26:85:37 | object creation of type Object : Object | CallSensitivityFlow.cs:7:38:7:38 | o : Object | CallSensitivityFlow.cs:11:20:11:20 | access to parameter o : Object | CallSensitivityFlow.cs:85:14:85:44 | call to method FlowThrough : Object | +| CallSensitivityFlow.cs:105:26:105:37 | object creation of type Object : Object | CallSensitivityFlow.cs:7:38:7:38 | o : Object | CallSensitivityFlow.cs:11:20:11:20 | access to parameter o : Object | CallSensitivityFlow.cs:105:14:105:41 | call to method FlowThrough : Object | #select | CallSensitivityFlow.cs:78:24:78:35 | object creation of type Object : Object | CallSensitivityFlow.cs:78:24:78:35 | object creation of type Object : Object | CallSensitivityFlow.cs:23:18:23:18 | access to parameter o | $@ | CallSensitivityFlow.cs:23:18:23:18 | access to parameter o | access to parameter o | | CallSensitivityFlow.cs:79:25:79:36 | object creation of type Object : Object | CallSensitivityFlow.cs:79:25:79:36 | object creation of type Object : Object | CallSensitivityFlow.cs:31:18:31:18 | access to parameter o | $@ | CallSensitivityFlow.cs:31:18:31:18 | access to parameter o | access to parameter o | diff --git a/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected b/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected index c6d5a86091b..20a5ae38fbb 100644 --- a/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected @@ -7,6 +7,7 @@ edges | CollectionFlow.cs:15:14:15:16 | access to local variable as [element] : A | CollectionFlow.cs:15:14:15:19 | access to array element | | CollectionFlow.cs:16:18:16:20 | access to local variable as [element] : A | CollectionFlow.cs:373:40:373:41 | ts [element] : A | | CollectionFlow.cs:17:20:17:22 | access to local variable as [element] : A | CollectionFlow.cs:17:14:17:23 | call to method First | +| CollectionFlow.cs:17:20:17:22 | access to local variable as [element] : A | CollectionFlow.cs:381:34:381:35 | ts [element] : A | | CollectionFlow.cs:31:17:31:23 | object creation of type A : A | CollectionFlow.cs:32:53:32:53 | access to local variable a : A | | CollectionFlow.cs:32:38:32:57 | { ..., ... } [field As, element] : A | CollectionFlow.cs:33:14:33:14 | access to local variable c [field As, element] : A | | CollectionFlow.cs:32:38:32:57 | { ..., ... } [field As, element] : A | CollectionFlow.cs:34:18:34:18 | access to local variable c [field As, element] : A | @@ -19,6 +20,7 @@ edges | CollectionFlow.cs:34:18:34:21 | access to field As [element] : A | CollectionFlow.cs:373:40:373:41 | ts [element] : A | | CollectionFlow.cs:35:20:35:20 | access to local variable c [field As, element] : A | CollectionFlow.cs:35:20:35:23 | access to field As [element] : A | | CollectionFlow.cs:35:20:35:23 | access to field As [element] : A | CollectionFlow.cs:35:14:35:24 | call to method First | +| CollectionFlow.cs:35:20:35:23 | access to field As [element] : A | CollectionFlow.cs:381:34:381:35 | ts [element] : A | | CollectionFlow.cs:49:17:49:23 | object creation of type A : A | CollectionFlow.cs:51:18:51:18 | access to local variable a : A | | CollectionFlow.cs:51:9:51:11 | [post] access to local variable as [element] : A | CollectionFlow.cs:52:14:52:16 | access to local variable as [element] : A | | CollectionFlow.cs:51:9:51:11 | [post] access to local variable as [element] : A | CollectionFlow.cs:53:18:53:20 | access to local variable as [element] : A | @@ -27,6 +29,7 @@ edges | CollectionFlow.cs:52:14:52:16 | access to local variable as [element] : A | CollectionFlow.cs:52:14:52:19 | access to array element | | CollectionFlow.cs:53:18:53:20 | access to local variable as [element] : A | CollectionFlow.cs:373:40:373:41 | ts [element] : A | | CollectionFlow.cs:54:20:54:22 | access to local variable as [element] : A | CollectionFlow.cs:54:14:54:23 | call to method First | +| CollectionFlow.cs:54:20:54:22 | access to local variable as [element] : A | CollectionFlow.cs:381:34:381:35 | ts [element] : A | | CollectionFlow.cs:69:17:69:23 | object creation of type A : A | CollectionFlow.cs:71:19:71:19 | access to local variable a : A | | CollectionFlow.cs:71:9:71:12 | [post] access to local variable list [element] : A | CollectionFlow.cs:72:14:72:17 | access to local variable list [element] : A | | CollectionFlow.cs:71:9:71:12 | [post] access to local variable list [element] : A | CollectionFlow.cs:73:22:73:25 | access to local variable list [element] : A | @@ -35,6 +38,7 @@ edges | CollectionFlow.cs:72:14:72:17 | access to local variable list [element] : A | CollectionFlow.cs:72:14:72:20 | access to indexer | | CollectionFlow.cs:73:22:73:25 | access to local variable list [element] : A | CollectionFlow.cs:375:49:375:52 | list [element] : A | | CollectionFlow.cs:74:24:74:27 | access to local variable list [element] : A | CollectionFlow.cs:74:14:74:28 | call to method ListFirst | +| CollectionFlow.cs:74:24:74:27 | access to local variable list [element] : A | CollectionFlow.cs:383:43:383:46 | list [element] : A | | CollectionFlow.cs:88:17:88:23 | object creation of type A : A | CollectionFlow.cs:89:36:89:36 | access to local variable a : A | | CollectionFlow.cs:89:20:89:38 | object creation of type List [element] : A | CollectionFlow.cs:90:14:90:17 | access to local variable list [element] : A | | CollectionFlow.cs:89:20:89:38 | object creation of type List [element] : A | CollectionFlow.cs:91:22:91:25 | access to local variable list [element] : A | @@ -43,6 +47,7 @@ edges | CollectionFlow.cs:90:14:90:17 | access to local variable list [element] : A | CollectionFlow.cs:90:14:90:20 | access to indexer | | CollectionFlow.cs:91:22:91:25 | access to local variable list [element] : A | CollectionFlow.cs:375:49:375:52 | list [element] : A | | CollectionFlow.cs:92:24:92:27 | access to local variable list [element] : A | CollectionFlow.cs:92:14:92:28 | call to method ListFirst | +| CollectionFlow.cs:92:24:92:27 | access to local variable list [element] : A | CollectionFlow.cs:383:43:383:46 | list [element] : A | | CollectionFlow.cs:105:17:105:23 | object creation of type A : A | CollectionFlow.cs:107:18:107:18 | access to local variable a : A | | CollectionFlow.cs:107:9:107:12 | [post] access to local variable list [element] : A | CollectionFlow.cs:108:14:108:17 | access to local variable list [element] : A | | CollectionFlow.cs:107:9:107:12 | [post] access to local variable list [element] : A | CollectionFlow.cs:109:22:109:25 | access to local variable list [element] : A | @@ -51,6 +56,7 @@ edges | CollectionFlow.cs:108:14:108:17 | access to local variable list [element] : A | CollectionFlow.cs:108:14:108:20 | access to indexer | | CollectionFlow.cs:109:22:109:25 | access to local variable list [element] : A | CollectionFlow.cs:375:49:375:52 | list [element] : A | | CollectionFlow.cs:110:24:110:27 | access to local variable list [element] : A | CollectionFlow.cs:110:14:110:28 | call to method ListFirst | +| CollectionFlow.cs:110:24:110:27 | access to local variable list [element] : A | CollectionFlow.cs:383:43:383:46 | list [element] : A | | CollectionFlow.cs:124:17:124:23 | object creation of type A : A | CollectionFlow.cs:126:19:126:19 | access to local variable a : A | | CollectionFlow.cs:126:9:126:12 | [post] access to local variable dict [element, property Value] : A | CollectionFlow.cs:127:14:127:17 | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:126:9:126:12 | [post] access to local variable dict [element, property Value] : A | CollectionFlow.cs:128:23:128:26 | access to local variable dict [element, property Value] : A | @@ -61,8 +67,11 @@ edges | CollectionFlow.cs:127:14:127:17 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:127:14:127:20 | access to indexer | | CollectionFlow.cs:128:23:128:26 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:377:61:377:64 | dict [element, property Value] : A | | CollectionFlow.cs:129:28:129:31 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:129:14:129:32 | call to method DictIndexZero | +| CollectionFlow.cs:129:28:129:31 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:385:58:385:61 | dict [element, property Value] : A | | CollectionFlow.cs:130:29:130:32 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:130:14:130:33 | call to method DictFirstValue | +| CollectionFlow.cs:130:29:130:32 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:387:59:387:62 | dict [element, property Value] : A | | CollectionFlow.cs:131:30:131:33 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:131:14:131:34 | call to method DictValuesFirst | +| CollectionFlow.cs:131:30:131:33 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:389:60:389:63 | dict [element, property Value] : A | | CollectionFlow.cs:147:17:147:23 | object creation of type A : A | CollectionFlow.cs:148:52:148:52 | access to local variable a : A | | CollectionFlow.cs:148:20:148:56 | object creation of type Dictionary [element, property Value] : A | CollectionFlow.cs:149:14:149:17 | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:148:20:148:56 | object creation of type Dictionary [element, property Value] : A | CollectionFlow.cs:150:23:150:26 | access to local variable dict [element, property Value] : A | @@ -73,8 +82,11 @@ edges | CollectionFlow.cs:149:14:149:17 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:149:14:149:20 | access to indexer | | CollectionFlow.cs:150:23:150:26 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:377:61:377:64 | dict [element, property Value] : A | | CollectionFlow.cs:151:28:151:31 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:151:14:151:32 | call to method DictIndexZero | +| CollectionFlow.cs:151:28:151:31 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:385:58:385:61 | dict [element, property Value] : A | | CollectionFlow.cs:152:29:152:32 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:152:14:152:33 | call to method DictFirstValue | +| CollectionFlow.cs:152:29:152:32 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:387:59:387:62 | dict [element, property Value] : A | | CollectionFlow.cs:153:30:153:33 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:153:14:153:34 | call to method DictValuesFirst | +| CollectionFlow.cs:153:30:153:33 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:389:60:389:63 | dict [element, property Value] : A | | CollectionFlow.cs:168:17:168:23 | object creation of type A : A | CollectionFlow.cs:169:53:169:53 | access to local variable a : A | | CollectionFlow.cs:169:20:169:55 | object creation of type Dictionary [element, property Value] : A | CollectionFlow.cs:170:14:170:17 | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:169:20:169:55 | object creation of type Dictionary [element, property Value] : A | CollectionFlow.cs:171:23:171:26 | access to local variable dict [element, property Value] : A | @@ -85,8 +97,11 @@ edges | CollectionFlow.cs:170:14:170:17 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:170:14:170:20 | access to indexer | | CollectionFlow.cs:171:23:171:26 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:377:61:377:64 | dict [element, property Value] : A | | CollectionFlow.cs:172:28:172:31 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:172:14:172:32 | call to method DictIndexZero | +| CollectionFlow.cs:172:28:172:31 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:385:58:385:61 | dict [element, property Value] : A | | CollectionFlow.cs:173:29:173:32 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:173:14:173:33 | call to method DictFirstValue | +| CollectionFlow.cs:173:29:173:32 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:387:59:387:62 | dict [element, property Value] : A | | CollectionFlow.cs:174:30:174:33 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:174:14:174:34 | call to method DictValuesFirst | +| CollectionFlow.cs:174:30:174:33 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:389:60:389:63 | dict [element, property Value] : A | | CollectionFlow.cs:190:17:190:23 | object creation of type A : A | CollectionFlow.cs:191:49:191:49 | access to local variable a : A | | CollectionFlow.cs:191:20:191:56 | object creation of type Dictionary [element, property Key] : A | CollectionFlow.cs:192:14:192:17 | access to local variable dict [element, property Key] : A | | CollectionFlow.cs:191:20:191:56 | object creation of type Dictionary [element, property Key] : A | CollectionFlow.cs:193:21:193:24 | access to local variable dict [element, property Key] : A | @@ -97,7 +112,9 @@ edges | CollectionFlow.cs:192:14:192:22 | access to property Keys [element] : A | CollectionFlow.cs:192:14:192:30 | call to method First | | CollectionFlow.cs:193:21:193:24 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:379:59:379:62 | dict [element, property Key] : A | | CollectionFlow.cs:194:28:194:31 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:194:14:194:32 | call to method DictKeysFirst | +| CollectionFlow.cs:194:28:194:31 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:391:58:391:61 | dict [element, property Key] : A | | CollectionFlow.cs:195:27:195:30 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:195:14:195:31 | call to method DictFirstKey | +| CollectionFlow.cs:195:27:195:30 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:393:57:393:60 | dict [element, property Key] : A | | CollectionFlow.cs:209:17:209:23 | object creation of type A : A | CollectionFlow.cs:210:48:210:48 | access to local variable a : A | | CollectionFlow.cs:210:20:210:55 | object creation of type Dictionary [element, property Key] : A | CollectionFlow.cs:211:14:211:17 | access to local variable dict [element, property Key] : A | | CollectionFlow.cs:210:20:210:55 | object creation of type Dictionary [element, property Key] : A | CollectionFlow.cs:212:21:212:24 | access to local variable dict [element, property Key] : A | @@ -108,7 +125,9 @@ edges | CollectionFlow.cs:211:14:211:22 | access to property Keys [element] : A | CollectionFlow.cs:211:14:211:30 | call to method First | | CollectionFlow.cs:212:21:212:24 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:379:59:379:62 | dict [element, property Key] : A | | CollectionFlow.cs:213:28:213:31 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:213:14:213:32 | call to method DictKeysFirst | +| CollectionFlow.cs:213:28:213:31 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:391:58:391:61 | dict [element, property Key] : A | | CollectionFlow.cs:214:27:214:30 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:214:14:214:31 | call to method DictFirstKey | +| CollectionFlow.cs:214:27:214:30 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:393:57:393:60 | dict [element, property Key] : A | | CollectionFlow.cs:228:17:228:23 | object creation of type A : A | CollectionFlow.cs:229:27:229:27 | access to local variable a : A | | CollectionFlow.cs:229:25:229:29 | { ..., ... } [element] : A | CollectionFlow.cs:230:27:230:29 | access to local variable as [element] : A | | CollectionFlow.cs:229:27:229:27 | access to local variable a : A | CollectionFlow.cs:229:25:229:29 | { ..., ... } [element] : A | @@ -133,22 +152,30 @@ edges | CollectionFlow.cs:282:9:282:12 | access to local variable list [element, property Key] : A | CollectionFlow.cs:282:21:282:23 | kvp [property Key] : A | | CollectionFlow.cs:282:21:282:23 | kvp [property Key] : A | CollectionFlow.cs:284:18:284:20 | access to parameter kvp [property Key] : A | | CollectionFlow.cs:284:18:284:20 | access to parameter kvp [property Key] : A | CollectionFlow.cs:284:18:284:24 | access to property Key | +| CollectionFlow.cs:301:32:301:38 | element : A | CollectionFlow.cs:301:55:301:61 | access to parameter element : A | +| CollectionFlow.cs:301:55:301:61 | access to parameter element : A | CollectionFlow.cs:301:44:301:48 | [post] access to parameter array [element] : A | | CollectionFlow.cs:305:17:305:23 | object creation of type A : A | CollectionFlow.cs:307:23:307:23 | access to local variable a : A | | CollectionFlow.cs:307:18:307:20 | [post] access to local variable as [element] : A | CollectionFlow.cs:308:14:308:16 | access to local variable as [element] : A | | CollectionFlow.cs:307:18:307:20 | [post] access to local variable as [element] : A | CollectionFlow.cs:309:18:309:20 | access to local variable as [element] : A | | CollectionFlow.cs:307:18:307:20 | [post] access to local variable as [element] : A | CollectionFlow.cs:310:20:310:22 | access to local variable as [element] : A | +| CollectionFlow.cs:307:23:307:23 | access to local variable a : A | CollectionFlow.cs:301:32:301:38 | element : A | | CollectionFlow.cs:307:23:307:23 | access to local variable a : A | CollectionFlow.cs:307:18:307:20 | [post] access to local variable as [element] : A | | CollectionFlow.cs:308:14:308:16 | access to local variable as [element] : A | CollectionFlow.cs:308:14:308:19 | access to array element | | CollectionFlow.cs:309:18:309:20 | access to local variable as [element] : A | CollectionFlow.cs:373:40:373:41 | ts [element] : A | | CollectionFlow.cs:310:20:310:22 | access to local variable as [element] : A | CollectionFlow.cs:310:14:310:23 | call to method First | +| CollectionFlow.cs:310:20:310:22 | access to local variable as [element] : A | CollectionFlow.cs:381:34:381:35 | ts [element] : A | +| CollectionFlow.cs:323:34:323:40 | element : A | CollectionFlow.cs:323:55:323:61 | access to parameter element : A | +| CollectionFlow.cs:323:55:323:61 | access to parameter element : A | CollectionFlow.cs:323:46:323:49 | [post] access to parameter list [element] : A | | CollectionFlow.cs:327:17:327:23 | object creation of type A : A | CollectionFlow.cs:329:23:329:23 | access to local variable a : A | | CollectionFlow.cs:329:17:329:20 | [post] access to local variable list [element] : A | CollectionFlow.cs:330:14:330:17 | access to local variable list [element] : A | | CollectionFlow.cs:329:17:329:20 | [post] access to local variable list [element] : A | CollectionFlow.cs:331:22:331:25 | access to local variable list [element] : A | | CollectionFlow.cs:329:17:329:20 | [post] access to local variable list [element] : A | CollectionFlow.cs:332:24:332:27 | access to local variable list [element] : A | +| CollectionFlow.cs:329:23:329:23 | access to local variable a : A | CollectionFlow.cs:323:34:323:40 | element : A | | CollectionFlow.cs:329:23:329:23 | access to local variable a : A | CollectionFlow.cs:329:17:329:20 | [post] access to local variable list [element] : A | | CollectionFlow.cs:330:14:330:17 | access to local variable list [element] : A | CollectionFlow.cs:330:14:330:20 | access to indexer | | CollectionFlow.cs:331:22:331:25 | access to local variable list [element] : A | CollectionFlow.cs:375:49:375:52 | list [element] : A | | CollectionFlow.cs:332:24:332:27 | access to local variable list [element] : A | CollectionFlow.cs:332:14:332:28 | call to method ListFirst | +| CollectionFlow.cs:332:24:332:27 | access to local variable list [element] : A | CollectionFlow.cs:383:43:383:46 | list [element] : A | | CollectionFlow.cs:346:20:346:26 | object creation of type A : A | CollectionFlow.cs:395:49:395:52 | args [element] : A | | CollectionFlow.cs:347:26:347:32 | object creation of type A : A | CollectionFlow.cs:395:49:395:52 | args [element] : A | | CollectionFlow.cs:348:26:348:32 | object creation of type A : A | CollectionFlow.cs:395:49:395:52 | args [element] : A | @@ -172,6 +199,32 @@ edges | CollectionFlow.cs:379:59:379:62 | dict [element, property Key] : A | CollectionFlow.cs:379:73:379:76 | access to parameter dict [element, property Key] : A | | CollectionFlow.cs:379:73:379:76 | access to parameter dict [element, property Key] : A | CollectionFlow.cs:379:73:379:81 | access to property Keys [element] : A | | CollectionFlow.cs:379:73:379:81 | access to property Keys [element] : A | CollectionFlow.cs:379:73:379:89 | call to method First | +| CollectionFlow.cs:381:34:381:35 | ts [element] : A | CollectionFlow.cs:381:41:381:42 | access to parameter ts [element] : A | +| CollectionFlow.cs:381:34:381:35 | ts [element] : A | CollectionFlow.cs:381:41:381:42 | access to parameter ts [element] : A | +| CollectionFlow.cs:381:41:381:42 | access to parameter ts [element] : A | CollectionFlow.cs:381:41:381:45 | access to array element : A | +| CollectionFlow.cs:381:41:381:42 | access to parameter ts [element] : A | CollectionFlow.cs:381:41:381:45 | access to array element : A | +| CollectionFlow.cs:383:43:383:46 | list [element] : A | CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | +| CollectionFlow.cs:383:43:383:46 | list [element] : A | CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | +| CollectionFlow.cs:383:43:383:46 | list [element] : A | CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | +| CollectionFlow.cs:383:43:383:46 | list [element] : A | CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | +| CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | CollectionFlow.cs:383:52:383:58 | access to indexer : A | +| CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | CollectionFlow.cs:383:52:383:58 | access to indexer : A | +| CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | CollectionFlow.cs:383:52:383:58 | access to indexer : A | +| CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | CollectionFlow.cs:383:52:383:58 | access to indexer : A | +| CollectionFlow.cs:385:58:385:61 | dict [element, property Value] : A | CollectionFlow.cs:385:67:385:70 | access to parameter dict [element, property Value] : A | +| CollectionFlow.cs:385:67:385:70 | access to parameter dict [element, property Value] : A | CollectionFlow.cs:385:67:385:73 | access to indexer : A | +| CollectionFlow.cs:387:59:387:62 | dict [element, property Value] : A | CollectionFlow.cs:387:68:387:71 | access to parameter dict [element, property Value] : A | +| CollectionFlow.cs:387:68:387:71 | access to parameter dict [element, property Value] : A | CollectionFlow.cs:387:68:387:79 | call to method First> [property Value] : A | +| CollectionFlow.cs:387:68:387:79 | call to method First> [property Value] : A | CollectionFlow.cs:387:68:387:85 | access to property Value : A | +| CollectionFlow.cs:389:60:389:63 | dict [element, property Value] : A | CollectionFlow.cs:389:69:389:72 | access to parameter dict [element, property Value] : A | +| CollectionFlow.cs:389:69:389:72 | access to parameter dict [element, property Value] : A | CollectionFlow.cs:389:69:389:79 | access to property Values [element] : A | +| CollectionFlow.cs:389:69:389:79 | access to property Values [element] : A | CollectionFlow.cs:389:69:389:87 | call to method First : A | +| CollectionFlow.cs:391:58:391:61 | dict [element, property Key] : A | CollectionFlow.cs:391:67:391:70 | access to parameter dict [element, property Key] : A | +| CollectionFlow.cs:391:67:391:70 | access to parameter dict [element, property Key] : A | CollectionFlow.cs:391:67:391:75 | access to property Keys [element] : A | +| CollectionFlow.cs:391:67:391:75 | access to property Keys [element] : A | CollectionFlow.cs:391:67:391:83 | call to method First : A | +| CollectionFlow.cs:393:57:393:60 | dict [element, property Key] : A | CollectionFlow.cs:393:66:393:69 | access to parameter dict [element, property Key] : A | +| CollectionFlow.cs:393:66:393:69 | access to parameter dict [element, property Key] : A | CollectionFlow.cs:393:66:393:77 | call to method First> [property Key] : A | +| CollectionFlow.cs:393:66:393:77 | call to method First> [property Key] : A | CollectionFlow.cs:393:66:393:81 | access to property Key : A | | CollectionFlow.cs:395:49:395:52 | args [element] : A | CollectionFlow.cs:395:63:395:66 | access to parameter args [element] : A | | CollectionFlow.cs:395:49:395:52 | args [element] : A | CollectionFlow.cs:395:63:395:66 | access to parameter args [element] : A | | CollectionFlow.cs:395:63:395:66 | access to parameter args [element] : A | CollectionFlow.cs:395:63:395:69 | access to array element | @@ -315,6 +368,9 @@ nodes | CollectionFlow.cs:282:21:282:23 | kvp [property Key] : A | semmle.label | kvp [property Key] : A | | CollectionFlow.cs:284:18:284:20 | access to parameter kvp [property Key] : A | semmle.label | access to parameter kvp [property Key] : A | | CollectionFlow.cs:284:18:284:24 | access to property Key | semmle.label | access to property Key | +| CollectionFlow.cs:301:32:301:38 | element : A | semmle.label | element : A | +| CollectionFlow.cs:301:44:301:48 | [post] access to parameter array [element] : A | semmle.label | [post] access to parameter array [element] : A | +| CollectionFlow.cs:301:55:301:61 | access to parameter element : A | semmle.label | access to parameter element : A | | CollectionFlow.cs:305:17:305:23 | object creation of type A : A | semmle.label | object creation of type A : A | | CollectionFlow.cs:307:18:307:20 | [post] access to local variable as [element] : A | semmle.label | [post] access to local variable as [element] : A | | CollectionFlow.cs:307:23:307:23 | access to local variable a : A | semmle.label | access to local variable a : A | @@ -323,6 +379,9 @@ nodes | CollectionFlow.cs:309:18:309:20 | access to local variable as [element] : A | semmle.label | access to local variable as [element] : A | | CollectionFlow.cs:310:14:310:23 | call to method First | semmle.label | call to method First | | CollectionFlow.cs:310:20:310:22 | access to local variable as [element] : A | semmle.label | access to local variable as [element] : A | +| CollectionFlow.cs:323:34:323:40 | element : A | semmle.label | element : A | +| CollectionFlow.cs:323:46:323:49 | [post] access to parameter list [element] : A | semmle.label | [post] access to parameter list [element] : A | +| CollectionFlow.cs:323:55:323:61 | access to parameter element : A | semmle.label | access to parameter element : A | | CollectionFlow.cs:327:17:327:23 | object creation of type A : A | semmle.label | object creation of type A : A | | CollectionFlow.cs:329:17:329:20 | [post] access to local variable list [element] : A | semmle.label | [post] access to local variable list [element] : A | | CollectionFlow.cs:329:23:329:23 | access to local variable a : A | semmle.label | access to local variable a : A | @@ -358,11 +417,72 @@ nodes | CollectionFlow.cs:379:73:379:76 | access to parameter dict [element, property Key] : A | semmle.label | access to parameter dict [element, property Key] : A | | CollectionFlow.cs:379:73:379:81 | access to property Keys [element] : A | semmle.label | access to property Keys [element] : A | | CollectionFlow.cs:379:73:379:89 | call to method First | semmle.label | call to method First | +| CollectionFlow.cs:381:34:381:35 | ts [element] : A | semmle.label | ts [element] : A | +| CollectionFlow.cs:381:34:381:35 | ts [element] : A | semmle.label | ts [element] : A | +| CollectionFlow.cs:381:41:381:42 | access to parameter ts [element] : A | semmle.label | access to parameter ts [element] : A | +| CollectionFlow.cs:381:41:381:42 | access to parameter ts [element] : A | semmle.label | access to parameter ts [element] : A | +| CollectionFlow.cs:381:41:381:45 | access to array element : A | semmle.label | access to array element : A | +| CollectionFlow.cs:381:41:381:45 | access to array element : A | semmle.label | access to array element : A | +| CollectionFlow.cs:383:43:383:46 | list [element] : A | semmle.label | list [element] : A | +| CollectionFlow.cs:383:43:383:46 | list [element] : A | semmle.label | list [element] : A | +| CollectionFlow.cs:383:43:383:46 | list [element] : A | semmle.label | list [element] : A | +| CollectionFlow.cs:383:43:383:46 | list [element] : A | semmle.label | list [element] : A | +| CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | semmle.label | access to parameter list [element] : A | +| CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | semmle.label | access to parameter list [element] : A | +| CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | semmle.label | access to parameter list [element] : A | +| CollectionFlow.cs:383:52:383:55 | access to parameter list [element] : A | semmle.label | access to parameter list [element] : A | +| CollectionFlow.cs:383:52:383:58 | access to indexer : A | semmle.label | access to indexer : A | +| CollectionFlow.cs:383:52:383:58 | access to indexer : A | semmle.label | access to indexer : A | +| CollectionFlow.cs:383:52:383:58 | access to indexer : A | semmle.label | access to indexer : A | +| CollectionFlow.cs:383:52:383:58 | access to indexer : A | semmle.label | access to indexer : A | +| CollectionFlow.cs:385:58:385:61 | dict [element, property Value] : A | semmle.label | dict [element, property Value] : A | +| CollectionFlow.cs:385:67:385:70 | access to parameter dict [element, property Value] : A | semmle.label | access to parameter dict [element, property Value] : A | +| CollectionFlow.cs:385:67:385:73 | access to indexer : A | semmle.label | access to indexer : A | +| CollectionFlow.cs:387:59:387:62 | dict [element, property Value] : A | semmle.label | dict [element, property Value] : A | +| CollectionFlow.cs:387:68:387:71 | access to parameter dict [element, property Value] : A | semmle.label | access to parameter dict [element, property Value] : A | +| CollectionFlow.cs:387:68:387:79 | call to method First> [property Value] : A | semmle.label | call to method First> [property Value] : A | +| CollectionFlow.cs:387:68:387:85 | access to property Value : A | semmle.label | access to property Value : A | +| CollectionFlow.cs:389:60:389:63 | dict [element, property Value] : A | semmle.label | dict [element, property Value] : A | +| CollectionFlow.cs:389:69:389:72 | access to parameter dict [element, property Value] : A | semmle.label | access to parameter dict [element, property Value] : A | +| CollectionFlow.cs:389:69:389:79 | access to property Values [element] : A | semmle.label | access to property Values [element] : A | +| CollectionFlow.cs:389:69:389:87 | call to method First : A | semmle.label | call to method First : A | +| CollectionFlow.cs:391:58:391:61 | dict [element, property Key] : A | semmle.label | dict [element, property Key] : A | +| CollectionFlow.cs:391:67:391:70 | access to parameter dict [element, property Key] : A | semmle.label | access to parameter dict [element, property Key] : A | +| CollectionFlow.cs:391:67:391:75 | access to property Keys [element] : A | semmle.label | access to property Keys [element] : A | +| CollectionFlow.cs:391:67:391:83 | call to method First : A | semmle.label | call to method First : A | +| CollectionFlow.cs:393:57:393:60 | dict [element, property Key] : A | semmle.label | dict [element, property Key] : A | +| CollectionFlow.cs:393:66:393:69 | access to parameter dict [element, property Key] : A | semmle.label | access to parameter dict [element, property Key] : A | +| CollectionFlow.cs:393:66:393:77 | call to method First> [property Key] : A | semmle.label | call to method First> [property Key] : A | +| CollectionFlow.cs:393:66:393:81 | access to property Key : A | semmle.label | access to property Key : A | | CollectionFlow.cs:395:49:395:52 | args [element] : A | semmle.label | args [element] : A | | CollectionFlow.cs:395:49:395:52 | args [element] : A | semmle.label | args [element] : A | | CollectionFlow.cs:395:63:395:66 | access to parameter args [element] : A | semmle.label | access to parameter args [element] : A | | CollectionFlow.cs:395:63:395:66 | access to parameter args [element] : A | semmle.label | access to parameter args [element] : A | | CollectionFlow.cs:395:63:395:69 | access to array element | semmle.label | access to array element | +subpaths +| CollectionFlow.cs:17:20:17:22 | access to local variable as [element] : A | CollectionFlow.cs:381:34:381:35 | ts [element] : A | CollectionFlow.cs:381:41:381:45 | access to array element : A | CollectionFlow.cs:17:14:17:23 | call to method First : A | +| CollectionFlow.cs:35:20:35:23 | access to field As [element] : A | CollectionFlow.cs:381:34:381:35 | ts [element] : A | CollectionFlow.cs:381:41:381:45 | access to array element : A | CollectionFlow.cs:35:14:35:24 | call to method First : A | +| CollectionFlow.cs:54:20:54:22 | access to local variable as [element] : A | CollectionFlow.cs:381:34:381:35 | ts [element] : A | CollectionFlow.cs:381:41:381:45 | access to array element : A | CollectionFlow.cs:54:14:54:23 | call to method First : A | +| CollectionFlow.cs:74:24:74:27 | access to local variable list [element] : A | CollectionFlow.cs:383:43:383:46 | list [element] : A | CollectionFlow.cs:383:52:383:58 | access to indexer : A | CollectionFlow.cs:74:14:74:28 | call to method ListFirst : A | +| CollectionFlow.cs:92:24:92:27 | access to local variable list [element] : A | CollectionFlow.cs:383:43:383:46 | list [element] : A | CollectionFlow.cs:383:52:383:58 | access to indexer : A | CollectionFlow.cs:92:14:92:28 | call to method ListFirst : A | +| CollectionFlow.cs:110:24:110:27 | access to local variable list [element] : A | CollectionFlow.cs:383:43:383:46 | list [element] : A | CollectionFlow.cs:383:52:383:58 | access to indexer : A | CollectionFlow.cs:110:14:110:28 | call to method ListFirst : A | +| CollectionFlow.cs:129:28:129:31 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:385:58:385:61 | dict [element, property Value] : A | CollectionFlow.cs:385:67:385:73 | access to indexer : A | CollectionFlow.cs:129:14:129:32 | call to method DictIndexZero : A | +| CollectionFlow.cs:130:29:130:32 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:387:59:387:62 | dict [element, property Value] : A | CollectionFlow.cs:387:68:387:85 | access to property Value : A | CollectionFlow.cs:130:14:130:33 | call to method DictFirstValue : A | +| CollectionFlow.cs:131:30:131:33 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:389:60:389:63 | dict [element, property Value] : A | CollectionFlow.cs:389:69:389:87 | call to method First : A | CollectionFlow.cs:131:14:131:34 | call to method DictValuesFirst : A | +| CollectionFlow.cs:151:28:151:31 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:385:58:385:61 | dict [element, property Value] : A | CollectionFlow.cs:385:67:385:73 | access to indexer : A | CollectionFlow.cs:151:14:151:32 | call to method DictIndexZero : A | +| CollectionFlow.cs:152:29:152:32 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:387:59:387:62 | dict [element, property Value] : A | CollectionFlow.cs:387:68:387:85 | access to property Value : A | CollectionFlow.cs:152:14:152:33 | call to method DictFirstValue : A | +| CollectionFlow.cs:153:30:153:33 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:389:60:389:63 | dict [element, property Value] : A | CollectionFlow.cs:389:69:389:87 | call to method First : A | CollectionFlow.cs:153:14:153:34 | call to method DictValuesFirst : A | +| CollectionFlow.cs:172:28:172:31 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:385:58:385:61 | dict [element, property Value] : A | CollectionFlow.cs:385:67:385:73 | access to indexer : A | CollectionFlow.cs:172:14:172:32 | call to method DictIndexZero : A | +| CollectionFlow.cs:173:29:173:32 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:387:59:387:62 | dict [element, property Value] : A | CollectionFlow.cs:387:68:387:85 | access to property Value : A | CollectionFlow.cs:173:14:173:33 | call to method DictFirstValue : A | +| CollectionFlow.cs:174:30:174:33 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:389:60:389:63 | dict [element, property Value] : A | CollectionFlow.cs:389:69:389:87 | call to method First : A | CollectionFlow.cs:174:14:174:34 | call to method DictValuesFirst : A | +| CollectionFlow.cs:194:28:194:31 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:391:58:391:61 | dict [element, property Key] : A | CollectionFlow.cs:391:67:391:83 | call to method First : A | CollectionFlow.cs:194:14:194:32 | call to method DictKeysFirst : A | +| CollectionFlow.cs:195:27:195:30 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:393:57:393:60 | dict [element, property Key] : A | CollectionFlow.cs:393:66:393:81 | access to property Key : A | CollectionFlow.cs:195:14:195:31 | call to method DictFirstKey : A | +| CollectionFlow.cs:213:28:213:31 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:391:58:391:61 | dict [element, property Key] : A | CollectionFlow.cs:391:67:391:83 | call to method First : A | CollectionFlow.cs:213:14:213:32 | call to method DictKeysFirst : A | +| CollectionFlow.cs:214:27:214:30 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:393:57:393:60 | dict [element, property Key] : A | CollectionFlow.cs:393:66:393:81 | access to property Key : A | CollectionFlow.cs:214:14:214:31 | call to method DictFirstKey : A | +| CollectionFlow.cs:307:23:307:23 | access to local variable a : A | CollectionFlow.cs:301:32:301:38 | element : A | CollectionFlow.cs:301:44:301:48 | [post] access to parameter array [element] : A | CollectionFlow.cs:307:18:307:20 | [post] access to local variable as [element] : A | +| CollectionFlow.cs:310:20:310:22 | access to local variable as [element] : A | CollectionFlow.cs:381:34:381:35 | ts [element] : A | CollectionFlow.cs:381:41:381:45 | access to array element : A | CollectionFlow.cs:310:14:310:23 | call to method First : A | +| CollectionFlow.cs:329:23:329:23 | access to local variable a : A | CollectionFlow.cs:323:34:323:40 | element : A | CollectionFlow.cs:323:46:323:49 | [post] access to parameter list [element] : A | CollectionFlow.cs:329:17:329:20 | [post] access to local variable list [element] : A | +| CollectionFlow.cs:332:24:332:27 | access to local variable list [element] : A | CollectionFlow.cs:383:43:383:46 | list [element] : A | CollectionFlow.cs:383:52:383:58 | access to indexer : A | CollectionFlow.cs:332:14:332:28 | call to method ListFirst : A | #select | CollectionFlow.cs:13:17:13:23 | object creation of type A : A | CollectionFlow.cs:13:17:13:23 | object creation of type A : A | CollectionFlow.cs:15:14:15:19 | access to array element | $@ | CollectionFlow.cs:15:14:15:19 | access to array element | access to array element | | CollectionFlow.cs:13:17:13:23 | object creation of type A : A | CollectionFlow.cs:13:17:13:23 | object creation of type A : A | CollectionFlow.cs:17:14:17:23 | call to method First | $@ | CollectionFlow.cs:17:14:17:23 | call to method First | call to method First | diff --git a/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.expected b/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.expected index 4425219b2cc..ecc6b95c817 100644 --- a/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.expected @@ -45,6 +45,9 @@ edges | ExternalFlow.cs:91:30:91:30 | SSA def(i) : Int32 | ExternalFlow.cs:92:18:92:18 | (...) ... | | ExternalFlow.cs:121:46:121:46 | s : Object | ExternalFlow.cs:60:35:60:35 | o : Object | | ExternalFlow.cs:123:34:123:41 | elements [element] : Object | ExternalFlow.cs:72:23:72:23 | o : Object | +| ExternalFlow.cs:123:34:123:41 | elements [element] : Object | ExternalFlow.cs:72:23:72:23 | o : Object | +| ExternalFlow.cs:123:34:123:41 | elements [element] : Object | ExternalFlow.cs:123:34:123:41 | elements [element] : Object | +| ExternalFlow.cs:123:34:123:41 | elements [element] : Object | ExternalFlow.cs:123:34:123:41 | elements [element] : Object | nodes | ExternalFlow.cs:9:27:9:38 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | | ExternalFlow.cs:10:18:10:33 | call to method StepArgRes | semmle.label | call to method StepArgRes | @@ -106,6 +109,8 @@ nodes | ExternalFlow.cs:92:18:92:18 | (...) ... | semmle.label | (...) ... | | ExternalFlow.cs:121:46:121:46 | s : Object | semmle.label | s : Object | | ExternalFlow.cs:123:34:123:41 | elements [element] : Object | semmle.label | elements [element] : Object | +| ExternalFlow.cs:123:34:123:41 | elements [element] : Object | semmle.label | elements [element] : Object | +subpaths invalidModelRow #select | ExternalFlow.cs:10:18:10:33 | call to method StepArgRes | ExternalFlow.cs:9:27:9:38 | object creation of type Object : Object | ExternalFlow.cs:10:18:10:33 | call to method StepArgRes | $@ | ExternalFlow.cs:9:27:9:38 | object creation of type Object : Object | object creation of type Object : Object | diff --git a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected index 46dfd50b07a..e8a74f347dc 100644 --- a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected @@ -2,18 +2,33 @@ edges | A.cs:5:17:5:23 | object creation of type C : C | A.cs:6:24:6:24 | access to local variable c : C | | A.cs:6:17:6:25 | call to method Make [field c] : C | A.cs:7:14:7:14 | access to local variable b [field c] : C | | A.cs:6:24:6:24 | access to local variable c : C | A.cs:6:17:6:25 | call to method Make [field c] : C | +| A.cs:6:24:6:24 | access to local variable c : C | A.cs:147:32:147:32 | c : C | | A.cs:7:14:7:14 | access to local variable b [field c] : C | A.cs:7:14:7:16 | access to field c | | A.cs:13:9:13:9 | [post] access to local variable b [field c] : C1 | A.cs:14:14:14:14 | access to local variable b [field c] : C1 | | A.cs:13:15:13:22 | object creation of type C1 : C1 | A.cs:13:9:13:9 | [post] access to local variable b [field c] : C1 | +| A.cs:13:15:13:22 | object creation of type C1 : C1 | A.cs:145:27:145:27 | c : C1 | | A.cs:14:14:14:14 | access to local variable b [field c] : C1 | A.cs:14:14:14:20 | call to method Get | +| A.cs:14:14:14:14 | access to local variable b [field c] : C1 | A.cs:146:18:146:20 | this [field c] : C1 | | A.cs:15:15:15:28 | object creation of type B [field c] : C | A.cs:15:14:15:35 | call to method Get | +| A.cs:15:15:15:28 | object creation of type B [field c] : C | A.cs:146:18:146:20 | this [field c] : C | | A.cs:15:21:15:27 | object creation of type C : C | A.cs:15:15:15:28 | object creation of type B [field c] : C | +| A.cs:15:21:15:27 | object creation of type C : C | A.cs:141:20:141:20 | c : C | | A.cs:22:14:22:33 | call to method SetOnB [field c] : C2 | A.cs:24:14:24:15 | access to local variable b2 [field c] : C2 | | A.cs:22:25:22:32 | object creation of type C2 : C2 | A.cs:22:14:22:33 | call to method SetOnB [field c] : C2 | +| A.cs:22:25:22:32 | object creation of type C2 : C2 | A.cs:42:29:42:29 | c : C2 | | A.cs:24:14:24:15 | access to local variable b2 [field c] : C2 | A.cs:24:14:24:17 | access to field c | | A.cs:31:14:31:37 | call to method SetOnBWrap [field c] : C2 | A.cs:33:14:33:15 | access to local variable b2 [field c] : C2 | | A.cs:31:29:31:36 | object creation of type C2 : C2 | A.cs:31:14:31:37 | call to method SetOnBWrap [field c] : C2 | +| A.cs:31:29:31:36 | object creation of type C2 : C2 | A.cs:36:33:36:33 | c : C2 | | A.cs:33:14:33:15 | access to local variable b2 [field c] : C2 | A.cs:33:14:33:17 | access to field c | +| A.cs:36:33:36:33 | c : C2 | A.cs:38:29:38:29 | access to parameter c : C2 | +| A.cs:38:18:38:30 | call to method SetOnB [field c] : C2 | A.cs:39:16:39:28 | ... ? ... : ... [field c] : C2 | +| A.cs:38:29:38:29 | access to parameter c : C2 | A.cs:38:18:38:30 | call to method SetOnB [field c] : C2 | +| A.cs:38:29:38:29 | access to parameter c : C2 | A.cs:42:29:42:29 | c : C2 | +| A.cs:42:29:42:29 | c : C2 | A.cs:47:20:47:20 | access to parameter c : C2 | +| A.cs:47:13:47:14 | [post] access to local variable b2 [field c] : C2 | A.cs:48:20:48:21 | access to local variable b2 [field c] : C2 | +| A.cs:47:20:47:20 | access to parameter c : C2 | A.cs:47:13:47:14 | [post] access to local variable b2 [field c] : C2 | +| A.cs:47:20:47:20 | access to parameter c : C2 | A.cs:145:27:145:27 | c : C2 | | A.cs:55:17:55:23 | object creation of type A : A | A.cs:57:16:57:16 | access to local variable a : A | | A.cs:57:9:57:10 | [post] access to local variable c1 [field a] : A | A.cs:58:12:58:13 | access to local variable c1 [field a] : A | | A.cs:57:16:57:16 | access to local variable a : A | A.cs:57:9:57:10 | [post] access to local variable c1 [field a] : A | @@ -22,20 +37,25 @@ edges | A.cs:64:19:64:23 | (...) ... [field a] : A | A.cs:64:18:64:26 | access to field a | | A.cs:83:9:83:9 | [post] access to parameter b [field c] : C | A.cs:88:12:88:12 | [post] access to local variable b [field c] : C | | A.cs:83:15:83:21 | object creation of type C : C | A.cs:83:9:83:9 | [post] access to parameter b [field c] : C | +| A.cs:83:15:83:21 | object creation of type C : C | A.cs:145:27:145:27 | c : C | | A.cs:88:12:88:12 | [post] access to local variable b [field c] : C | A.cs:89:14:89:14 | access to local variable b [field c] : C | | A.cs:89:14:89:14 | access to local variable b [field c] : C | A.cs:89:14:89:16 | access to field c | +| A.cs:95:20:95:20 | b : B | A.cs:97:13:97:13 | access to parameter b : B | | A.cs:97:13:97:13 | [post] access to parameter b [field c] : C | A.cs:98:22:98:36 | ... ? ... : ... [field c] : C | | A.cs:97:13:97:13 | [post] access to parameter b [field c] : C | A.cs:105:23:105:23 | [post] access to local variable b [field c] : C | +| A.cs:97:13:97:13 | access to parameter b : B | A.cs:98:22:98:36 | ... ? ... : ... : B | | A.cs:97:19:97:25 | object creation of type C : C | A.cs:97:13:97:13 | [post] access to parameter b [field c] : C | | A.cs:98:13:98:16 | [post] this access [field b, field c] : C | A.cs:105:17:105:29 | object creation of type D [field b, field c] : C | | A.cs:98:13:98:16 | [post] this access [field b] : B | A.cs:105:17:105:29 | object creation of type D [field b] : B | | A.cs:98:22:98:36 | ... ? ... : ... : B | A.cs:98:13:98:16 | [post] this access [field b] : B | +| A.cs:98:22:98:36 | ... ? ... : ... : B | A.cs:98:13:98:16 | [post] this access [field b] : B | | A.cs:98:22:98:36 | ... ? ... : ... [field c] : C | A.cs:98:13:98:16 | [post] this access [field b, field c] : C | | A.cs:98:30:98:36 | object creation of type B : B | A.cs:98:22:98:36 | ... ? ... : ... : B | | A.cs:104:17:104:23 | object creation of type B : B | A.cs:105:23:105:23 | access to local variable b : B | | A.cs:105:17:105:29 | object creation of type D [field b, field c] : C | A.cs:107:14:107:14 | access to local variable d [field b, field c] : C | | A.cs:105:17:105:29 | object creation of type D [field b] : B | A.cs:106:14:106:14 | access to local variable d [field b] : B | | A.cs:105:23:105:23 | [post] access to local variable b [field c] : C | A.cs:108:14:108:14 | access to local variable b [field c] : C | +| A.cs:105:23:105:23 | access to local variable b : B | A.cs:95:20:95:20 | b : B | | A.cs:105:23:105:23 | access to local variable b : B | A.cs:105:17:105:29 | object creation of type D [field b] : B | | A.cs:106:14:106:14 | access to local variable d [field b] : B | A.cs:106:14:106:16 | access to field b | | A.cs:107:14:107:14 | access to local variable d [field b, field c] : C | A.cs:107:14:107:16 | access to field b [field c] : C | @@ -44,11 +64,14 @@ edges | A.cs:113:17:113:23 | object creation of type B : B | A.cs:114:29:114:29 | access to local variable b : B | | A.cs:114:18:114:54 | object creation of type MyList [field head] : B | A.cs:115:35:115:36 | access to local variable l1 [field head] : B | | A.cs:114:29:114:29 | access to local variable b : B | A.cs:114:18:114:54 | object creation of type MyList [field head] : B | +| A.cs:114:29:114:29 | access to local variable b : B | A.cs:157:25:157:28 | head : B | | A.cs:115:18:115:37 | object creation of type MyList [field next, field head] : B | A.cs:116:35:116:36 | access to local variable l2 [field next, field head] : B | | A.cs:115:35:115:36 | access to local variable l1 [field head] : B | A.cs:115:18:115:37 | object creation of type MyList [field next, field head] : B | +| A.cs:115:35:115:36 | access to local variable l1 [field head] : B | A.cs:157:38:157:41 | next [field head] : B | | A.cs:116:18:116:37 | object creation of type MyList [field next, field next, field head] : B | A.cs:119:14:119:15 | access to local variable l3 [field next, field next, field head] : B | | A.cs:116:18:116:37 | object creation of type MyList [field next, field next, field head] : B | A.cs:121:41:121:41 | access to local variable l [field next, field next, field head] : B | | A.cs:116:35:116:36 | access to local variable l2 [field next, field head] : B | A.cs:116:18:116:37 | object creation of type MyList [field next, field next, field head] : B | +| A.cs:116:35:116:36 | access to local variable l2 [field next, field head] : B | A.cs:157:38:157:41 | next [field next, field head] : B | | A.cs:119:14:119:15 | access to local variable l3 [field next, field next, field head] : B | A.cs:119:14:119:20 | access to field next [field next, field head] : B | | A.cs:119:14:119:20 | access to field next [field next, field head] : B | A.cs:119:14:119:25 | access to field next [field head] : B | | A.cs:119:14:119:25 | access to field next [field head] : B | A.cs:119:14:119:30 | access to field head | @@ -57,20 +80,53 @@ edges | A.cs:121:41:121:46 | access to field next [field head] : B | A.cs:123:18:123:18 | access to local variable l [field head] : B | | A.cs:121:41:121:46 | access to field next [field next, field head] : B | A.cs:121:41:121:41 | access to local variable l [field next, field head] : B | | A.cs:123:18:123:18 | access to local variable l [field head] : B | A.cs:123:18:123:23 | access to field head | +| A.cs:141:20:141:20 | c : C | A.cs:143:22:143:22 | access to parameter c : C | +| A.cs:143:22:143:22 | access to parameter c : C | A.cs:143:13:143:16 | [post] this access [field c] : C | +| A.cs:145:27:145:27 | c : C | A.cs:145:41:145:41 | access to parameter c : C | +| A.cs:145:27:145:27 | c : C1 | A.cs:145:41:145:41 | access to parameter c : C1 | +| A.cs:145:27:145:27 | c : C2 | A.cs:145:41:145:41 | access to parameter c : C2 | +| A.cs:145:41:145:41 | access to parameter c : C | A.cs:145:32:145:35 | [post] this access [field c] : C | +| A.cs:145:41:145:41 | access to parameter c : C1 | A.cs:145:32:145:35 | [post] this access [field c] : C1 | +| A.cs:145:41:145:41 | access to parameter c : C2 | A.cs:145:32:145:35 | [post] this access [field c] : C2 | +| A.cs:146:18:146:20 | this [field c] : C | A.cs:146:33:146:36 | this access [field c] : C | +| A.cs:146:18:146:20 | this [field c] : C1 | A.cs:146:33:146:36 | this access [field c] : C1 | +| A.cs:146:33:146:36 | this access [field c] : C | A.cs:146:33:146:38 | access to field c : C | +| A.cs:146:33:146:36 | this access [field c] : C1 | A.cs:146:33:146:38 | access to field c : C1 | +| A.cs:147:32:147:32 | c : C | A.cs:149:26:149:26 | access to parameter c : C | +| A.cs:149:26:149:26 | access to parameter c : C | A.cs:141:20:141:20 | c : C | +| A.cs:149:26:149:26 | access to parameter c : C | A.cs:149:20:149:27 | object creation of type B [field c] : C | +| A.cs:157:25:157:28 | head : B | A.cs:159:25:159:28 | access to parameter head : B | +| A.cs:157:38:157:41 | next [field head] : B | A.cs:160:25:160:28 | access to parameter next [field head] : B | +| A.cs:157:38:157:41 | next [field next, field head] : B | A.cs:160:25:160:28 | access to parameter next [field next, field head] : B | +| A.cs:159:25:159:28 | access to parameter head : B | A.cs:159:13:159:16 | [post] this access [field head] : B | +| A.cs:160:25:160:28 | access to parameter next [field head] : B | A.cs:160:13:160:16 | [post] this access [field next, field head] : B | +| A.cs:160:25:160:28 | access to parameter next [field next, field head] : B | A.cs:160:13:160:16 | [post] this access [field next, field next, field head] : B | | B.cs:5:17:5:26 | object creation of type Elem : Elem | B.cs:6:27:6:27 | access to local variable e : Elem | | B.cs:6:18:6:34 | object creation of type Box1 [field elem1] : Elem | B.cs:7:27:7:28 | access to local variable b1 [field elem1] : Elem | | B.cs:6:27:6:27 | access to local variable e : Elem | B.cs:6:18:6:34 | object creation of type Box1 [field elem1] : Elem | +| B.cs:6:27:6:27 | access to local variable e : Elem | B.cs:29:26:29:27 | e1 : Elem | | B.cs:7:18:7:29 | object creation of type Box2 [field box1, field elem1] : Elem | B.cs:8:14:8:15 | access to local variable b2 [field box1, field elem1] : Elem | | B.cs:7:27:7:28 | access to local variable b1 [field elem1] : Elem | B.cs:7:18:7:29 | object creation of type Box2 [field box1, field elem1] : Elem | +| B.cs:7:27:7:28 | access to local variable b1 [field elem1] : Elem | B.cs:39:26:39:27 | b1 [field elem1] : Elem | | B.cs:8:14:8:15 | access to local variable b2 [field box1, field elem1] : Elem | B.cs:8:14:8:20 | access to field box1 [field elem1] : Elem | | B.cs:8:14:8:20 | access to field box1 [field elem1] : Elem | B.cs:8:14:8:26 | access to field elem1 | | B.cs:14:17:14:26 | object creation of type Elem : Elem | B.cs:15:33:15:33 | access to local variable e : Elem | | B.cs:15:18:15:34 | object creation of type Box1 [field elem2] : Elem | B.cs:16:27:16:28 | access to local variable b1 [field elem2] : Elem | | B.cs:15:33:15:33 | access to local variable e : Elem | B.cs:15:18:15:34 | object creation of type Box1 [field elem2] : Elem | +| B.cs:15:33:15:33 | access to local variable e : Elem | B.cs:29:35:29:36 | e2 : Elem | | B.cs:16:18:16:29 | object creation of type Box2 [field box1, field elem2] : Elem | B.cs:18:14:18:15 | access to local variable b2 [field box1, field elem2] : Elem | | B.cs:16:27:16:28 | access to local variable b1 [field elem2] : Elem | B.cs:16:18:16:29 | object creation of type Box2 [field box1, field elem2] : Elem | +| B.cs:16:27:16:28 | access to local variable b1 [field elem2] : Elem | B.cs:39:26:39:27 | b1 [field elem2] : Elem | | B.cs:18:14:18:15 | access to local variable b2 [field box1, field elem2] : Elem | B.cs:18:14:18:20 | access to field box1 [field elem2] : Elem | | B.cs:18:14:18:20 | access to field box1 [field elem2] : Elem | B.cs:18:14:18:26 | access to field elem2 | +| B.cs:29:26:29:27 | e1 : Elem | B.cs:31:26:31:27 | access to parameter e1 : Elem | +| B.cs:29:35:29:36 | e2 : Elem | B.cs:32:26:32:27 | access to parameter e2 : Elem | +| B.cs:31:26:31:27 | access to parameter e1 : Elem | B.cs:31:13:31:16 | [post] this access [field elem1] : Elem | +| B.cs:32:26:32:27 | access to parameter e2 : Elem | B.cs:32:13:32:16 | [post] this access [field elem2] : Elem | +| B.cs:39:26:39:27 | b1 [field elem1] : Elem | B.cs:41:25:41:26 | access to parameter b1 [field elem1] : Elem | +| B.cs:39:26:39:27 | b1 [field elem2] : Elem | B.cs:41:25:41:26 | access to parameter b1 [field elem2] : Elem | +| B.cs:41:25:41:26 | access to parameter b1 [field elem1] : Elem | B.cs:41:13:41:16 | [post] this access [field box1, field elem1] : Elem | +| B.cs:41:25:41:26 | access to parameter b1 [field elem2] : Elem | B.cs:41:13:41:16 | [post] this access [field box1, field elem2] : Elem | | C.cs:3:18:3:19 | [post] this access [field s1] : Elem | C.cs:12:15:12:21 | object creation of type C [field s1] : Elem | | C.cs:3:23:3:32 | object creation of type Elem : Elem | C.cs:3:18:3:19 | [post] this access [field s1] : Elem | | C.cs:4:27:4:28 | [post] this access [field s2] : Elem | C.cs:12:15:12:21 | object creation of type C [field s2] : Elem | @@ -97,38 +153,77 @@ edges | C.cs:24:14:24:15 | this access [field s2] : Elem | C.cs:24:14:24:15 | access to field s2 | | C.cs:25:14:25:15 | this access [field s3] : Elem | C.cs:25:14:25:15 | access to field s3 | | C.cs:27:14:27:15 | this access [property s5] : Elem | C.cs:27:14:27:15 | access to property s5 | +| D.cs:8:9:8:11 | this [field trivialPropField] : Object | D.cs:8:22:8:25 | this access [field trivialPropField] : Object | +| D.cs:8:22:8:25 | this access [field trivialPropField] : Object | D.cs:8:22:8:42 | access to field trivialPropField : Object | +| D.cs:9:9:9:11 | value : Object | D.cs:9:39:9:43 | access to parameter value : Object | +| D.cs:9:39:9:43 | access to parameter value : Object | D.cs:9:15:9:18 | [post] this access [field trivialPropField] : Object | +| D.cs:14:9:14:11 | this [field trivialPropField] : Object | D.cs:14:22:14:25 | this access [field trivialPropField] : Object | +| D.cs:14:22:14:25 | this access [field trivialPropField] : Object | D.cs:14:22:14:42 | access to field trivialPropField : Object | +| D.cs:15:9:15:11 | value : Object | D.cs:15:34:15:38 | access to parameter value : Object | +| D.cs:15:34:15:38 | access to parameter value : Object | D.cs:9:9:9:11 | value : Object | +| D.cs:15:34:15:38 | access to parameter value : Object | D.cs:15:15:15:18 | [post] this access [field trivialPropField] : Object | +| D.cs:18:28:18:29 | o1 : Object | D.cs:21:24:21:25 | access to parameter o1 : Object | +| D.cs:18:39:18:40 | o2 : Object | D.cs:22:27:22:28 | access to parameter o2 : Object | +| D.cs:18:50:18:51 | o3 : Object | D.cs:23:27:23:28 | access to parameter o3 : Object | +| D.cs:21:9:21:11 | [post] access to local variable ret [property AutoProp] : Object | D.cs:24:16:24:18 | access to local variable ret [property AutoProp] : Object | +| D.cs:21:24:21:25 | access to parameter o1 : Object | D.cs:21:9:21:11 | [post] access to local variable ret [property AutoProp] : Object | +| D.cs:22:9:22:11 | [post] access to local variable ret [field trivialPropField] : Object | D.cs:24:16:24:18 | access to local variable ret [field trivialPropField] : Object | +| D.cs:22:27:22:28 | access to parameter o2 : Object | D.cs:9:9:9:11 | value : Object | +| D.cs:22:27:22:28 | access to parameter o2 : Object | D.cs:22:9:22:11 | [post] access to local variable ret [field trivialPropField] : Object | +| D.cs:23:9:23:11 | [post] access to local variable ret [field trivialPropField] : Object | D.cs:24:16:24:18 | access to local variable ret [field trivialPropField] : Object | +| D.cs:23:27:23:28 | access to parameter o3 : Object | D.cs:15:9:15:11 | value : Object | +| D.cs:23:27:23:28 | access to parameter o3 : Object | D.cs:23:9:23:11 | [post] access to local variable ret [field trivialPropField] : Object | | D.cs:29:17:29:28 | object creation of type Object : Object | D.cs:31:24:31:24 | access to local variable o : Object | | D.cs:29:17:29:28 | object creation of type Object : Object | D.cs:37:26:37:26 | access to local variable o : Object | | D.cs:29:17:29:28 | object creation of type Object : Object | D.cs:43:32:43:32 | access to local variable o : Object | | D.cs:31:17:31:37 | call to method Create [property AutoProp] : Object | D.cs:32:14:32:14 | access to local variable d [property AutoProp] : Object | +| D.cs:31:24:31:24 | access to local variable o : Object | D.cs:18:28:18:29 | o1 : Object | | D.cs:31:24:31:24 | access to local variable o : Object | D.cs:31:17:31:37 | call to method Create [property AutoProp] : Object | | D.cs:32:14:32:14 | access to local variable d [property AutoProp] : Object | D.cs:32:14:32:23 | access to property AutoProp | | D.cs:37:13:37:33 | call to method Create [field trivialPropField] : Object | D.cs:39:14:39:14 | access to local variable d [field trivialPropField] : Object | | D.cs:37:13:37:33 | call to method Create [field trivialPropField] : Object | D.cs:40:14:40:14 | access to local variable d [field trivialPropField] : Object | | D.cs:37:13:37:33 | call to method Create [field trivialPropField] : Object | D.cs:41:14:41:14 | access to local variable d [field trivialPropField] : Object | +| D.cs:37:26:37:26 | access to local variable o : Object | D.cs:18:39:18:40 | o2 : Object | | D.cs:37:26:37:26 | access to local variable o : Object | D.cs:37:13:37:33 | call to method Create [field trivialPropField] : Object | +| D.cs:39:14:39:14 | access to local variable d [field trivialPropField] : Object | D.cs:8:9:8:11 | this [field trivialPropField] : Object | | D.cs:39:14:39:14 | access to local variable d [field trivialPropField] : Object | D.cs:39:14:39:26 | access to property TrivialProp | | D.cs:40:14:40:14 | access to local variable d [field trivialPropField] : Object | D.cs:40:14:40:31 | access to field trivialPropField | +| D.cs:41:14:41:14 | access to local variable d [field trivialPropField] : Object | D.cs:14:9:14:11 | this [field trivialPropField] : Object | | D.cs:41:14:41:14 | access to local variable d [field trivialPropField] : Object | D.cs:41:14:41:26 | access to property ComplexProp | | D.cs:43:13:43:33 | call to method Create [field trivialPropField] : Object | D.cs:45:14:45:14 | access to local variable d [field trivialPropField] : Object | | D.cs:43:13:43:33 | call to method Create [field trivialPropField] : Object | D.cs:46:14:46:14 | access to local variable d [field trivialPropField] : Object | | D.cs:43:13:43:33 | call to method Create [field trivialPropField] : Object | D.cs:47:14:47:14 | access to local variable d [field trivialPropField] : Object | +| D.cs:43:32:43:32 | access to local variable o : Object | D.cs:18:50:18:51 | o3 : Object | | D.cs:43:32:43:32 | access to local variable o : Object | D.cs:43:13:43:33 | call to method Create [field trivialPropField] : Object | +| D.cs:45:14:45:14 | access to local variable d [field trivialPropField] : Object | D.cs:8:9:8:11 | this [field trivialPropField] : Object | | D.cs:45:14:45:14 | access to local variable d [field trivialPropField] : Object | D.cs:45:14:45:26 | access to property TrivialProp | | D.cs:46:14:46:14 | access to local variable d [field trivialPropField] : Object | D.cs:46:14:46:31 | access to field trivialPropField | +| D.cs:47:14:47:14 | access to local variable d [field trivialPropField] : Object | D.cs:14:9:14:11 | this [field trivialPropField] : Object | | D.cs:47:14:47:14 | access to local variable d [field trivialPropField] : Object | D.cs:47:14:47:26 | access to property ComplexProp | +| E.cs:8:29:8:29 | o : Object | E.cs:11:21:11:21 | access to parameter o : Object | +| E.cs:11:9:11:11 | [post] access to local variable ret [field Field] : Object | E.cs:12:16:12:18 | access to local variable ret [field Field] : Object | +| E.cs:11:21:11:21 | access to parameter o : Object | E.cs:11:9:11:11 | [post] access to local variable ret [field Field] : Object | | E.cs:22:17:22:28 | object creation of type Object : Object | E.cs:23:25:23:25 | access to local variable o : Object | | E.cs:23:17:23:26 | call to method CreateS [field Field] : Object | E.cs:24:14:24:14 | access to local variable s [field Field] : Object | +| E.cs:23:25:23:25 | access to local variable o : Object | E.cs:8:29:8:29 | o : Object | | E.cs:23:25:23:25 | access to local variable o : Object | E.cs:23:17:23:26 | call to method CreateS [field Field] : Object | | E.cs:24:14:24:14 | access to local variable s [field Field] : Object | E.cs:24:14:24:20 | access to field Field | +| F.cs:6:28:6:29 | o1 : Object | F.cs:6:65:6:66 | access to parameter o1 : Object | +| F.cs:6:39:6:40 | o2 : Object | F.cs:6:78:6:79 | access to parameter o2 : Object | +| F.cs:6:54:6:81 | { ..., ... } [field Field1] : Object | F.cs:6:46:6:81 | object creation of type F [field Field1] : Object | +| F.cs:6:54:6:81 | { ..., ... } [field Field2] : Object | F.cs:6:46:6:81 | object creation of type F [field Field2] : Object | +| F.cs:6:65:6:66 | access to parameter o1 : Object | F.cs:6:54:6:81 | { ..., ... } [field Field1] : Object | +| F.cs:6:78:6:79 | access to parameter o2 : Object | F.cs:6:54:6:81 | { ..., ... } [field Field2] : Object | | F.cs:10:17:10:28 | object creation of type Object : Object | F.cs:11:24:11:24 | access to local variable o : Object | | F.cs:10:17:10:28 | object creation of type Object : Object | F.cs:15:26:15:26 | access to local variable o : Object | | F.cs:10:17:10:28 | object creation of type Object : Object | F.cs:19:32:19:32 | access to local variable o : Object | | F.cs:10:17:10:28 | object creation of type Object : Object | F.cs:23:32:23:32 | access to local variable o : Object | | F.cs:11:17:11:31 | call to method Create [field Field1] : Object | F.cs:12:14:12:14 | access to local variable f [field Field1] : Object | +| F.cs:11:24:11:24 | access to local variable o : Object | F.cs:6:28:6:29 | o1 : Object | | F.cs:11:24:11:24 | access to local variable o : Object | F.cs:11:17:11:31 | call to method Create [field Field1] : Object | | F.cs:12:14:12:14 | access to local variable f [field Field1] : Object | F.cs:12:14:12:21 | access to field Field1 | | F.cs:15:13:15:27 | call to method Create [field Field2] : Object | F.cs:17:14:17:14 | access to local variable f [field Field2] : Object | +| F.cs:15:26:15:26 | access to local variable o : Object | F.cs:6:39:6:40 | o2 : Object | | F.cs:15:26:15:26 | access to local variable o : Object | F.cs:15:13:15:27 | call to method Create [field Field2] : Object | | F.cs:17:14:17:14 | access to local variable f [field Field2] : Object | F.cs:17:14:17:21 | access to field Field2 | | F.cs:19:21:19:34 | { ..., ... } [field Field1] : Object | F.cs:20:14:20:14 | access to local variable f [field Field1] : Object | @@ -146,6 +241,7 @@ edges | G.cs:17:9:17:9 | [post] access to local variable b [field Box1, field Elem] : Elem | G.cs:18:18:18:18 | access to local variable b [field Box1, field Elem] : Elem | | G.cs:17:9:17:14 | [post] access to field Box1 [field Elem] : Elem | G.cs:17:9:17:9 | [post] access to local variable b [field Box1, field Elem] : Elem | | G.cs:17:24:17:24 | access to local variable e : Elem | G.cs:17:9:17:14 | [post] access to field Box1 [field Elem] : Elem | +| G.cs:17:24:17:24 | access to local variable e : Elem | G.cs:64:34:64:34 | e : Elem | | G.cs:18:18:18:18 | access to local variable b [field Box1, field Elem] : Elem | G.cs:37:38:37:39 | b2 [field Box1, field Elem] : Elem | | G.cs:23:18:23:27 | object creation of type Elem : Elem | G.cs:25:28:25:28 | access to local variable e : Elem | | G.cs:25:9:25:9 | [post] access to local variable b [field Box1, field Elem] : Elem | G.cs:26:18:26:18 | access to local variable b [field Box1, field Elem] : Elem | @@ -156,10 +252,13 @@ edges | G.cs:33:9:33:9 | [post] access to local variable b [field Box1, field Elem] : Elem | G.cs:34:18:34:18 | access to local variable b [field Box1, field Elem] : Elem | | G.cs:33:9:33:19 | [post] call to method GetBox1 [field Elem] : Elem | G.cs:33:9:33:9 | [post] access to local variable b [field Box1, field Elem] : Elem | | G.cs:33:29:33:29 | access to local variable e : Elem | G.cs:33:9:33:19 | [post] call to method GetBox1 [field Elem] : Elem | +| G.cs:33:29:33:29 | access to local variable e : Elem | G.cs:64:34:64:34 | e : Elem | | G.cs:34:18:34:18 | access to local variable b [field Box1, field Elem] : Elem | G.cs:37:38:37:39 | b2 [field Box1, field Elem] : Elem | | G.cs:37:38:37:39 | b2 [field Box1, field Elem] : Elem | G.cs:39:14:39:15 | access to parameter b2 [field Box1, field Elem] : Elem | | G.cs:39:14:39:15 | access to parameter b2 [field Box1, field Elem] : Elem | G.cs:39:14:39:25 | call to method GetBox1 [field Elem] : Elem | +| G.cs:39:14:39:15 | access to parameter b2 [field Box1, field Elem] : Elem | G.cs:71:21:71:27 | this [field Box1, field Elem] : Elem | | G.cs:39:14:39:25 | call to method GetBox1 [field Elem] : Elem | G.cs:39:14:39:35 | call to method GetElem | +| G.cs:39:14:39:25 | call to method GetBox1 [field Elem] : Elem | G.cs:63:21:63:27 | this [field Elem] : Elem | | G.cs:44:18:44:27 | object creation of type Elem : Elem | G.cs:46:30:46:30 | access to local variable e : Elem | | G.cs:46:9:46:16 | [post] access to field boxfield [field Box1, field Elem] : Elem | G.cs:46:9:46:16 | [post] this access [field boxfield, field Box1, field Elem] : Elem | | G.cs:46:9:46:16 | [post] this access [field boxfield, field Box1, field Elem] : Elem | G.cs:47:9:47:13 | this access [field boxfield, field Box1, field Elem] : Elem | @@ -170,44 +269,99 @@ edges | G.cs:52:14:52:21 | access to field boxfield [field Box1, field Elem] : Elem | G.cs:52:14:52:26 | access to field Box1 [field Elem] : Elem | | G.cs:52:14:52:21 | this access [field boxfield, field Box1, field Elem] : Elem | G.cs:52:14:52:21 | access to field boxfield [field Box1, field Elem] : Elem | | G.cs:52:14:52:26 | access to field Box1 [field Elem] : Elem | G.cs:52:14:52:31 | access to field Elem | +| G.cs:63:21:63:27 | this [field Elem] : Elem | G.cs:63:34:63:37 | this access [field Elem] : Elem | +| G.cs:63:34:63:37 | this access [field Elem] : Elem | G.cs:63:34:63:37 | access to field Elem : Elem | +| G.cs:64:34:64:34 | e : Elem | G.cs:64:46:64:46 | access to parameter e : Elem | +| G.cs:64:46:64:46 | access to parameter e : Elem | G.cs:64:39:64:42 | [post] this access [field Elem] : Elem | +| G.cs:71:21:71:27 | this [field Box1, field Elem] : Elem | G.cs:71:34:71:37 | this access [field Box1, field Elem] : Elem | +| G.cs:71:34:71:37 | this access [field Box1, field Elem] : Elem | G.cs:71:34:71:37 | access to field Box1 [field Elem] : Elem | +| H.cs:13:15:13:15 | a [field FieldA] : Object | H.cs:16:22:16:22 | access to parameter a [field FieldA] : Object | +| H.cs:16:9:16:11 | [post] access to local variable ret [field FieldA] : Object | H.cs:17:16:17:18 | access to local variable ret [field FieldA] : Object | +| H.cs:16:22:16:22 | access to parameter a [field FieldA] : Object | H.cs:16:22:16:29 | access to field FieldA : Object | +| H.cs:16:22:16:29 | access to field FieldA : Object | H.cs:16:9:16:11 | [post] access to local variable ret [field FieldA] : Object | | H.cs:23:9:23:9 | [post] access to local variable a [field FieldA] : Object | H.cs:24:27:24:27 | access to local variable a [field FieldA] : Object | | H.cs:23:20:23:31 | object creation of type Object : Object | H.cs:23:9:23:9 | [post] access to local variable a [field FieldA] : Object | | H.cs:24:21:24:28 | call to method Clone [field FieldA] : Object | H.cs:25:14:25:18 | access to local variable clone [field FieldA] : Object | +| H.cs:24:27:24:27 | access to local variable a [field FieldA] : Object | H.cs:13:15:13:15 | a [field FieldA] : Object | | H.cs:24:27:24:27 | access to local variable a [field FieldA] : Object | H.cs:24:21:24:28 | call to method Clone [field FieldA] : Object | | H.cs:25:14:25:18 | access to local variable clone [field FieldA] : Object | H.cs:25:14:25:25 | access to field FieldA | +| H.cs:33:19:33:19 | a [field FieldA] : A | H.cs:36:20:36:20 | access to parameter a [field FieldA] : A | +| H.cs:33:19:33:19 | a [field FieldA] : Object | H.cs:36:20:36:20 | access to parameter a [field FieldA] : Object | +| H.cs:36:9:36:9 | [post] access to local variable b [field FieldB] : A | H.cs:37:16:37:16 | access to local variable b [field FieldB] : A | +| H.cs:36:9:36:9 | [post] access to local variable b [field FieldB] : Object | H.cs:37:16:37:16 | access to local variable b [field FieldB] : Object | +| H.cs:36:20:36:20 | access to parameter a [field FieldA] : A | H.cs:36:20:36:27 | access to field FieldA : A | +| H.cs:36:20:36:20 | access to parameter a [field FieldA] : Object | H.cs:36:20:36:27 | access to field FieldA : Object | +| H.cs:36:20:36:27 | access to field FieldA : A | H.cs:36:9:36:9 | [post] access to local variable b [field FieldB] : A | +| H.cs:36:20:36:27 | access to field FieldA : Object | H.cs:36:9:36:9 | [post] access to local variable b [field FieldB] : Object | | H.cs:43:9:43:9 | [post] access to local variable a [field FieldA] : Object | H.cs:44:27:44:27 | access to local variable a [field FieldA] : Object | | H.cs:43:20:43:31 | object creation of type Object : Object | H.cs:43:9:43:9 | [post] access to local variable a [field FieldA] : Object | | H.cs:44:17:44:28 | call to method Transform [field FieldB] : Object | H.cs:45:14:45:14 | access to local variable b [field FieldB] : Object | +| H.cs:44:27:44:27 | access to local variable a [field FieldA] : Object | H.cs:33:19:33:19 | a [field FieldA] : Object | | H.cs:44:27:44:27 | access to local variable a [field FieldA] : Object | H.cs:44:17:44:28 | call to method Transform [field FieldB] : Object | | H.cs:45:14:45:14 | access to local variable b [field FieldB] : Object | H.cs:45:14:45:21 | access to field FieldB | +| H.cs:53:25:53:25 | a [field FieldA] : Object | H.cs:55:21:55:21 | access to parameter a [field FieldA] : Object | +| H.cs:55:21:55:21 | access to parameter a [field FieldA] : Object | H.cs:55:21:55:28 | access to field FieldA : Object | +| H.cs:55:21:55:28 | access to field FieldA : Object | H.cs:55:9:55:10 | [post] access to parameter b1 [field FieldB] : Object | | H.cs:63:9:63:9 | [post] access to local variable a [field FieldA] : Object | H.cs:64:22:64:22 | access to local variable a [field FieldA] : Object | | H.cs:63:20:63:31 | object creation of type Object : Object | H.cs:63:9:63:9 | [post] access to local variable a [field FieldA] : Object | +| H.cs:64:22:64:22 | access to local variable a [field FieldA] : Object | H.cs:53:25:53:25 | a [field FieldA] : Object | | H.cs:64:22:64:22 | access to local variable a [field FieldA] : Object | H.cs:64:25:64:26 | [post] access to local variable b1 [field FieldB] : Object | | H.cs:64:25:64:26 | [post] access to local variable b1 [field FieldB] : Object | H.cs:65:14:65:15 | access to local variable b1 [field FieldB] : Object | | H.cs:65:14:65:15 | access to local variable b1 [field FieldB] : Object | H.cs:65:14:65:22 | access to field FieldB | +| H.cs:77:30:77:30 | o : Object | H.cs:79:20:79:20 | access to parameter o : Object | +| H.cs:79:9:79:9 | [post] access to parameter a [field FieldA] : Object | H.cs:80:22:80:22 | access to parameter a [field FieldA] : Object | +| H.cs:79:20:79:20 | access to parameter o : Object | H.cs:79:9:79:9 | [post] access to parameter a [field FieldA] : Object | +| H.cs:80:22:80:22 | access to parameter a [field FieldA] : Object | H.cs:53:25:53:25 | a [field FieldA] : Object | +| H.cs:80:22:80:22 | access to parameter a [field FieldA] : Object | H.cs:80:25:80:26 | [post] access to parameter b1 [field FieldB] : Object | | H.cs:88:17:88:17 | [post] access to local variable a [field FieldA] : Object | H.cs:89:14:89:14 | access to local variable a [field FieldA] : Object | +| H.cs:88:20:88:31 | object creation of type Object : Object | H.cs:77:30:77:30 | o : Object | | H.cs:88:20:88:31 | object creation of type Object : Object | H.cs:88:17:88:17 | [post] access to local variable a [field FieldA] : Object | | H.cs:88:20:88:31 | object creation of type Object : Object | H.cs:88:34:88:35 | [post] access to local variable b1 [field FieldB] : Object | | H.cs:88:34:88:35 | [post] access to local variable b1 [field FieldB] : Object | H.cs:90:14:90:15 | access to local variable b1 [field FieldB] : Object | | H.cs:89:14:89:14 | access to local variable a [field FieldA] : Object | H.cs:89:14:89:21 | access to field FieldA | | H.cs:90:14:90:15 | access to local variable b1 [field FieldB] : Object | H.cs:90:14:90:22 | access to field FieldB | +| H.cs:102:23:102:23 | a [field FieldA] : Object | H.cs:105:23:105:23 | access to parameter a [field FieldA] : Object | +| H.cs:105:9:105:12 | [post] access to local variable temp [field FieldB, field FieldA] : Object | H.cs:106:29:106:32 | access to local variable temp [field FieldB, field FieldA] : Object | +| H.cs:105:23:105:23 | access to parameter a [field FieldA] : Object | H.cs:105:9:105:12 | [post] access to local variable temp [field FieldB, field FieldA] : Object | +| H.cs:106:26:106:39 | (...) ... [field FieldA] : Object | H.cs:33:19:33:19 | a [field FieldA] : Object | +| H.cs:106:26:106:39 | (...) ... [field FieldA] : Object | H.cs:106:16:106:40 | call to method Transform [field FieldB] : Object | +| H.cs:106:29:106:32 | access to local variable temp [field FieldB, field FieldA] : Object | H.cs:106:29:106:39 | access to field FieldB [field FieldA] : Object | +| H.cs:106:29:106:39 | access to field FieldB [field FieldA] : Object | H.cs:106:26:106:39 | (...) ... [field FieldA] : Object | | H.cs:112:9:112:9 | [post] access to local variable a [field FieldA] : Object | H.cs:113:31:113:31 | access to local variable a [field FieldA] : Object | | H.cs:112:20:112:31 | object creation of type Object : Object | H.cs:112:9:112:9 | [post] access to local variable a [field FieldA] : Object | | H.cs:113:17:113:32 | call to method TransformWrap [field FieldB] : Object | H.cs:114:14:114:14 | access to local variable b [field FieldB] : Object | +| H.cs:113:31:113:31 | access to local variable a [field FieldA] : Object | H.cs:102:23:102:23 | a [field FieldA] : Object | | H.cs:113:31:113:31 | access to local variable a [field FieldA] : Object | H.cs:113:17:113:32 | call to method TransformWrap [field FieldB] : Object | | H.cs:114:14:114:14 | access to local variable b [field FieldB] : Object | H.cs:114:14:114:21 | access to field FieldB | +| H.cs:122:18:122:18 | a [field FieldA] : Object | H.cs:124:26:124:26 | access to parameter a [field FieldA] : Object | +| H.cs:124:16:124:27 | call to method Transform [field FieldB] : Object | H.cs:124:16:124:34 | access to field FieldB : Object | +| H.cs:124:26:124:26 | access to parameter a [field FieldA] : Object | H.cs:33:19:33:19 | a [field FieldA] : Object | +| H.cs:124:26:124:26 | access to parameter a [field FieldA] : Object | H.cs:124:16:124:27 | call to method Transform [field FieldB] : Object | | H.cs:130:9:130:9 | [post] access to local variable a [field FieldA] : Object | H.cs:131:18:131:18 | access to local variable a [field FieldA] : Object | | H.cs:130:20:130:31 | object creation of type Object : Object | H.cs:130:9:130:9 | [post] access to local variable a [field FieldA] : Object | +| H.cs:131:18:131:18 | access to local variable a [field FieldA] : Object | H.cs:122:18:122:18 | a [field FieldA] : Object | | H.cs:131:18:131:18 | access to local variable a [field FieldA] : Object | H.cs:131:14:131:19 | call to method Get | +| H.cs:138:27:138:27 | o : A | H.cs:141:20:141:25 | ... as ... : A | +| H.cs:141:9:141:9 | [post] access to local variable a [field FieldA] : A | H.cs:142:26:142:26 | access to local variable a [field FieldA] : A | +| H.cs:141:20:141:25 | ... as ... : A | H.cs:141:9:141:9 | [post] access to local variable a [field FieldA] : A | +| H.cs:142:16:142:27 | call to method Transform [field FieldB] : A | H.cs:142:16:142:34 | access to field FieldB : A | +| H.cs:142:26:142:26 | access to local variable a [field FieldA] : A | H.cs:33:19:33:19 | a [field FieldA] : A | +| H.cs:142:26:142:26 | access to local variable a [field FieldA] : A | H.cs:142:16:142:27 | call to method Transform [field FieldB] : A | | H.cs:147:17:147:32 | call to method Through : A | H.cs:148:14:148:14 | access to local variable a | +| H.cs:147:25:147:31 | object creation of type A : A | H.cs:138:27:138:27 | o : A | | H.cs:147:25:147:31 | object creation of type A : A | H.cs:147:17:147:32 | call to method Through : A | +| H.cs:153:32:153:32 | o : Object | H.cs:156:20:156:20 | access to parameter o : Object | | H.cs:155:17:155:23 | object creation of type B : B | H.cs:156:9:156:9 | access to local variable b : B | +| H.cs:156:9:156:9 | [post] access to local variable b [field FieldB] : Object | H.cs:157:20:157:20 | access to local variable b [field FieldB] : Object | | H.cs:156:9:156:9 | access to local variable b : B | H.cs:157:20:157:20 | access to local variable b : B | +| H.cs:156:20:156:20 | access to parameter o : Object | H.cs:156:9:156:9 | [post] access to local variable b [field FieldB] : Object | | H.cs:157:9:157:9 | [post] access to parameter a [field FieldA] : B | H.cs:164:19:164:19 | [post] access to local variable a [field FieldA] : B | | H.cs:157:20:157:20 | access to local variable b : B | H.cs:157:9:157:9 | [post] access to parameter a [field FieldA] : B | +| H.cs:157:20:157:20 | access to local variable b [field FieldB] : Object | H.cs:157:9:157:9 | [post] access to parameter a [field FieldA, field FieldB] : Object | | H.cs:163:17:163:28 | object creation of type Object : Object | H.cs:164:22:164:22 | access to local variable o : Object | | H.cs:164:19:164:19 | [post] access to local variable a [field FieldA, field FieldB] : Object | H.cs:165:21:165:21 | access to local variable a [field FieldA, field FieldB] : Object | | H.cs:164:19:164:19 | [post] access to local variable a [field FieldA] : B | H.cs:165:21:165:21 | access to local variable a [field FieldA] : B | +| H.cs:164:22:164:22 | access to local variable o : Object | H.cs:153:32:153:32 | o : Object | | H.cs:164:22:164:22 | access to local variable o : Object | H.cs:164:19:164:19 | [post] access to local variable a [field FieldA, field FieldB] : Object | | H.cs:165:17:165:28 | (...) ... : B | H.cs:166:14:166:14 | access to local variable b | | H.cs:165:17:165:28 | (...) ... [field FieldB] : Object | H.cs:167:14:167:14 | access to local variable b [field FieldB] : Object | @@ -271,6 +425,14 @@ nodes | A.cs:31:29:31:36 | object creation of type C2 : C2 | semmle.label | object creation of type C2 : C2 | | A.cs:33:14:33:15 | access to local variable b2 [field c] : C2 | semmle.label | access to local variable b2 [field c] : C2 | | A.cs:33:14:33:17 | access to field c | semmle.label | access to field c | +| A.cs:36:33:36:33 | c : C2 | semmle.label | c : C2 | +| A.cs:38:18:38:30 | call to method SetOnB [field c] : C2 | semmle.label | call to method SetOnB [field c] : C2 | +| A.cs:38:29:38:29 | access to parameter c : C2 | semmle.label | access to parameter c : C2 | +| A.cs:39:16:39:28 | ... ? ... : ... [field c] : C2 | semmle.label | ... ? ... : ... [field c] : C2 | +| A.cs:42:29:42:29 | c : C2 | semmle.label | c : C2 | +| A.cs:47:13:47:14 | [post] access to local variable b2 [field c] : C2 | semmle.label | [post] access to local variable b2 [field c] : C2 | +| A.cs:47:20:47:20 | access to parameter c : C2 | semmle.label | access to parameter c : C2 | +| A.cs:48:20:48:21 | access to local variable b2 [field c] : C2 | semmle.label | access to local variable b2 [field c] : C2 | | A.cs:55:17:55:23 | object creation of type A : A | semmle.label | object creation of type A : A | | A.cs:57:9:57:10 | [post] access to local variable c1 [field a] : A | semmle.label | [post] access to local variable c1 [field a] : A | | A.cs:57:16:57:16 | access to local variable a : A | semmle.label | access to local variable a : A | @@ -283,10 +445,14 @@ nodes | A.cs:88:12:88:12 | [post] access to local variable b [field c] : C | semmle.label | [post] access to local variable b [field c] : C | | A.cs:89:14:89:14 | access to local variable b [field c] : C | semmle.label | access to local variable b [field c] : C | | A.cs:89:14:89:16 | access to field c | semmle.label | access to field c | +| A.cs:95:20:95:20 | b : B | semmle.label | b : B | | A.cs:97:13:97:13 | [post] access to parameter b [field c] : C | semmle.label | [post] access to parameter b [field c] : C | +| A.cs:97:13:97:13 | access to parameter b : B | semmle.label | access to parameter b : B | | A.cs:97:19:97:25 | object creation of type C : C | semmle.label | object creation of type C : C | | A.cs:98:13:98:16 | [post] this access [field b, field c] : C | semmle.label | [post] this access [field b, field c] : C | | A.cs:98:13:98:16 | [post] this access [field b] : B | semmle.label | [post] this access [field b] : B | +| A.cs:98:13:98:16 | [post] this access [field b] : B | semmle.label | [post] this access [field b] : B | +| A.cs:98:22:98:36 | ... ? ... : ... : B | semmle.label | ... ? ... : ... : B | | A.cs:98:22:98:36 | ... ? ... : ... : B | semmle.label | ... ? ... : ... : B | | A.cs:98:22:98:36 | ... ? ... : ... [field c] : C | semmle.label | ... ? ... : ... [field c] : C | | A.cs:98:30:98:36 | object creation of type B : B | semmle.label | object creation of type B : B | @@ -319,6 +485,36 @@ nodes | A.cs:121:41:121:46 | access to field next [field next, field head] : B | semmle.label | access to field next [field next, field head] : B | | A.cs:123:18:123:18 | access to local variable l [field head] : B | semmle.label | access to local variable l [field head] : B | | A.cs:123:18:123:23 | access to field head | semmle.label | access to field head | +| A.cs:141:20:141:20 | c : C | semmle.label | c : C | +| A.cs:143:13:143:16 | [post] this access [field c] : C | semmle.label | [post] this access [field c] : C | +| A.cs:143:22:143:22 | access to parameter c : C | semmle.label | access to parameter c : C | +| A.cs:145:27:145:27 | c : C | semmle.label | c : C | +| A.cs:145:27:145:27 | c : C1 | semmle.label | c : C1 | +| A.cs:145:27:145:27 | c : C2 | semmle.label | c : C2 | +| A.cs:145:32:145:35 | [post] this access [field c] : C | semmle.label | [post] this access [field c] : C | +| A.cs:145:32:145:35 | [post] this access [field c] : C1 | semmle.label | [post] this access [field c] : C1 | +| A.cs:145:32:145:35 | [post] this access [field c] : C2 | semmle.label | [post] this access [field c] : C2 | +| A.cs:145:41:145:41 | access to parameter c : C | semmle.label | access to parameter c : C | +| A.cs:145:41:145:41 | access to parameter c : C1 | semmle.label | access to parameter c : C1 | +| A.cs:145:41:145:41 | access to parameter c : C2 | semmle.label | access to parameter c : C2 | +| A.cs:146:18:146:20 | this [field c] : C | semmle.label | this [field c] : C | +| A.cs:146:18:146:20 | this [field c] : C1 | semmle.label | this [field c] : C1 | +| A.cs:146:33:146:36 | this access [field c] : C | semmle.label | this access [field c] : C | +| A.cs:146:33:146:36 | this access [field c] : C1 | semmle.label | this access [field c] : C1 | +| A.cs:146:33:146:38 | access to field c : C | semmle.label | access to field c : C | +| A.cs:146:33:146:38 | access to field c : C1 | semmle.label | access to field c : C1 | +| A.cs:147:32:147:32 | c : C | semmle.label | c : C | +| A.cs:149:20:149:27 | object creation of type B [field c] : C | semmle.label | object creation of type B [field c] : C | +| A.cs:149:26:149:26 | access to parameter c : C | semmle.label | access to parameter c : C | +| A.cs:157:25:157:28 | head : B | semmle.label | head : B | +| A.cs:157:38:157:41 | next [field head] : B | semmle.label | next [field head] : B | +| A.cs:157:38:157:41 | next [field next, field head] : B | semmle.label | next [field next, field head] : B | +| A.cs:159:13:159:16 | [post] this access [field head] : B | semmle.label | [post] this access [field head] : B | +| A.cs:159:25:159:28 | access to parameter head : B | semmle.label | access to parameter head : B | +| A.cs:160:13:160:16 | [post] this access [field next, field head] : B | semmle.label | [post] this access [field next, field head] : B | +| A.cs:160:13:160:16 | [post] this access [field next, field next, field head] : B | semmle.label | [post] this access [field next, field next, field head] : B | +| A.cs:160:25:160:28 | access to parameter next [field head] : B | semmle.label | access to parameter next [field head] : B | +| A.cs:160:25:160:28 | access to parameter next [field next, field head] : B | semmle.label | access to parameter next [field next, field head] : B | | B.cs:5:17:5:26 | object creation of type Elem : Elem | semmle.label | object creation of type Elem : Elem | | B.cs:6:18:6:34 | object creation of type Box1 [field elem1] : Elem | semmle.label | object creation of type Box1 [field elem1] : Elem | | B.cs:6:27:6:27 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | @@ -335,6 +531,18 @@ nodes | B.cs:18:14:18:15 | access to local variable b2 [field box1, field elem2] : Elem | semmle.label | access to local variable b2 [field box1, field elem2] : Elem | | B.cs:18:14:18:20 | access to field box1 [field elem2] : Elem | semmle.label | access to field box1 [field elem2] : Elem | | B.cs:18:14:18:26 | access to field elem2 | semmle.label | access to field elem2 | +| B.cs:29:26:29:27 | e1 : Elem | semmle.label | e1 : Elem | +| B.cs:29:35:29:36 | e2 : Elem | semmle.label | e2 : Elem | +| B.cs:31:13:31:16 | [post] this access [field elem1] : Elem | semmle.label | [post] this access [field elem1] : Elem | +| B.cs:31:26:31:27 | access to parameter e1 : Elem | semmle.label | access to parameter e1 : Elem | +| B.cs:32:13:32:16 | [post] this access [field elem2] : Elem | semmle.label | [post] this access [field elem2] : Elem | +| B.cs:32:26:32:27 | access to parameter e2 : Elem | semmle.label | access to parameter e2 : Elem | +| B.cs:39:26:39:27 | b1 [field elem1] : Elem | semmle.label | b1 [field elem1] : Elem | +| B.cs:39:26:39:27 | b1 [field elem2] : Elem | semmle.label | b1 [field elem2] : Elem | +| B.cs:41:13:41:16 | [post] this access [field box1, field elem1] : Elem | semmle.label | [post] this access [field box1, field elem1] : Elem | +| B.cs:41:13:41:16 | [post] this access [field box1, field elem2] : Elem | semmle.label | [post] this access [field box1, field elem2] : Elem | +| B.cs:41:25:41:26 | access to parameter b1 [field elem1] : Elem | semmle.label | access to parameter b1 [field elem1] : Elem | +| B.cs:41:25:41:26 | access to parameter b1 [field elem2] : Elem | semmle.label | access to parameter b1 [field elem2] : Elem | | C.cs:3:18:3:19 | [post] this access [field s1] : Elem | semmle.label | [post] this access [field s1] : Elem | | C.cs:3:23:3:32 | object creation of type Elem : Elem | semmle.label | object creation of type Elem : Elem | | C.cs:4:27:4:28 | [post] this access [field s2] : Elem | semmle.label | [post] this access [field s2] : Elem | @@ -367,6 +575,30 @@ nodes | C.cs:27:14:27:15 | access to property s5 | semmle.label | access to property s5 | | C.cs:27:14:27:15 | this access [property s5] : Elem | semmle.label | this access [property s5] : Elem | | C.cs:28:14:28:15 | access to property s6 | semmle.label | access to property s6 | +| D.cs:8:9:8:11 | this [field trivialPropField] : Object | semmle.label | this [field trivialPropField] : Object | +| D.cs:8:22:8:25 | this access [field trivialPropField] : Object | semmle.label | this access [field trivialPropField] : Object | +| D.cs:8:22:8:42 | access to field trivialPropField : Object | semmle.label | access to field trivialPropField : Object | +| D.cs:9:9:9:11 | value : Object | semmle.label | value : Object | +| D.cs:9:15:9:18 | [post] this access [field trivialPropField] : Object | semmle.label | [post] this access [field trivialPropField] : Object | +| D.cs:9:39:9:43 | access to parameter value : Object | semmle.label | access to parameter value : Object | +| D.cs:14:9:14:11 | this [field trivialPropField] : Object | semmle.label | this [field trivialPropField] : Object | +| D.cs:14:22:14:25 | this access [field trivialPropField] : Object | semmle.label | this access [field trivialPropField] : Object | +| D.cs:14:22:14:42 | access to field trivialPropField : Object | semmle.label | access to field trivialPropField : Object | +| D.cs:15:9:15:11 | value : Object | semmle.label | value : Object | +| D.cs:15:15:15:18 | [post] this access [field trivialPropField] : Object | semmle.label | [post] this access [field trivialPropField] : Object | +| D.cs:15:34:15:38 | access to parameter value : Object | semmle.label | access to parameter value : Object | +| D.cs:18:28:18:29 | o1 : Object | semmle.label | o1 : Object | +| D.cs:18:39:18:40 | o2 : Object | semmle.label | o2 : Object | +| D.cs:18:50:18:51 | o3 : Object | semmle.label | o3 : Object | +| D.cs:21:9:21:11 | [post] access to local variable ret [property AutoProp] : Object | semmle.label | [post] access to local variable ret [property AutoProp] : Object | +| D.cs:21:24:21:25 | access to parameter o1 : Object | semmle.label | access to parameter o1 : Object | +| D.cs:22:9:22:11 | [post] access to local variable ret [field trivialPropField] : Object | semmle.label | [post] access to local variable ret [field trivialPropField] : Object | +| D.cs:22:27:22:28 | access to parameter o2 : Object | semmle.label | access to parameter o2 : Object | +| D.cs:23:9:23:11 | [post] access to local variable ret [field trivialPropField] : Object | semmle.label | [post] access to local variable ret [field trivialPropField] : Object | +| D.cs:23:27:23:28 | access to parameter o3 : Object | semmle.label | access to parameter o3 : Object | +| D.cs:24:16:24:18 | access to local variable ret [field trivialPropField] : Object | semmle.label | access to local variable ret [field trivialPropField] : Object | +| D.cs:24:16:24:18 | access to local variable ret [field trivialPropField] : Object | semmle.label | access to local variable ret [field trivialPropField] : Object | +| D.cs:24:16:24:18 | access to local variable ret [property AutoProp] : Object | semmle.label | access to local variable ret [property AutoProp] : Object | | D.cs:29:17:29:28 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | | D.cs:31:17:31:37 | call to method Create [property AutoProp] : Object | semmle.label | call to method Create [property AutoProp] : Object | | D.cs:31:24:31:24 | access to local variable o : Object | semmle.label | access to local variable o : Object | @@ -388,11 +620,23 @@ nodes | D.cs:46:14:46:31 | access to field trivialPropField | semmle.label | access to field trivialPropField | | D.cs:47:14:47:14 | access to local variable d [field trivialPropField] : Object | semmle.label | access to local variable d [field trivialPropField] : Object | | D.cs:47:14:47:26 | access to property ComplexProp | semmle.label | access to property ComplexProp | +| E.cs:8:29:8:29 | o : Object | semmle.label | o : Object | +| E.cs:11:9:11:11 | [post] access to local variable ret [field Field] : Object | semmle.label | [post] access to local variable ret [field Field] : Object | +| E.cs:11:21:11:21 | access to parameter o : Object | semmle.label | access to parameter o : Object | +| E.cs:12:16:12:18 | access to local variable ret [field Field] : Object | semmle.label | access to local variable ret [field Field] : Object | | E.cs:22:17:22:28 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | | E.cs:23:17:23:26 | call to method CreateS [field Field] : Object | semmle.label | call to method CreateS [field Field] : Object | | E.cs:23:25:23:25 | access to local variable o : Object | semmle.label | access to local variable o : Object | | E.cs:24:14:24:14 | access to local variable s [field Field] : Object | semmle.label | access to local variable s [field Field] : Object | | E.cs:24:14:24:20 | access to field Field | semmle.label | access to field Field | +| F.cs:6:28:6:29 | o1 : Object | semmle.label | o1 : Object | +| F.cs:6:39:6:40 | o2 : Object | semmle.label | o2 : Object | +| F.cs:6:46:6:81 | object creation of type F [field Field1] : Object | semmle.label | object creation of type F [field Field1] : Object | +| F.cs:6:46:6:81 | object creation of type F [field Field2] : Object | semmle.label | object creation of type F [field Field2] : Object | +| F.cs:6:54:6:81 | { ..., ... } [field Field1] : Object | semmle.label | { ..., ... } [field Field1] : Object | +| F.cs:6:54:6:81 | { ..., ... } [field Field2] : Object | semmle.label | { ..., ... } [field Field2] : Object | +| F.cs:6:65:6:66 | access to parameter o1 : Object | semmle.label | access to parameter o1 : Object | +| F.cs:6:78:6:79 | access to parameter o2 : Object | semmle.label | access to parameter o2 : Object | | F.cs:10:17:10:28 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | | F.cs:11:17:11:31 | call to method Create [field Field1] : Object | semmle.label | call to method Create [field Field1] : Object | | F.cs:11:24:11:24 | access to local variable o : Object | semmle.label | access to local variable o : Object | @@ -445,24 +689,57 @@ nodes | G.cs:52:14:52:21 | this access [field boxfield, field Box1, field Elem] : Elem | semmle.label | this access [field boxfield, field Box1, field Elem] : Elem | | G.cs:52:14:52:26 | access to field Box1 [field Elem] : Elem | semmle.label | access to field Box1 [field Elem] : Elem | | G.cs:52:14:52:31 | access to field Elem | semmle.label | access to field Elem | +| G.cs:63:21:63:27 | this [field Elem] : Elem | semmle.label | this [field Elem] : Elem | +| G.cs:63:34:63:37 | access to field Elem : Elem | semmle.label | access to field Elem : Elem | +| G.cs:63:34:63:37 | this access [field Elem] : Elem | semmle.label | this access [field Elem] : Elem | +| G.cs:64:34:64:34 | e : Elem | semmle.label | e : Elem | +| G.cs:64:39:64:42 | [post] this access [field Elem] : Elem | semmle.label | [post] this access [field Elem] : Elem | +| G.cs:64:46:64:46 | access to parameter e : Elem | semmle.label | access to parameter e : Elem | +| G.cs:71:21:71:27 | this [field Box1, field Elem] : Elem | semmle.label | this [field Box1, field Elem] : Elem | +| G.cs:71:34:71:37 | access to field Box1 [field Elem] : Elem | semmle.label | access to field Box1 [field Elem] : Elem | +| G.cs:71:34:71:37 | this access [field Box1, field Elem] : Elem | semmle.label | this access [field Box1, field Elem] : Elem | +| H.cs:13:15:13:15 | a [field FieldA] : Object | semmle.label | a [field FieldA] : Object | +| H.cs:16:9:16:11 | [post] access to local variable ret [field FieldA] : Object | semmle.label | [post] access to local variable ret [field FieldA] : Object | +| H.cs:16:22:16:22 | access to parameter a [field FieldA] : Object | semmle.label | access to parameter a [field FieldA] : Object | +| H.cs:16:22:16:29 | access to field FieldA : Object | semmle.label | access to field FieldA : Object | +| H.cs:17:16:17:18 | access to local variable ret [field FieldA] : Object | semmle.label | access to local variable ret [field FieldA] : Object | | H.cs:23:9:23:9 | [post] access to local variable a [field FieldA] : Object | semmle.label | [post] access to local variable a [field FieldA] : Object | | H.cs:23:20:23:31 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | | H.cs:24:21:24:28 | call to method Clone [field FieldA] : Object | semmle.label | call to method Clone [field FieldA] : Object | | H.cs:24:27:24:27 | access to local variable a [field FieldA] : Object | semmle.label | access to local variable a [field FieldA] : Object | | H.cs:25:14:25:18 | access to local variable clone [field FieldA] : Object | semmle.label | access to local variable clone [field FieldA] : Object | | H.cs:25:14:25:25 | access to field FieldA | semmle.label | access to field FieldA | +| H.cs:33:19:33:19 | a [field FieldA] : A | semmle.label | a [field FieldA] : A | +| H.cs:33:19:33:19 | a [field FieldA] : Object | semmle.label | a [field FieldA] : Object | +| H.cs:36:9:36:9 | [post] access to local variable b [field FieldB] : A | semmle.label | [post] access to local variable b [field FieldB] : A | +| H.cs:36:9:36:9 | [post] access to local variable b [field FieldB] : Object | semmle.label | [post] access to local variable b [field FieldB] : Object | +| H.cs:36:20:36:20 | access to parameter a [field FieldA] : A | semmle.label | access to parameter a [field FieldA] : A | +| H.cs:36:20:36:20 | access to parameter a [field FieldA] : Object | semmle.label | access to parameter a [field FieldA] : Object | +| H.cs:36:20:36:27 | access to field FieldA : A | semmle.label | access to field FieldA : A | +| H.cs:36:20:36:27 | access to field FieldA : Object | semmle.label | access to field FieldA : Object | +| H.cs:37:16:37:16 | access to local variable b [field FieldB] : A | semmle.label | access to local variable b [field FieldB] : A | +| H.cs:37:16:37:16 | access to local variable b [field FieldB] : Object | semmle.label | access to local variable b [field FieldB] : Object | | H.cs:43:9:43:9 | [post] access to local variable a [field FieldA] : Object | semmle.label | [post] access to local variable a [field FieldA] : Object | | H.cs:43:20:43:31 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | | H.cs:44:17:44:28 | call to method Transform [field FieldB] : Object | semmle.label | call to method Transform [field FieldB] : Object | | H.cs:44:27:44:27 | access to local variable a [field FieldA] : Object | semmle.label | access to local variable a [field FieldA] : Object | | H.cs:45:14:45:14 | access to local variable b [field FieldB] : Object | semmle.label | access to local variable b [field FieldB] : Object | | H.cs:45:14:45:21 | access to field FieldB | semmle.label | access to field FieldB | +| H.cs:53:25:53:25 | a [field FieldA] : Object | semmle.label | a [field FieldA] : Object | +| H.cs:55:9:55:10 | [post] access to parameter b1 [field FieldB] : Object | semmle.label | [post] access to parameter b1 [field FieldB] : Object | +| H.cs:55:21:55:21 | access to parameter a [field FieldA] : Object | semmle.label | access to parameter a [field FieldA] : Object | +| H.cs:55:21:55:28 | access to field FieldA : Object | semmle.label | access to field FieldA : Object | | H.cs:63:9:63:9 | [post] access to local variable a [field FieldA] : Object | semmle.label | [post] access to local variable a [field FieldA] : Object | | H.cs:63:20:63:31 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | | H.cs:64:22:64:22 | access to local variable a [field FieldA] : Object | semmle.label | access to local variable a [field FieldA] : Object | | H.cs:64:25:64:26 | [post] access to local variable b1 [field FieldB] : Object | semmle.label | [post] access to local variable b1 [field FieldB] : Object | | H.cs:65:14:65:15 | access to local variable b1 [field FieldB] : Object | semmle.label | access to local variable b1 [field FieldB] : Object | | H.cs:65:14:65:22 | access to field FieldB | semmle.label | access to field FieldB | +| H.cs:77:30:77:30 | o : Object | semmle.label | o : Object | +| H.cs:79:9:79:9 | [post] access to parameter a [field FieldA] : Object | semmle.label | [post] access to parameter a [field FieldA] : Object | +| H.cs:79:20:79:20 | access to parameter o : Object | semmle.label | access to parameter o : Object | +| H.cs:80:22:80:22 | access to parameter a [field FieldA] : Object | semmle.label | access to parameter a [field FieldA] : Object | +| H.cs:80:25:80:26 | [post] access to parameter b1 [field FieldB] : Object | semmle.label | [post] access to parameter b1 [field FieldB] : Object | | H.cs:88:17:88:17 | [post] access to local variable a [field FieldA] : Object | semmle.label | [post] access to local variable a [field FieldA] : Object | | H.cs:88:20:88:31 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | | H.cs:88:34:88:35 | [post] access to local variable b1 [field FieldB] : Object | semmle.label | [post] access to local variable b1 [field FieldB] : Object | @@ -470,23 +747,45 @@ nodes | H.cs:89:14:89:21 | access to field FieldA | semmle.label | access to field FieldA | | H.cs:90:14:90:15 | access to local variable b1 [field FieldB] : Object | semmle.label | access to local variable b1 [field FieldB] : Object | | H.cs:90:14:90:22 | access to field FieldB | semmle.label | access to field FieldB | +| H.cs:102:23:102:23 | a [field FieldA] : Object | semmle.label | a [field FieldA] : Object | +| H.cs:105:9:105:12 | [post] access to local variable temp [field FieldB, field FieldA] : Object | semmle.label | [post] access to local variable temp [field FieldB, field FieldA] : Object | +| H.cs:105:23:105:23 | access to parameter a [field FieldA] : Object | semmle.label | access to parameter a [field FieldA] : Object | +| H.cs:106:16:106:40 | call to method Transform [field FieldB] : Object | semmle.label | call to method Transform [field FieldB] : Object | +| H.cs:106:26:106:39 | (...) ... [field FieldA] : Object | semmle.label | (...) ... [field FieldA] : Object | +| H.cs:106:29:106:32 | access to local variable temp [field FieldB, field FieldA] : Object | semmle.label | access to local variable temp [field FieldB, field FieldA] : Object | +| H.cs:106:29:106:39 | access to field FieldB [field FieldA] : Object | semmle.label | access to field FieldB [field FieldA] : Object | | H.cs:112:9:112:9 | [post] access to local variable a [field FieldA] : Object | semmle.label | [post] access to local variable a [field FieldA] : Object | | H.cs:112:20:112:31 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | | H.cs:113:17:113:32 | call to method TransformWrap [field FieldB] : Object | semmle.label | call to method TransformWrap [field FieldB] : Object | | H.cs:113:31:113:31 | access to local variable a [field FieldA] : Object | semmle.label | access to local variable a [field FieldA] : Object | | H.cs:114:14:114:14 | access to local variable b [field FieldB] : Object | semmle.label | access to local variable b [field FieldB] : Object | | H.cs:114:14:114:21 | access to field FieldB | semmle.label | access to field FieldB | +| H.cs:122:18:122:18 | a [field FieldA] : Object | semmle.label | a [field FieldA] : Object | +| H.cs:124:16:124:27 | call to method Transform [field FieldB] : Object | semmle.label | call to method Transform [field FieldB] : Object | +| H.cs:124:16:124:34 | access to field FieldB : Object | semmle.label | access to field FieldB : Object | +| H.cs:124:26:124:26 | access to parameter a [field FieldA] : Object | semmle.label | access to parameter a [field FieldA] : Object | | H.cs:130:9:130:9 | [post] access to local variable a [field FieldA] : Object | semmle.label | [post] access to local variable a [field FieldA] : Object | | H.cs:130:20:130:31 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | | H.cs:131:14:131:19 | call to method Get | semmle.label | call to method Get | | H.cs:131:18:131:18 | access to local variable a [field FieldA] : Object | semmle.label | access to local variable a [field FieldA] : Object | +| H.cs:138:27:138:27 | o : A | semmle.label | o : A | +| H.cs:141:9:141:9 | [post] access to local variable a [field FieldA] : A | semmle.label | [post] access to local variable a [field FieldA] : A | +| H.cs:141:20:141:25 | ... as ... : A | semmle.label | ... as ... : A | +| H.cs:142:16:142:27 | call to method Transform [field FieldB] : A | semmle.label | call to method Transform [field FieldB] : A | +| H.cs:142:16:142:34 | access to field FieldB : A | semmle.label | access to field FieldB : A | +| H.cs:142:26:142:26 | access to local variable a [field FieldA] : A | semmle.label | access to local variable a [field FieldA] : A | | H.cs:147:17:147:32 | call to method Through : A | semmle.label | call to method Through : A | | H.cs:147:25:147:31 | object creation of type A : A | semmle.label | object creation of type A : A | | H.cs:148:14:148:14 | access to local variable a | semmle.label | access to local variable a | +| H.cs:153:32:153:32 | o : Object | semmle.label | o : Object | | H.cs:155:17:155:23 | object creation of type B : B | semmle.label | object creation of type B : B | +| H.cs:156:9:156:9 | [post] access to local variable b [field FieldB] : Object | semmle.label | [post] access to local variable b [field FieldB] : Object | | H.cs:156:9:156:9 | access to local variable b : B | semmle.label | access to local variable b : B | +| H.cs:156:20:156:20 | access to parameter o : Object | semmle.label | access to parameter o : Object | +| H.cs:157:9:157:9 | [post] access to parameter a [field FieldA, field FieldB] : Object | semmle.label | [post] access to parameter a [field FieldA, field FieldB] : Object | | H.cs:157:9:157:9 | [post] access to parameter a [field FieldA] : B | semmle.label | [post] access to parameter a [field FieldA] : B | | H.cs:157:20:157:20 | access to local variable b : B | semmle.label | access to local variable b : B | +| H.cs:157:20:157:20 | access to local variable b [field FieldB] : Object | semmle.label | access to local variable b [field FieldB] : Object | | H.cs:163:17:163:28 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | | H.cs:164:19:164:19 | [post] access to local variable a [field FieldA, field FieldB] : Object | semmle.label | [post] access to local variable a [field FieldA, field FieldB] : Object | | H.cs:164:19:164:19 | [post] access to local variable a [field FieldA] : B | semmle.label | [post] access to local variable a [field FieldA] : B | @@ -538,6 +837,56 @@ nodes | J.cs:22:14:22:21 | access to property Prop1 | semmle.label | access to property Prop1 | | J.cs:23:14:23:15 | access to local variable r3 [property Prop2] : Object | semmle.label | access to local variable r3 [property Prop2] : Object | | J.cs:23:14:23:21 | access to property Prop2 | semmle.label | access to property Prop2 | +subpaths +| A.cs:6:24:6:24 | access to local variable c : C | A.cs:147:32:147:32 | c : C | A.cs:149:20:149:27 | object creation of type B [field c] : C | A.cs:6:17:6:25 | call to method Make [field c] : C | +| A.cs:13:15:13:22 | object creation of type C1 : C1 | A.cs:145:27:145:27 | c : C1 | A.cs:145:32:145:35 | [post] this access [field c] : C1 | A.cs:13:9:13:9 | [post] access to local variable b [field c] : C1 | +| A.cs:14:14:14:14 | access to local variable b [field c] : C1 | A.cs:146:18:146:20 | this [field c] : C1 | A.cs:146:33:146:38 | access to field c : C1 | A.cs:14:14:14:20 | call to method Get : C1 | +| A.cs:15:15:15:28 | object creation of type B [field c] : C | A.cs:146:18:146:20 | this [field c] : C | A.cs:146:33:146:38 | access to field c : C | A.cs:15:14:15:35 | call to method Get : C | +| A.cs:15:21:15:27 | object creation of type C : C | A.cs:141:20:141:20 | c : C | A.cs:143:13:143:16 | [post] this access [field c] : C | A.cs:15:15:15:28 | object creation of type B [field c] : C | +| A.cs:22:25:22:32 | object creation of type C2 : C2 | A.cs:42:29:42:29 | c : C2 | A.cs:48:20:48:21 | access to local variable b2 [field c] : C2 | A.cs:22:14:22:33 | call to method SetOnB [field c] : C2 | +| A.cs:31:29:31:36 | object creation of type C2 : C2 | A.cs:36:33:36:33 | c : C2 | A.cs:39:16:39:28 | ... ? ... : ... [field c] : C2 | A.cs:31:14:31:37 | call to method SetOnBWrap [field c] : C2 | +| A.cs:38:29:38:29 | access to parameter c : C2 | A.cs:42:29:42:29 | c : C2 | A.cs:48:20:48:21 | access to local variable b2 [field c] : C2 | A.cs:38:18:38:30 | call to method SetOnB [field c] : C2 | +| A.cs:47:20:47:20 | access to parameter c : C2 | A.cs:145:27:145:27 | c : C2 | A.cs:145:32:145:35 | [post] this access [field c] : C2 | A.cs:47:13:47:14 | [post] access to local variable b2 [field c] : C2 | +| A.cs:83:15:83:21 | object creation of type C : C | A.cs:145:27:145:27 | c : C | A.cs:145:32:145:35 | [post] this access [field c] : C | A.cs:83:9:83:9 | [post] access to parameter b [field c] : C | +| A.cs:105:23:105:23 | access to local variable b : B | A.cs:95:20:95:20 | b : B | A.cs:98:13:98:16 | [post] this access [field b] : B | A.cs:105:17:105:29 | object creation of type D [field b] : B | +| A.cs:114:29:114:29 | access to local variable b : B | A.cs:157:25:157:28 | head : B | A.cs:159:13:159:16 | [post] this access [field head] : B | A.cs:114:18:114:54 | object creation of type MyList [field head] : B | +| A.cs:115:35:115:36 | access to local variable l1 [field head] : B | A.cs:157:38:157:41 | next [field head] : B | A.cs:160:13:160:16 | [post] this access [field next, field head] : B | A.cs:115:18:115:37 | object creation of type MyList [field next, field head] : B | +| A.cs:116:35:116:36 | access to local variable l2 [field next, field head] : B | A.cs:157:38:157:41 | next [field next, field head] : B | A.cs:160:13:160:16 | [post] this access [field next, field next, field head] : B | A.cs:116:18:116:37 | object creation of type MyList [field next, field next, field head] : B | +| A.cs:149:26:149:26 | access to parameter c : C | A.cs:141:20:141:20 | c : C | A.cs:143:13:143:16 | [post] this access [field c] : C | A.cs:149:20:149:27 | object creation of type B [field c] : C | +| B.cs:6:27:6:27 | access to local variable e : Elem | B.cs:29:26:29:27 | e1 : Elem | B.cs:31:13:31:16 | [post] this access [field elem1] : Elem | B.cs:6:18:6:34 | object creation of type Box1 [field elem1] : Elem | +| B.cs:7:27:7:28 | access to local variable b1 [field elem1] : Elem | B.cs:39:26:39:27 | b1 [field elem1] : Elem | B.cs:41:13:41:16 | [post] this access [field box1, field elem1] : Elem | B.cs:7:18:7:29 | object creation of type Box2 [field box1, field elem1] : Elem | +| B.cs:15:33:15:33 | access to local variable e : Elem | B.cs:29:35:29:36 | e2 : Elem | B.cs:32:13:32:16 | [post] this access [field elem2] : Elem | B.cs:15:18:15:34 | object creation of type Box1 [field elem2] : Elem | +| B.cs:16:27:16:28 | access to local variable b1 [field elem2] : Elem | B.cs:39:26:39:27 | b1 [field elem2] : Elem | B.cs:41:13:41:16 | [post] this access [field box1, field elem2] : Elem | B.cs:16:18:16:29 | object creation of type Box2 [field box1, field elem2] : Elem | +| D.cs:15:34:15:38 | access to parameter value : Object | D.cs:9:9:9:11 | value : Object | D.cs:9:15:9:18 | [post] this access [field trivialPropField] : Object | D.cs:15:15:15:18 | [post] this access [field trivialPropField] : Object | +| D.cs:22:27:22:28 | access to parameter o2 : Object | D.cs:9:9:9:11 | value : Object | D.cs:9:15:9:18 | [post] this access [field trivialPropField] : Object | D.cs:22:9:22:11 | [post] access to local variable ret [field trivialPropField] : Object | +| D.cs:23:27:23:28 | access to parameter o3 : Object | D.cs:15:9:15:11 | value : Object | D.cs:15:15:15:18 | [post] this access [field trivialPropField] : Object | D.cs:23:9:23:11 | [post] access to local variable ret [field trivialPropField] : Object | +| D.cs:31:24:31:24 | access to local variable o : Object | D.cs:18:28:18:29 | o1 : Object | D.cs:24:16:24:18 | access to local variable ret [property AutoProp] : Object | D.cs:31:17:31:37 | call to method Create [property AutoProp] : Object | +| D.cs:37:26:37:26 | access to local variable o : Object | D.cs:18:39:18:40 | o2 : Object | D.cs:24:16:24:18 | access to local variable ret [field trivialPropField] : Object | D.cs:37:13:37:33 | call to method Create [field trivialPropField] : Object | +| D.cs:39:14:39:14 | access to local variable d [field trivialPropField] : Object | D.cs:8:9:8:11 | this [field trivialPropField] : Object | D.cs:8:22:8:42 | access to field trivialPropField : Object | D.cs:39:14:39:26 | access to property TrivialProp : Object | +| D.cs:41:14:41:14 | access to local variable d [field trivialPropField] : Object | D.cs:14:9:14:11 | this [field trivialPropField] : Object | D.cs:14:22:14:42 | access to field trivialPropField : Object | D.cs:41:14:41:26 | access to property ComplexProp : Object | +| D.cs:43:32:43:32 | access to local variable o : Object | D.cs:18:50:18:51 | o3 : Object | D.cs:24:16:24:18 | access to local variable ret [field trivialPropField] : Object | D.cs:43:13:43:33 | call to method Create [field trivialPropField] : Object | +| D.cs:45:14:45:14 | access to local variable d [field trivialPropField] : Object | D.cs:8:9:8:11 | this [field trivialPropField] : Object | D.cs:8:22:8:42 | access to field trivialPropField : Object | D.cs:45:14:45:26 | access to property TrivialProp : Object | +| D.cs:47:14:47:14 | access to local variable d [field trivialPropField] : Object | D.cs:14:9:14:11 | this [field trivialPropField] : Object | D.cs:14:22:14:42 | access to field trivialPropField : Object | D.cs:47:14:47:26 | access to property ComplexProp : Object | +| E.cs:23:25:23:25 | access to local variable o : Object | E.cs:8:29:8:29 | o : Object | E.cs:12:16:12:18 | access to local variable ret [field Field] : Object | E.cs:23:17:23:26 | call to method CreateS [field Field] : Object | +| F.cs:11:24:11:24 | access to local variable o : Object | F.cs:6:28:6:29 | o1 : Object | F.cs:6:46:6:81 | object creation of type F [field Field1] : Object | F.cs:11:17:11:31 | call to method Create [field Field1] : Object | +| F.cs:15:26:15:26 | access to local variable o : Object | F.cs:6:39:6:40 | o2 : Object | F.cs:6:46:6:81 | object creation of type F [field Field2] : Object | F.cs:15:13:15:27 | call to method Create [field Field2] : Object | +| G.cs:17:24:17:24 | access to local variable e : Elem | G.cs:64:34:64:34 | e : Elem | G.cs:64:39:64:42 | [post] this access [field Elem] : Elem | G.cs:17:9:17:14 | [post] access to field Box1 [field Elem] : Elem | +| G.cs:33:29:33:29 | access to local variable e : Elem | G.cs:64:34:64:34 | e : Elem | G.cs:64:39:64:42 | [post] this access [field Elem] : Elem | G.cs:33:9:33:19 | [post] call to method GetBox1 [field Elem] : Elem | +| G.cs:39:14:39:15 | access to parameter b2 [field Box1, field Elem] : Elem | G.cs:71:21:71:27 | this [field Box1, field Elem] : Elem | G.cs:71:34:71:37 | access to field Box1 [field Elem] : Elem | G.cs:39:14:39:25 | call to method GetBox1 [field Elem] : Elem | +| G.cs:39:14:39:25 | call to method GetBox1 [field Elem] : Elem | G.cs:63:21:63:27 | this [field Elem] : Elem | G.cs:63:34:63:37 | access to field Elem : Elem | G.cs:39:14:39:35 | call to method GetElem : Elem | +| H.cs:24:27:24:27 | access to local variable a [field FieldA] : Object | H.cs:13:15:13:15 | a [field FieldA] : Object | H.cs:17:16:17:18 | access to local variable ret [field FieldA] : Object | H.cs:24:21:24:28 | call to method Clone [field FieldA] : Object | +| H.cs:44:27:44:27 | access to local variable a [field FieldA] : Object | H.cs:33:19:33:19 | a [field FieldA] : Object | H.cs:37:16:37:16 | access to local variable b [field FieldB] : Object | H.cs:44:17:44:28 | call to method Transform [field FieldB] : Object | +| H.cs:64:22:64:22 | access to local variable a [field FieldA] : Object | H.cs:53:25:53:25 | a [field FieldA] : Object | H.cs:55:9:55:10 | [post] access to parameter b1 [field FieldB] : Object | H.cs:64:25:64:26 | [post] access to local variable b1 [field FieldB] : Object | +| H.cs:80:22:80:22 | access to parameter a [field FieldA] : Object | H.cs:53:25:53:25 | a [field FieldA] : Object | H.cs:55:9:55:10 | [post] access to parameter b1 [field FieldB] : Object | H.cs:80:25:80:26 | [post] access to parameter b1 [field FieldB] : Object | +| H.cs:88:20:88:31 | object creation of type Object : Object | H.cs:77:30:77:30 | o : Object | H.cs:79:9:79:9 | [post] access to parameter a [field FieldA] : Object | H.cs:88:17:88:17 | [post] access to local variable a [field FieldA] : Object | +| H.cs:88:20:88:31 | object creation of type Object : Object | H.cs:77:30:77:30 | o : Object | H.cs:80:25:80:26 | [post] access to parameter b1 [field FieldB] : Object | H.cs:88:34:88:35 | [post] access to local variable b1 [field FieldB] : Object | +| H.cs:106:26:106:39 | (...) ... [field FieldA] : Object | H.cs:33:19:33:19 | a [field FieldA] : Object | H.cs:37:16:37:16 | access to local variable b [field FieldB] : Object | H.cs:106:16:106:40 | call to method Transform [field FieldB] : Object | +| H.cs:113:31:113:31 | access to local variable a [field FieldA] : Object | H.cs:102:23:102:23 | a [field FieldA] : Object | H.cs:106:16:106:40 | call to method Transform [field FieldB] : Object | H.cs:113:17:113:32 | call to method TransformWrap [field FieldB] : Object | +| H.cs:124:26:124:26 | access to parameter a [field FieldA] : Object | H.cs:33:19:33:19 | a [field FieldA] : Object | H.cs:37:16:37:16 | access to local variable b [field FieldB] : Object | H.cs:124:16:124:27 | call to method Transform [field FieldB] : Object | +| H.cs:131:18:131:18 | access to local variable a [field FieldA] : Object | H.cs:122:18:122:18 | a [field FieldA] : Object | H.cs:124:16:124:34 | access to field FieldB : Object | H.cs:131:14:131:19 | call to method Get : Object | +| H.cs:142:26:142:26 | access to local variable a [field FieldA] : A | H.cs:33:19:33:19 | a [field FieldA] : A | H.cs:37:16:37:16 | access to local variable b [field FieldB] : A | H.cs:142:16:142:27 | call to method Transform [field FieldB] : A | +| H.cs:147:25:147:31 | object creation of type A : A | H.cs:138:27:138:27 | o : A | H.cs:142:16:142:34 | access to field FieldB : A | H.cs:147:17:147:32 | call to method Through : A | +| H.cs:164:22:164:22 | access to local variable o : Object | H.cs:153:32:153:32 | o : Object | H.cs:157:9:157:9 | [post] access to parameter a [field FieldA, field FieldB] : Object | H.cs:164:19:164:19 | [post] access to local variable a [field FieldA, field FieldB] : Object | #select | A.cs:7:14:7:16 | access to field c | A.cs:5:17:5:23 | object creation of type C : C | A.cs:7:14:7:16 | access to field c | $@ | A.cs:5:17:5:23 | object creation of type C : C | object creation of type C : C | | A.cs:14:14:14:20 | call to method Get | A.cs:13:15:13:22 | object creation of type C1 : C1 | A.cs:14:14:14:20 | call to method Get | $@ | A.cs:13:15:13:22 | object creation of type C1 : C1 | object creation of type C1 : C1 | diff --git a/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected b/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected index e4b10dfa57d..f3554fc535e 100644 --- a/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected +++ b/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected @@ -21,7 +21,9 @@ edges | Capture.cs:125:25:125:31 | tainted : String | Capture.cs:194:25:194:31 | access to parameter tainted : String | | Capture.cs:160:22:160:38 | call to local function CaptureThrough4 : String | Capture.cs:161:15:161:20 | access to local variable sink36 | | Capture.cs:168:25:168:31 | access to parameter tainted : String | Capture.cs:169:15:169:20 | access to local variable sink37 | +| Capture.cs:188:26:188:26 | s : String | Capture.cs:191:20:191:22 | call to local function M : String | | Capture.cs:194:22:194:32 | call to local function Id : String | Capture.cs:195:15:195:20 | access to local variable sink38 | +| Capture.cs:194:25:194:31 | access to parameter tainted : String | Capture.cs:188:26:188:26 | s : String | | Capture.cs:194:25:194:31 | access to parameter tainted : String | Capture.cs:194:22:194:32 | call to local function Id : String | | GlobalDataFlow.cs:18:27:18:40 | "taint source" : String | GlobalDataFlow.cs:19:15:19:29 | access to field SinkField0 | | GlobalDataFlow.cs:18:27:18:40 | "taint source" : String | GlobalDataFlow.cs:27:15:27:32 | access to property SinkProperty0 | @@ -108,14 +110,18 @@ edges | GlobalDataFlow.cs:71:21:71:46 | call to method Return : String | GlobalDataFlow.cs:72:15:72:19 | access to local variable sink0 | | GlobalDataFlow.cs:71:21:71:46 | call to method Return : String | GlobalDataFlow.cs:73:94:73:98 | access to local variable sink0 : String | | GlobalDataFlow.cs:71:28:71:45 | access to property SinkProperty0 : String | GlobalDataFlow.cs:71:21:71:46 | call to method Return : String | +| GlobalDataFlow.cs:71:28:71:45 | access to property SinkProperty0 : String | GlobalDataFlow.cs:298:26:298:26 | x : String | | GlobalDataFlow.cs:73:21:73:101 | (...) ... : String | GlobalDataFlow.cs:74:15:74:19 | access to local variable sink1 | | GlobalDataFlow.cs:73:21:73:101 | (...) ... : String | GlobalDataFlow.cs:76:19:76:23 | access to local variable sink1 : String | | GlobalDataFlow.cs:73:29:73:101 | call to method Invoke : String | GlobalDataFlow.cs:73:21:73:101 | (...) ... : String | | GlobalDataFlow.cs:73:94:73:98 | access to local variable sink0 : String | GlobalDataFlow.cs:73:29:73:101 | call to method Invoke : String | +| GlobalDataFlow.cs:73:94:73:98 | access to local variable sink0 : String | GlobalDataFlow.cs:298:26:298:26 | x : String | | GlobalDataFlow.cs:76:19:76:23 | access to local variable sink1 : String | GlobalDataFlow.cs:76:30:76:34 | SSA def(sink2) : String | +| GlobalDataFlow.cs:76:19:76:23 | access to local variable sink1 : String | GlobalDataFlow.cs:304:32:304:32 | x : String | | GlobalDataFlow.cs:76:30:76:34 | SSA def(sink2) : String | GlobalDataFlow.cs:77:15:77:19 | access to local variable sink2 | | GlobalDataFlow.cs:76:30:76:34 | SSA def(sink2) : String | GlobalDataFlow.cs:79:19:79:23 | access to local variable sink2 : String | | GlobalDataFlow.cs:79:19:79:23 | access to local variable sink2 : String | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | +| GlobalDataFlow.cs:79:19:79:23 | access to local variable sink2 : String | GlobalDataFlow.cs:310:32:310:32 | x : String | | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | GlobalDataFlow.cs:80:15:80:19 | access to local variable sink3 | | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | GlobalDataFlow.cs:81:59:81:63 | access to local variable sink3 : String | | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | GlobalDataFlow.cs:139:29:139:33 | access to local variable sink3 : String | @@ -125,6 +131,7 @@ edges | GlobalDataFlow.cs:81:23:81:65 | (...) ... [element] : String | GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven [element] : String | | GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [element] : String | GlobalDataFlow.cs:81:23:81:65 | (...) ... [element] : String | | GlobalDataFlow.cs:81:59:81:63 | access to local variable sink3 : String | GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [element] : String | +| GlobalDataFlow.cs:81:79:81:79 | x : String | GlobalDataFlow.cs:81:84:81:84 | access to parameter x : String | | GlobalDataFlow.cs:83:22:83:87 | call to method Select [element] : String | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | GlobalDataFlow.cs:84:15:84:20 | access to local variable sink14 | | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | GlobalDataFlow.cs:85:59:85:64 | access to local variable sink14 : String | @@ -143,11 +150,16 @@ edges | GlobalDataFlow.cs:87:70:87:113 | (...) ... [element] : String | GlobalDataFlow.cs:87:22:87:128 | call to method Zip [element] : String | | GlobalDataFlow.cs:87:104:87:113 | { ..., ... } [element] : String | GlobalDataFlow.cs:87:70:87:113 | (...) ... [element] : String | | GlobalDataFlow.cs:87:106:87:111 | access to local variable sink15 : String | GlobalDataFlow.cs:87:104:87:113 | { ..., ... } [element] : String | +| GlobalDataFlow.cs:138:40:138:40 | x : String | GlobalDataFlow.cs:138:63:138:63 | access to parameter x : String | +| GlobalDataFlow.cs:138:63:138:63 | access to parameter x : String | GlobalDataFlow.cs:138:45:138:64 | call to method ApplyFunc : String | +| GlobalDataFlow.cs:138:63:138:63 | access to parameter x : String | GlobalDataFlow.cs:387:46:387:46 | x : String | | GlobalDataFlow.cs:139:21:139:34 | delegate call : String | GlobalDataFlow.cs:140:15:140:19 | access to local variable sink4 | | GlobalDataFlow.cs:139:21:139:34 | delegate call : String | GlobalDataFlow.cs:147:39:147:43 | access to local variable sink4 : String | +| GlobalDataFlow.cs:139:29:139:33 | access to local variable sink3 : String | GlobalDataFlow.cs:138:40:138:40 | x : String | | GlobalDataFlow.cs:139:29:139:33 | access to local variable sink3 : String | GlobalDataFlow.cs:139:21:139:34 | delegate call : String | | GlobalDataFlow.cs:147:21:147:44 | call to method ApplyFunc : String | GlobalDataFlow.cs:148:15:148:19 | access to local variable sink5 | | GlobalDataFlow.cs:147:39:147:43 | access to local variable sink4 : String | GlobalDataFlow.cs:147:21:147:44 | call to method ApplyFunc : String | +| GlobalDataFlow.cs:147:39:147:43 | access to local variable sink4 : String | GlobalDataFlow.cs:387:46:387:46 | x : String | | GlobalDataFlow.cs:157:21:157:25 | call to method Out : String | GlobalDataFlow.cs:158:15:158:19 | access to local variable sink6 | | GlobalDataFlow.cs:160:20:160:24 | SSA def(sink7) : String | GlobalDataFlow.cs:161:15:161:19 | access to local variable sink7 | | GlobalDataFlow.cs:163:20:163:24 | SSA def(sink8) : String | GlobalDataFlow.cs:164:15:164:19 | access to local variable sink8 | @@ -196,8 +208,16 @@ edges | GlobalDataFlow.cs:278:26:278:35 | sinkParam5 : String | GlobalDataFlow.cs:280:15:280:24 | access to parameter sinkParam5 | | GlobalDataFlow.cs:283:26:283:35 | sinkParam6 : String | GlobalDataFlow.cs:285:15:285:24 | access to parameter sinkParam6 | | GlobalDataFlow.cs:288:26:288:35 | sinkParam7 : String | GlobalDataFlow.cs:290:15:290:24 | access to parameter sinkParam7 | +| GlobalDataFlow.cs:298:26:298:26 | x : String | GlobalDataFlow.cs:300:37:300:37 | access to parameter x : String | +| GlobalDataFlow.cs:300:17:300:38 | call to method ApplyFunc : String | GlobalDataFlow.cs:301:16:301:41 | ... ? ... : ... : String | +| GlobalDataFlow.cs:300:27:300:28 | x0 : String | GlobalDataFlow.cs:300:33:300:34 | access to parameter x0 : String | +| GlobalDataFlow.cs:300:37:300:37 | access to parameter x : String | GlobalDataFlow.cs:300:17:300:38 | call to method ApplyFunc : String | +| GlobalDataFlow.cs:300:37:300:37 | access to parameter x : String | GlobalDataFlow.cs:387:46:387:46 | x : String | +| GlobalDataFlow.cs:304:32:304:32 | x : String | GlobalDataFlow.cs:306:9:306:13 | SSA def(y) : String | +| GlobalDataFlow.cs:310:32:310:32 | x : String | GlobalDataFlow.cs:312:9:312:13 | SSA def(y) : String | | GlobalDataFlow.cs:315:31:315:40 | sinkParam8 : String | GlobalDataFlow.cs:317:15:317:24 | access to parameter sinkParam8 | | GlobalDataFlow.cs:321:32:321:41 | sinkParam9 : String | GlobalDataFlow.cs:323:15:323:24 | access to parameter sinkParam9 | +| GlobalDataFlow.cs:321:32:321:41 | sinkParam9 : String | GlobalDataFlow.cs:324:16:324:25 | access to parameter sinkParam9 : String | | GlobalDataFlow.cs:327:32:327:42 | sinkParam11 : String | GlobalDataFlow.cs:329:15:329:25 | access to parameter sinkParam11 | | GlobalDataFlow.cs:341:16:341:29 | "taint source" : String | GlobalDataFlow.cs:157:21:157:25 | call to method Out : String | | GlobalDataFlow.cs:341:16:341:29 | "taint source" : String | GlobalDataFlow.cs:193:22:193:42 | object creation of type Lazy [property Value] : String | @@ -210,6 +230,15 @@ edges | GlobalDataFlow.cs:382:41:382:41 | x : String | GlobalDataFlow.cs:384:11:384:11 | access to parameter x : String | | GlobalDataFlow.cs:384:11:384:11 | access to parameter x : String | GlobalDataFlow.cs:54:15:54:15 | x : String | | GlobalDataFlow.cs:384:11:384:11 | access to parameter x : String | GlobalDataFlow.cs:268:26:268:35 | sinkParam3 : String | +| GlobalDataFlow.cs:387:46:387:46 | x : String | GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | +| GlobalDataFlow.cs:387:46:387:46 | x : String | GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | +| GlobalDataFlow.cs:387:46:387:46 | x : String | GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:298:26:298:26 | x : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:298:26:298:26 | x : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:300:27:300:28 | x0 : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | | GlobalDataFlow.cs:396:52:396:52 | x : String | GlobalDataFlow.cs:398:11:398:11 | access to parameter x : String | | GlobalDataFlow.cs:396:52:396:52 | x : String | GlobalDataFlow.cs:398:11:398:11 | access to parameter x : String | | GlobalDataFlow.cs:396:52:396:52 | x : String | GlobalDataFlow.cs:398:11:398:11 | access to parameter x : String | @@ -233,14 +262,22 @@ edges | GlobalDataFlow.cs:486:21:486:21 | s : String | GlobalDataFlow.cs:486:32:486:32 | access to parameter s | | GlobalDataFlow.cs:487:15:487:17 | access to parameter arg : String | GlobalDataFlow.cs:486:21:486:21 | s : String | | GlobalDataFlow.cs:490:28:490:41 | "taint source" : String | GlobalDataFlow.cs:483:53:483:55 | arg : String | +| GlobalDataFlow.cs:501:46:501:46 | access to local variable x : String | GlobalDataFlow.cs:81:79:81:79 | x : String | | Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted : String | | Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted : String | | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return : String | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | | Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return : String | Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | | Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return : String | Splitting.cs:11:19:11:19 | access to local variable x | | Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted : String | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return : String | +| Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted : String | Splitting.cs:16:26:16:26 | x : String | | Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted : String | Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return : String | +| Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted : String | Splitting.cs:16:26:16:26 | x : String | +| Splitting.cs:16:26:16:26 | x : String | Splitting.cs:16:32:16:32 | access to parameter x : String | +| Splitting.cs:18:24:18:24 | s : String | Splitting.cs:20:29:20:29 | access to parameter s : String | +| Splitting.cs:20:29:20:29 | access to parameter s : String | Splitting.cs:16:26:16:26 | x : String | +| Splitting.cs:20:29:20:29 | access to parameter s : String | Splitting.cs:20:22:20:30 | call to method Return : String | | Splitting.cs:21:9:21:11 | value : String | Splitting.cs:21:28:21:32 | access to parameter value : String | +| Splitting.cs:21:28:21:32 | access to parameter value : String | Splitting.cs:16:26:16:26 | x : String | | Splitting.cs:21:28:21:32 | access to parameter value : String | Splitting.cs:21:21:21:33 | call to method Return | | Splitting.cs:24:28:24:34 | tainted : String | Splitting.cs:30:17:30:23 | [b (line 24): false] access to parameter tainted : String | | Splitting.cs:24:28:24:34 | tainted : String | Splitting.cs:30:17:30:23 | [b (line 24): true] access to parameter tainted : String | @@ -251,7 +288,9 @@ edges | Splitting.cs:31:17:31:26 | [b (line 24): false] dynamic access to element : String | Splitting.cs:32:15:32:15 | [b (line 24): false] access to local variable x | | Splitting.cs:31:17:31:26 | [b (line 24): true] dynamic access to element : String | Splitting.cs:32:15:32:15 | [b (line 24): true] access to local variable x | | Splitting.cs:31:17:31:26 | [b (line 24): true] dynamic access to element : String | Splitting.cs:34:19:34:19 | access to local variable x | +| Splitting.cs:31:19:31:25 | [b (line 24): false] access to parameter tainted : String | Splitting.cs:18:24:18:24 | s : String | | Splitting.cs:31:19:31:25 | [b (line 24): false] access to parameter tainted : String | Splitting.cs:31:17:31:26 | [b (line 24): false] dynamic access to element : String | +| Splitting.cs:31:19:31:25 | [b (line 24): true] access to parameter tainted : String | Splitting.cs:18:24:18:24 | s : String | | Splitting.cs:31:19:31:25 | [b (line 24): true] access to parameter tainted : String | Splitting.cs:31:17:31:26 | [b (line 24): true] dynamic access to element : String | | Splitting.cs:39:21:39:34 | [b (line 37): true] "taint source" : String | Splitting.cs:41:19:41:19 | access to local variable s | | Splitting.cs:48:36:48:49 | "taint source" : String | Splitting.cs:50:19:50:19 | access to local variable s | @@ -284,6 +323,8 @@ nodes | Capture.cs:161:15:161:20 | access to local variable sink36 | semmle.label | access to local variable sink36 | | Capture.cs:168:25:168:31 | access to parameter tainted : String | semmle.label | access to parameter tainted : String | | Capture.cs:169:15:169:20 | access to local variable sink37 | semmle.label | access to local variable sink37 | +| Capture.cs:188:26:188:26 | s : String | semmle.label | s : String | +| Capture.cs:191:20:191:22 | call to local function M : String | semmle.label | call to local function M : String | | Capture.cs:194:22:194:32 | call to local function Id : String | semmle.label | call to local function Id : String | | Capture.cs:194:25:194:31 | access to parameter tainted : String | semmle.label | access to parameter tainted : String | | Capture.cs:195:15:195:20 | access to local variable sink38 | semmle.label | access to local variable sink38 | @@ -324,6 +365,8 @@ nodes | GlobalDataFlow.cs:81:23:81:65 | (...) ... [element] : String | semmle.label | (...) ... [element] : String | | GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [element] : String | semmle.label | { ..., ... } [element] : String | | GlobalDataFlow.cs:81:59:81:63 | access to local variable sink3 : String | semmle.label | access to local variable sink3 : String | +| GlobalDataFlow.cs:81:79:81:79 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:81:84:81:84 | access to parameter x : String | semmle.label | access to parameter x : String | | GlobalDataFlow.cs:82:15:82:20 | access to local variable sink13 | semmle.label | access to local variable sink13 | | GlobalDataFlow.cs:83:22:83:87 | call to method Select [element] : String | semmle.label | call to method Select [element] : String | | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | semmle.label | call to method First : String | @@ -343,6 +386,9 @@ nodes | GlobalDataFlow.cs:87:104:87:113 | { ..., ... } [element] : String | semmle.label | { ..., ... } [element] : String | | GlobalDataFlow.cs:87:106:87:111 | access to local variable sink15 : String | semmle.label | access to local variable sink15 : String | | GlobalDataFlow.cs:88:15:88:20 | access to local variable sink16 | semmle.label | access to local variable sink16 | +| GlobalDataFlow.cs:138:40:138:40 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:138:45:138:64 | call to method ApplyFunc : String | semmle.label | call to method ApplyFunc : String | +| GlobalDataFlow.cs:138:63:138:63 | access to parameter x : String | semmle.label | access to parameter x : String | | GlobalDataFlow.cs:139:21:139:34 | delegate call : String | semmle.label | delegate call : String | | GlobalDataFlow.cs:139:29:139:33 | access to local variable sink3 : String | semmle.label | access to local variable sink3 : String | | GlobalDataFlow.cs:140:15:140:19 | access to local variable sink4 | semmle.label | access to local variable sink4 | @@ -411,10 +457,21 @@ nodes | GlobalDataFlow.cs:285:15:285:24 | access to parameter sinkParam6 | semmle.label | access to parameter sinkParam6 | | GlobalDataFlow.cs:288:26:288:35 | sinkParam7 : String | semmle.label | sinkParam7 : String | | GlobalDataFlow.cs:290:15:290:24 | access to parameter sinkParam7 | semmle.label | access to parameter sinkParam7 | +| GlobalDataFlow.cs:298:26:298:26 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:300:17:300:38 | call to method ApplyFunc : String | semmle.label | call to method ApplyFunc : String | +| GlobalDataFlow.cs:300:27:300:28 | x0 : String | semmle.label | x0 : String | +| GlobalDataFlow.cs:300:33:300:34 | access to parameter x0 : String | semmle.label | access to parameter x0 : String | +| GlobalDataFlow.cs:300:37:300:37 | access to parameter x : String | semmle.label | access to parameter x : String | +| GlobalDataFlow.cs:301:16:301:41 | ... ? ... : ... : String | semmle.label | ... ? ... : ... : String | +| GlobalDataFlow.cs:304:32:304:32 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:306:9:306:13 | SSA def(y) : String | semmle.label | SSA def(y) : String | +| GlobalDataFlow.cs:310:32:310:32 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:312:9:312:13 | SSA def(y) : String | semmle.label | SSA def(y) : String | | GlobalDataFlow.cs:315:31:315:40 | sinkParam8 : String | semmle.label | sinkParam8 : String | | GlobalDataFlow.cs:317:15:317:24 | access to parameter sinkParam8 | semmle.label | access to parameter sinkParam8 | | GlobalDataFlow.cs:321:32:321:41 | sinkParam9 : String | semmle.label | sinkParam9 : String | | GlobalDataFlow.cs:323:15:323:24 | access to parameter sinkParam9 | semmle.label | access to parameter sinkParam9 | +| GlobalDataFlow.cs:324:16:324:25 | access to parameter sinkParam9 : String | semmle.label | access to parameter sinkParam9 : String | | GlobalDataFlow.cs:327:32:327:42 | sinkParam11 : String | semmle.label | sinkParam11 : String | | GlobalDataFlow.cs:329:15:329:25 | access to parameter sinkParam11 | semmle.label | access to parameter sinkParam11 | | GlobalDataFlow.cs:341:16:341:29 | "taint source" : String | semmle.label | "taint source" : String | @@ -427,6 +484,15 @@ nodes | GlobalDataFlow.cs:382:41:382:41 | x : String | semmle.label | x : String | | GlobalDataFlow.cs:384:11:384:11 | access to parameter x : String | semmle.label | access to parameter x : String | | GlobalDataFlow.cs:384:11:384:11 | access to parameter x : String | semmle.label | access to parameter x : String | +| GlobalDataFlow.cs:387:46:387:46 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:387:46:387:46 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:387:46:387:46 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:389:16:389:19 | delegate call : String | semmle.label | delegate call : String | +| GlobalDataFlow.cs:389:16:389:19 | delegate call : String | semmle.label | delegate call : String | +| GlobalDataFlow.cs:389:16:389:19 | delegate call : String | semmle.label | delegate call : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | semmle.label | access to parameter x : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | semmle.label | access to parameter x : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | semmle.label | access to parameter x : String | | GlobalDataFlow.cs:396:52:396:52 | x : String | semmle.label | x : String | | GlobalDataFlow.cs:396:52:396:52 | x : String | semmle.label | x : String | | GlobalDataFlow.cs:396:52:396:52 | x : String | semmle.label | x : String | @@ -461,6 +527,11 @@ nodes | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | semmle.label | [b (line 3): false] access to local variable x | | Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | semmle.label | [b (line 3): true] access to local variable x | | Splitting.cs:11:19:11:19 | access to local variable x | semmle.label | access to local variable x | +| Splitting.cs:16:26:16:26 | x : String | semmle.label | x : String | +| Splitting.cs:16:32:16:32 | access to parameter x : String | semmle.label | access to parameter x : String | +| Splitting.cs:18:24:18:24 | s : String | semmle.label | s : String | +| Splitting.cs:20:22:20:30 | call to method Return : String | semmle.label | call to method Return : String | +| Splitting.cs:20:29:20:29 | access to parameter s : String | semmle.label | access to parameter s : String | | Splitting.cs:21:9:21:11 | value : String | semmle.label | value : String | | Splitting.cs:21:21:21:33 | call to method Return | semmle.label | call to method Return | | Splitting.cs:21:28:21:32 | access to parameter value : String | semmle.label | access to parameter value : String | @@ -479,6 +550,27 @@ nodes | Splitting.cs:48:36:48:49 | "taint source" : String | semmle.label | "taint source" : String | | Splitting.cs:50:19:50:19 | access to local variable s | semmle.label | access to local variable s | | Splitting.cs:52:19:52:19 | access to local variable s | semmle.label | access to local variable s | +subpaths +| Capture.cs:194:25:194:31 | access to parameter tainted : String | Capture.cs:188:26:188:26 | s : String | Capture.cs:191:20:191:22 | call to local function M : String | Capture.cs:194:22:194:32 | call to local function Id : String | +| GlobalDataFlow.cs:71:28:71:45 | access to property SinkProperty0 : String | GlobalDataFlow.cs:298:26:298:26 | x : String | GlobalDataFlow.cs:301:16:301:41 | ... ? ... : ... : String | GlobalDataFlow.cs:71:21:71:46 | call to method Return : String | +| GlobalDataFlow.cs:73:94:73:98 | access to local variable sink0 : String | GlobalDataFlow.cs:298:26:298:26 | x : String | GlobalDataFlow.cs:301:16:301:41 | ... ? ... : ... : String | GlobalDataFlow.cs:73:29:73:101 | call to method Invoke : String | +| GlobalDataFlow.cs:76:19:76:23 | access to local variable sink1 : String | GlobalDataFlow.cs:304:32:304:32 | x : String | GlobalDataFlow.cs:306:9:306:13 | SSA def(y) : String | GlobalDataFlow.cs:76:30:76:34 | SSA def(sink2) : String | +| GlobalDataFlow.cs:79:19:79:23 | access to local variable sink2 : String | GlobalDataFlow.cs:310:32:310:32 | x : String | GlobalDataFlow.cs:312:9:312:13 | SSA def(y) : String | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | +| GlobalDataFlow.cs:138:63:138:63 | access to parameter x : String | GlobalDataFlow.cs:387:46:387:46 | x : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | GlobalDataFlow.cs:138:45:138:64 | call to method ApplyFunc : String | +| GlobalDataFlow.cs:139:29:139:33 | access to local variable sink3 : String | GlobalDataFlow.cs:138:40:138:40 | x : String | GlobalDataFlow.cs:138:45:138:64 | call to method ApplyFunc : String | GlobalDataFlow.cs:139:21:139:34 | delegate call : String | +| GlobalDataFlow.cs:147:39:147:43 | access to local variable sink4 : String | GlobalDataFlow.cs:387:46:387:46 | x : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | GlobalDataFlow.cs:147:21:147:44 | call to method ApplyFunc : String | +| GlobalDataFlow.cs:215:89:215:89 | access to parameter x : String | GlobalDataFlow.cs:321:32:321:41 | sinkParam9 : String | GlobalDataFlow.cs:324:16:324:25 | access to parameter sinkParam9 : String | GlobalDataFlow.cs:215:76:215:90 | call to method ReturnCheck2 : String | +| GlobalDataFlow.cs:300:37:300:37 | access to parameter x : String | GlobalDataFlow.cs:387:46:387:46 | x : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | GlobalDataFlow.cs:300:17:300:38 | call to method ApplyFunc : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:298:26:298:26 | x : String | GlobalDataFlow.cs:301:16:301:41 | ... ? ... : ... : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:298:26:298:26 | x : String | GlobalDataFlow.cs:301:16:301:41 | ... ? ... : ... : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:300:27:300:28 | x0 : String | GlobalDataFlow.cs:300:33:300:34 | access to parameter x0 : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | +| GlobalDataFlow.cs:501:46:501:46 | access to local variable x : String | GlobalDataFlow.cs:81:79:81:79 | x : String | GlobalDataFlow.cs:81:84:81:84 | access to parameter x : String | GlobalDataFlow.cs:501:44:501:47 | delegate call : String | +| Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted : String | Splitting.cs:16:26:16:26 | x : String | Splitting.cs:16:32:16:32 | access to parameter x : String | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return : String | +| Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted : String | Splitting.cs:16:26:16:26 | x : String | Splitting.cs:16:32:16:32 | access to parameter x : String | Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return : String | +| Splitting.cs:20:29:20:29 | access to parameter s : String | Splitting.cs:16:26:16:26 | x : String | Splitting.cs:16:32:16:32 | access to parameter x : String | Splitting.cs:20:22:20:30 | call to method Return : String | +| Splitting.cs:21:28:21:32 | access to parameter value : String | Splitting.cs:16:26:16:26 | x : String | Splitting.cs:16:32:16:32 | access to parameter x : String | Splitting.cs:21:21:21:33 | call to method Return : String | +| Splitting.cs:31:19:31:25 | [b (line 24): false] access to parameter tainted : String | Splitting.cs:18:24:18:24 | s : String | Splitting.cs:20:22:20:30 | call to method Return : String | Splitting.cs:31:17:31:26 | [b (line 24): false] dynamic access to element : String | +| Splitting.cs:31:19:31:25 | [b (line 24): true] access to parameter tainted : String | Splitting.cs:18:24:18:24 | s : String | Splitting.cs:20:22:20:30 | call to method Return : String | Splitting.cs:31:17:31:26 | [b (line 24): true] dynamic access to element : String | #select | Splitting.cs:32:15:32:15 | [b (line 24): false] access to local variable x | Splitting.cs:24:28:24:34 | tainted : String | Splitting.cs:32:15:32:15 | [b (line 24): false] access to local variable x | [b (line 24): false] access to local variable x | | Splitting.cs:32:15:32:15 | [b (line 24): true] access to local variable x | Splitting.cs:24:28:24:34 | tainted : String | Splitting.cs:32:15:32:15 | [b (line 24): true] access to local variable x | [b (line 24): true] access to local variable x | diff --git a/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected b/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected index af4f0bf287b..5fbd6113092 100644 --- a/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected +++ b/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected @@ -21,7 +21,9 @@ edges | Capture.cs:125:25:125:31 | tainted : String | Capture.cs:194:25:194:31 | access to parameter tainted : String | | Capture.cs:160:22:160:38 | call to local function CaptureThrough4 : String | Capture.cs:161:15:161:20 | access to local variable sink36 | | Capture.cs:168:25:168:31 | access to parameter tainted : String | Capture.cs:169:15:169:20 | access to local variable sink37 | +| Capture.cs:188:26:188:26 | s : String | Capture.cs:191:20:191:22 | call to local function M : String | | Capture.cs:194:22:194:32 | call to local function Id : String | Capture.cs:195:15:195:20 | access to local variable sink38 | +| Capture.cs:194:25:194:31 | access to parameter tainted : String | Capture.cs:188:26:188:26 | s : String | | Capture.cs:194:25:194:31 | access to parameter tainted : String | Capture.cs:194:22:194:32 | call to local function Id : String | | GlobalDataFlow.cs:18:27:18:40 | "taint source" : String | GlobalDataFlow.cs:19:15:19:29 | access to field SinkField0 | | GlobalDataFlow.cs:18:27:18:40 | "taint source" : String | GlobalDataFlow.cs:27:15:27:32 | access to property SinkProperty0 | @@ -108,14 +110,18 @@ edges | GlobalDataFlow.cs:71:21:71:46 | call to method Return : String | GlobalDataFlow.cs:72:15:72:19 | access to local variable sink0 | | GlobalDataFlow.cs:71:21:71:46 | call to method Return : String | GlobalDataFlow.cs:73:94:73:98 | access to local variable sink0 : String | | GlobalDataFlow.cs:71:28:71:45 | access to property SinkProperty0 : String | GlobalDataFlow.cs:71:21:71:46 | call to method Return : String | +| GlobalDataFlow.cs:71:28:71:45 | access to property SinkProperty0 : String | GlobalDataFlow.cs:298:26:298:26 | x : String | | GlobalDataFlow.cs:73:21:73:101 | (...) ... : String | GlobalDataFlow.cs:74:15:74:19 | access to local variable sink1 | | GlobalDataFlow.cs:73:21:73:101 | (...) ... : String | GlobalDataFlow.cs:76:19:76:23 | access to local variable sink1 : String | | GlobalDataFlow.cs:73:29:73:101 | call to method Invoke : String | GlobalDataFlow.cs:73:21:73:101 | (...) ... : String | | GlobalDataFlow.cs:73:94:73:98 | access to local variable sink0 : String | GlobalDataFlow.cs:73:29:73:101 | call to method Invoke : String | +| GlobalDataFlow.cs:73:94:73:98 | access to local variable sink0 : String | GlobalDataFlow.cs:298:26:298:26 | x : String | | GlobalDataFlow.cs:76:19:76:23 | access to local variable sink1 : String | GlobalDataFlow.cs:76:30:76:34 | SSA def(sink2) : String | +| GlobalDataFlow.cs:76:19:76:23 | access to local variable sink1 : String | GlobalDataFlow.cs:304:32:304:32 | x : String | | GlobalDataFlow.cs:76:30:76:34 | SSA def(sink2) : String | GlobalDataFlow.cs:77:15:77:19 | access to local variable sink2 | | GlobalDataFlow.cs:76:30:76:34 | SSA def(sink2) : String | GlobalDataFlow.cs:79:19:79:23 | access to local variable sink2 : String | | GlobalDataFlow.cs:79:19:79:23 | access to local variable sink2 : String | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | +| GlobalDataFlow.cs:79:19:79:23 | access to local variable sink2 : String | GlobalDataFlow.cs:310:32:310:32 | x : String | | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | GlobalDataFlow.cs:80:15:80:19 | access to local variable sink3 | | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | GlobalDataFlow.cs:81:59:81:63 | access to local variable sink3 : String | | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | GlobalDataFlow.cs:139:29:139:33 | access to local variable sink3 : String | @@ -125,6 +131,7 @@ edges | GlobalDataFlow.cs:81:23:81:65 | (...) ... [element] : String | GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven [element] : String | | GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [element] : String | GlobalDataFlow.cs:81:23:81:65 | (...) ... [element] : String | | GlobalDataFlow.cs:81:59:81:63 | access to local variable sink3 : String | GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [element] : String | +| GlobalDataFlow.cs:81:79:81:79 | x : String | GlobalDataFlow.cs:81:84:81:84 | access to parameter x : String | | GlobalDataFlow.cs:83:22:83:87 | call to method Select [element] : String | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | GlobalDataFlow.cs:84:15:84:20 | access to local variable sink14 | | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | GlobalDataFlow.cs:85:59:85:64 | access to local variable sink14 : String | @@ -160,11 +167,16 @@ edges | GlobalDataFlow.cs:97:35:97:40 | SSA def(sink22) : Boolean | GlobalDataFlow.cs:98:15:98:20 | access to local variable sink22 | | GlobalDataFlow.cs:100:24:100:29 | access to local variable sink18 : String | GlobalDataFlow.cs:100:82:100:88 | SSA def(sink21b) : Int32 | | GlobalDataFlow.cs:100:82:100:88 | SSA def(sink21b) : Int32 | GlobalDataFlow.cs:101:15:101:21 | access to local variable sink21b | +| GlobalDataFlow.cs:138:40:138:40 | x : String | GlobalDataFlow.cs:138:63:138:63 | access to parameter x : String | +| GlobalDataFlow.cs:138:63:138:63 | access to parameter x : String | GlobalDataFlow.cs:138:45:138:64 | call to method ApplyFunc : String | +| GlobalDataFlow.cs:138:63:138:63 | access to parameter x : String | GlobalDataFlow.cs:387:46:387:46 | x : String | | GlobalDataFlow.cs:139:21:139:34 | delegate call : String | GlobalDataFlow.cs:140:15:140:19 | access to local variable sink4 | | GlobalDataFlow.cs:139:21:139:34 | delegate call : String | GlobalDataFlow.cs:147:39:147:43 | access to local variable sink4 : String | +| GlobalDataFlow.cs:139:29:139:33 | access to local variable sink3 : String | GlobalDataFlow.cs:138:40:138:40 | x : String | | GlobalDataFlow.cs:139:29:139:33 | access to local variable sink3 : String | GlobalDataFlow.cs:139:21:139:34 | delegate call : String | | GlobalDataFlow.cs:147:21:147:44 | call to method ApplyFunc : String | GlobalDataFlow.cs:148:15:148:19 | access to local variable sink5 | | GlobalDataFlow.cs:147:39:147:43 | access to local variable sink4 : String | GlobalDataFlow.cs:147:21:147:44 | call to method ApplyFunc : String | +| GlobalDataFlow.cs:147:39:147:43 | access to local variable sink4 : String | GlobalDataFlow.cs:387:46:387:46 | x : String | | GlobalDataFlow.cs:157:21:157:25 | call to method Out : String | GlobalDataFlow.cs:158:15:158:19 | access to local variable sink6 | | GlobalDataFlow.cs:160:20:160:24 | SSA def(sink7) : String | GlobalDataFlow.cs:161:15:161:19 | access to local variable sink7 | | GlobalDataFlow.cs:163:20:163:24 | SSA def(sink8) : String | GlobalDataFlow.cs:164:15:164:19 | access to local variable sink8 | @@ -213,8 +225,16 @@ edges | GlobalDataFlow.cs:278:26:278:35 | sinkParam5 : String | GlobalDataFlow.cs:280:15:280:24 | access to parameter sinkParam5 | | GlobalDataFlow.cs:283:26:283:35 | sinkParam6 : String | GlobalDataFlow.cs:285:15:285:24 | access to parameter sinkParam6 | | GlobalDataFlow.cs:288:26:288:35 | sinkParam7 : String | GlobalDataFlow.cs:290:15:290:24 | access to parameter sinkParam7 | +| GlobalDataFlow.cs:298:26:298:26 | x : String | GlobalDataFlow.cs:300:37:300:37 | access to parameter x : String | +| GlobalDataFlow.cs:300:17:300:38 | call to method ApplyFunc : String | GlobalDataFlow.cs:301:16:301:41 | ... ? ... : ... : String | +| GlobalDataFlow.cs:300:27:300:28 | x0 : String | GlobalDataFlow.cs:300:33:300:34 | access to parameter x0 : String | +| GlobalDataFlow.cs:300:37:300:37 | access to parameter x : String | GlobalDataFlow.cs:300:17:300:38 | call to method ApplyFunc : String | +| GlobalDataFlow.cs:300:37:300:37 | access to parameter x : String | GlobalDataFlow.cs:387:46:387:46 | x : String | +| GlobalDataFlow.cs:304:32:304:32 | x : String | GlobalDataFlow.cs:306:9:306:13 | SSA def(y) : String | +| GlobalDataFlow.cs:310:32:310:32 | x : String | GlobalDataFlow.cs:312:9:312:13 | SSA def(y) : String | | GlobalDataFlow.cs:315:31:315:40 | sinkParam8 : String | GlobalDataFlow.cs:317:15:317:24 | access to parameter sinkParam8 | | GlobalDataFlow.cs:321:32:321:41 | sinkParam9 : String | GlobalDataFlow.cs:323:15:323:24 | access to parameter sinkParam9 | +| GlobalDataFlow.cs:321:32:321:41 | sinkParam9 : String | GlobalDataFlow.cs:324:16:324:25 | access to parameter sinkParam9 : String | | GlobalDataFlow.cs:327:32:327:42 | sinkParam11 : String | GlobalDataFlow.cs:329:15:329:25 | access to parameter sinkParam11 | | GlobalDataFlow.cs:341:16:341:29 | "taint source" : String | GlobalDataFlow.cs:157:21:157:25 | call to method Out : String | | GlobalDataFlow.cs:341:16:341:29 | "taint source" : String | GlobalDataFlow.cs:193:22:193:42 | object creation of type Lazy [property Value] : String | @@ -227,6 +247,15 @@ edges | GlobalDataFlow.cs:382:41:382:41 | x : String | GlobalDataFlow.cs:384:11:384:11 | access to parameter x : String | | GlobalDataFlow.cs:384:11:384:11 | access to parameter x : String | GlobalDataFlow.cs:54:15:54:15 | x : String | | GlobalDataFlow.cs:384:11:384:11 | access to parameter x : String | GlobalDataFlow.cs:268:26:268:35 | sinkParam3 : String | +| GlobalDataFlow.cs:387:46:387:46 | x : String | GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | +| GlobalDataFlow.cs:387:46:387:46 | x : String | GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | +| GlobalDataFlow.cs:387:46:387:46 | x : String | GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:298:26:298:26 | x : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:298:26:298:26 | x : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:300:27:300:28 | x0 : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | | GlobalDataFlow.cs:396:52:396:52 | x : String | GlobalDataFlow.cs:398:11:398:11 | access to parameter x : String | | GlobalDataFlow.cs:396:52:396:52 | x : String | GlobalDataFlow.cs:398:11:398:11 | access to parameter x : String | | GlobalDataFlow.cs:396:52:396:52 | x : String | GlobalDataFlow.cs:398:11:398:11 | access to parameter x : String | @@ -238,7 +267,10 @@ edges | GlobalDataFlow.cs:405:16:405:21 | access to local variable sink11 : String | GlobalDataFlow.cs:167:22:167:43 | call to method TaintedParam : String | | GlobalDataFlow.cs:427:9:427:11 | value : String | GlobalDataFlow.cs:427:41:427:46 | access to local variable sink20 | | GlobalDataFlow.cs:438:22:438:35 | "taint source" : String | GlobalDataFlow.cs:201:22:201:32 | access to property OutProperty : String | +| GlobalDataFlow.cs:446:64:446:64 | s : String | GlobalDataFlow.cs:448:19:448:19 | access to parameter s : String | +| GlobalDataFlow.cs:448:19:448:19 | access to parameter s : String | GlobalDataFlow.cs:448:9:448:10 | [post] access to parameter sb [element] : String | | GlobalDataFlow.cs:454:31:454:32 | [post] access to local variable sb [element] : String | GlobalDataFlow.cs:455:22:455:23 | access to local variable sb [element] : String | +| GlobalDataFlow.cs:454:35:454:48 | "taint source" : String | GlobalDataFlow.cs:446:64:446:64 | s : String | | GlobalDataFlow.cs:454:35:454:48 | "taint source" : String | GlobalDataFlow.cs:454:31:454:32 | [post] access to local variable sb [element] : String | | GlobalDataFlow.cs:455:22:455:23 | access to local variable sb [element] : String | GlobalDataFlow.cs:455:22:455:34 | call to method ToString : String | | GlobalDataFlow.cs:455:22:455:34 | call to method ToString : String | GlobalDataFlow.cs:456:15:456:20 | access to local variable sink43 | @@ -256,14 +288,22 @@ edges | GlobalDataFlow.cs:486:21:486:21 | s : String | GlobalDataFlow.cs:486:32:486:32 | access to parameter s | | GlobalDataFlow.cs:487:15:487:17 | access to parameter arg : String | GlobalDataFlow.cs:486:21:486:21 | s : String | | GlobalDataFlow.cs:490:28:490:41 | "taint source" : String | GlobalDataFlow.cs:483:53:483:55 | arg : String | +| GlobalDataFlow.cs:501:46:501:46 | access to local variable x : String | GlobalDataFlow.cs:81:79:81:79 | x : String | | Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted : String | | Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted : String | | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return : String | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | | Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return : String | Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | | Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return : String | Splitting.cs:11:19:11:19 | access to local variable x | | Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted : String | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return : String | +| Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted : String | Splitting.cs:16:26:16:26 | x : String | | Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted : String | Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return : String | +| Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted : String | Splitting.cs:16:26:16:26 | x : String | +| Splitting.cs:16:26:16:26 | x : String | Splitting.cs:16:32:16:32 | access to parameter x : String | +| Splitting.cs:18:24:18:24 | s : String | Splitting.cs:20:29:20:29 | access to parameter s : String | +| Splitting.cs:20:29:20:29 | access to parameter s : String | Splitting.cs:16:26:16:26 | x : String | +| Splitting.cs:20:29:20:29 | access to parameter s : String | Splitting.cs:20:22:20:30 | call to method Return : String | | Splitting.cs:21:9:21:11 | value : String | Splitting.cs:21:28:21:32 | access to parameter value : String | +| Splitting.cs:21:28:21:32 | access to parameter value : String | Splitting.cs:16:26:16:26 | x : String | | Splitting.cs:21:28:21:32 | access to parameter value : String | Splitting.cs:21:21:21:33 | call to method Return | | Splitting.cs:24:28:24:34 | tainted : String | Splitting.cs:30:17:30:23 | [b (line 24): false] access to parameter tainted : String | | Splitting.cs:24:28:24:34 | tainted : String | Splitting.cs:30:17:30:23 | [b (line 24): true] access to parameter tainted : String | @@ -274,7 +314,9 @@ edges | Splitting.cs:31:17:31:26 | [b (line 24): false] dynamic access to element : String | Splitting.cs:32:15:32:15 | [b (line 24): false] access to local variable x | | Splitting.cs:31:17:31:26 | [b (line 24): true] dynamic access to element : String | Splitting.cs:32:15:32:15 | [b (line 24): true] access to local variable x | | Splitting.cs:31:17:31:26 | [b (line 24): true] dynamic access to element : String | Splitting.cs:34:19:34:19 | access to local variable x | +| Splitting.cs:31:19:31:25 | [b (line 24): false] access to parameter tainted : String | Splitting.cs:18:24:18:24 | s : String | | Splitting.cs:31:19:31:25 | [b (line 24): false] access to parameter tainted : String | Splitting.cs:31:17:31:26 | [b (line 24): false] dynamic access to element : String | +| Splitting.cs:31:19:31:25 | [b (line 24): true] access to parameter tainted : String | Splitting.cs:18:24:18:24 | s : String | | Splitting.cs:31:19:31:25 | [b (line 24): true] access to parameter tainted : String | Splitting.cs:31:17:31:26 | [b (line 24): true] dynamic access to element : String | | Splitting.cs:39:21:39:34 | [b (line 37): true] "taint source" : String | Splitting.cs:41:19:41:19 | access to local variable s | | Splitting.cs:48:36:48:49 | "taint source" : String | Splitting.cs:50:19:50:19 | access to local variable s | @@ -307,6 +349,8 @@ nodes | Capture.cs:161:15:161:20 | access to local variable sink36 | semmle.label | access to local variable sink36 | | Capture.cs:168:25:168:31 | access to parameter tainted : String | semmle.label | access to parameter tainted : String | | Capture.cs:169:15:169:20 | access to local variable sink37 | semmle.label | access to local variable sink37 | +| Capture.cs:188:26:188:26 | s : String | semmle.label | s : String | +| Capture.cs:191:20:191:22 | call to local function M : String | semmle.label | call to local function M : String | | Capture.cs:194:22:194:32 | call to local function Id : String | semmle.label | call to local function Id : String | | Capture.cs:194:25:194:31 | access to parameter tainted : String | semmle.label | access to parameter tainted : String | | Capture.cs:195:15:195:20 | access to local variable sink38 | semmle.label | access to local variable sink38 | @@ -347,6 +391,8 @@ nodes | GlobalDataFlow.cs:81:23:81:65 | (...) ... [element] : String | semmle.label | (...) ... [element] : String | | GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [element] : String | semmle.label | { ..., ... } [element] : String | | GlobalDataFlow.cs:81:59:81:63 | access to local variable sink3 : String | semmle.label | access to local variable sink3 : String | +| GlobalDataFlow.cs:81:79:81:79 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:81:84:81:84 | access to parameter x : String | semmle.label | access to parameter x : String | | GlobalDataFlow.cs:82:15:82:20 | access to local variable sink13 | semmle.label | access to local variable sink13 | | GlobalDataFlow.cs:83:22:83:87 | call to method Select [element] : String | semmle.label | call to method Select [element] : String | | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | semmle.label | call to method First : String | @@ -383,6 +429,9 @@ nodes | GlobalDataFlow.cs:100:24:100:29 | access to local variable sink18 : String | semmle.label | access to local variable sink18 : String | | GlobalDataFlow.cs:100:82:100:88 | SSA def(sink21b) : Int32 | semmle.label | SSA def(sink21b) : Int32 | | GlobalDataFlow.cs:101:15:101:21 | access to local variable sink21b | semmle.label | access to local variable sink21b | +| GlobalDataFlow.cs:138:40:138:40 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:138:45:138:64 | call to method ApplyFunc : String | semmle.label | call to method ApplyFunc : String | +| GlobalDataFlow.cs:138:63:138:63 | access to parameter x : String | semmle.label | access to parameter x : String | | GlobalDataFlow.cs:139:21:139:34 | delegate call : String | semmle.label | delegate call : String | | GlobalDataFlow.cs:139:29:139:33 | access to local variable sink3 : String | semmle.label | access to local variable sink3 : String | | GlobalDataFlow.cs:140:15:140:19 | access to local variable sink4 | semmle.label | access to local variable sink4 | @@ -451,10 +500,21 @@ nodes | GlobalDataFlow.cs:285:15:285:24 | access to parameter sinkParam6 | semmle.label | access to parameter sinkParam6 | | GlobalDataFlow.cs:288:26:288:35 | sinkParam7 : String | semmle.label | sinkParam7 : String | | GlobalDataFlow.cs:290:15:290:24 | access to parameter sinkParam7 | semmle.label | access to parameter sinkParam7 | +| GlobalDataFlow.cs:298:26:298:26 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:300:17:300:38 | call to method ApplyFunc : String | semmle.label | call to method ApplyFunc : String | +| GlobalDataFlow.cs:300:27:300:28 | x0 : String | semmle.label | x0 : String | +| GlobalDataFlow.cs:300:33:300:34 | access to parameter x0 : String | semmle.label | access to parameter x0 : String | +| GlobalDataFlow.cs:300:37:300:37 | access to parameter x : String | semmle.label | access to parameter x : String | +| GlobalDataFlow.cs:301:16:301:41 | ... ? ... : ... : String | semmle.label | ... ? ... : ... : String | +| GlobalDataFlow.cs:304:32:304:32 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:306:9:306:13 | SSA def(y) : String | semmle.label | SSA def(y) : String | +| GlobalDataFlow.cs:310:32:310:32 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:312:9:312:13 | SSA def(y) : String | semmle.label | SSA def(y) : String | | GlobalDataFlow.cs:315:31:315:40 | sinkParam8 : String | semmle.label | sinkParam8 : String | | GlobalDataFlow.cs:317:15:317:24 | access to parameter sinkParam8 | semmle.label | access to parameter sinkParam8 | | GlobalDataFlow.cs:321:32:321:41 | sinkParam9 : String | semmle.label | sinkParam9 : String | | GlobalDataFlow.cs:323:15:323:24 | access to parameter sinkParam9 | semmle.label | access to parameter sinkParam9 | +| GlobalDataFlow.cs:324:16:324:25 | access to parameter sinkParam9 : String | semmle.label | access to parameter sinkParam9 : String | | GlobalDataFlow.cs:327:32:327:42 | sinkParam11 : String | semmle.label | sinkParam11 : String | | GlobalDataFlow.cs:329:15:329:25 | access to parameter sinkParam11 | semmle.label | access to parameter sinkParam11 | | GlobalDataFlow.cs:341:16:341:29 | "taint source" : String | semmle.label | "taint source" : String | @@ -467,6 +527,15 @@ nodes | GlobalDataFlow.cs:382:41:382:41 | x : String | semmle.label | x : String | | GlobalDataFlow.cs:384:11:384:11 | access to parameter x : String | semmle.label | access to parameter x : String | | GlobalDataFlow.cs:384:11:384:11 | access to parameter x : String | semmle.label | access to parameter x : String | +| GlobalDataFlow.cs:387:46:387:46 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:387:46:387:46 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:387:46:387:46 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:389:16:389:19 | delegate call : String | semmle.label | delegate call : String | +| GlobalDataFlow.cs:389:16:389:19 | delegate call : String | semmle.label | delegate call : String | +| GlobalDataFlow.cs:389:16:389:19 | delegate call : String | semmle.label | delegate call : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | semmle.label | access to parameter x : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | semmle.label | access to parameter x : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | semmle.label | access to parameter x : String | | GlobalDataFlow.cs:396:52:396:52 | x : String | semmle.label | x : String | | GlobalDataFlow.cs:396:52:396:52 | x : String | semmle.label | x : String | | GlobalDataFlow.cs:396:52:396:52 | x : String | semmle.label | x : String | @@ -479,6 +548,9 @@ nodes | GlobalDataFlow.cs:427:9:427:11 | value : String | semmle.label | value : String | | GlobalDataFlow.cs:427:41:427:46 | access to local variable sink20 | semmle.label | access to local variable sink20 | | GlobalDataFlow.cs:438:22:438:35 | "taint source" : String | semmle.label | "taint source" : String | +| GlobalDataFlow.cs:446:64:446:64 | s : String | semmle.label | s : String | +| GlobalDataFlow.cs:448:9:448:10 | [post] access to parameter sb [element] : String | semmle.label | [post] access to parameter sb [element] : String | +| GlobalDataFlow.cs:448:19:448:19 | access to parameter s : String | semmle.label | access to parameter s : String | | GlobalDataFlow.cs:454:31:454:32 | [post] access to local variable sb [element] : String | semmle.label | [post] access to local variable sb [element] : String | | GlobalDataFlow.cs:454:35:454:48 | "taint source" : String | semmle.label | "taint source" : String | | GlobalDataFlow.cs:455:22:455:23 | access to local variable sb [element] : String | semmle.label | access to local variable sb [element] : String | @@ -509,6 +581,11 @@ nodes | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | semmle.label | [b (line 3): false] access to local variable x | | Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | semmle.label | [b (line 3): true] access to local variable x | | Splitting.cs:11:19:11:19 | access to local variable x | semmle.label | access to local variable x | +| Splitting.cs:16:26:16:26 | x : String | semmle.label | x : String | +| Splitting.cs:16:32:16:32 | access to parameter x : String | semmle.label | access to parameter x : String | +| Splitting.cs:18:24:18:24 | s : String | semmle.label | s : String | +| Splitting.cs:20:22:20:30 | call to method Return : String | semmle.label | call to method Return : String | +| Splitting.cs:20:29:20:29 | access to parameter s : String | semmle.label | access to parameter s : String | | Splitting.cs:21:9:21:11 | value : String | semmle.label | value : String | | Splitting.cs:21:21:21:33 | call to method Return | semmle.label | call to method Return | | Splitting.cs:21:28:21:32 | access to parameter value : String | semmle.label | access to parameter value : String | @@ -527,6 +604,28 @@ nodes | Splitting.cs:48:36:48:49 | "taint source" : String | semmle.label | "taint source" : String | | Splitting.cs:50:19:50:19 | access to local variable s | semmle.label | access to local variable s | | Splitting.cs:52:19:52:19 | access to local variable s | semmle.label | access to local variable s | +subpaths +| Capture.cs:194:25:194:31 | access to parameter tainted : String | Capture.cs:188:26:188:26 | s : String | Capture.cs:191:20:191:22 | call to local function M : String | Capture.cs:194:22:194:32 | call to local function Id : String | +| GlobalDataFlow.cs:71:28:71:45 | access to property SinkProperty0 : String | GlobalDataFlow.cs:298:26:298:26 | x : String | GlobalDataFlow.cs:301:16:301:41 | ... ? ... : ... : String | GlobalDataFlow.cs:71:21:71:46 | call to method Return : String | +| GlobalDataFlow.cs:73:94:73:98 | access to local variable sink0 : String | GlobalDataFlow.cs:298:26:298:26 | x : String | GlobalDataFlow.cs:301:16:301:41 | ... ? ... : ... : String | GlobalDataFlow.cs:73:29:73:101 | call to method Invoke : String | +| GlobalDataFlow.cs:76:19:76:23 | access to local variable sink1 : String | GlobalDataFlow.cs:304:32:304:32 | x : String | GlobalDataFlow.cs:306:9:306:13 | SSA def(y) : String | GlobalDataFlow.cs:76:30:76:34 | SSA def(sink2) : String | +| GlobalDataFlow.cs:79:19:79:23 | access to local variable sink2 : String | GlobalDataFlow.cs:310:32:310:32 | x : String | GlobalDataFlow.cs:312:9:312:13 | SSA def(y) : String | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | +| GlobalDataFlow.cs:138:63:138:63 | access to parameter x : String | GlobalDataFlow.cs:387:46:387:46 | x : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | GlobalDataFlow.cs:138:45:138:64 | call to method ApplyFunc : String | +| GlobalDataFlow.cs:139:29:139:33 | access to local variable sink3 : String | GlobalDataFlow.cs:138:40:138:40 | x : String | GlobalDataFlow.cs:138:45:138:64 | call to method ApplyFunc : String | GlobalDataFlow.cs:139:21:139:34 | delegate call : String | +| GlobalDataFlow.cs:147:39:147:43 | access to local variable sink4 : String | GlobalDataFlow.cs:387:46:387:46 | x : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | GlobalDataFlow.cs:147:21:147:44 | call to method ApplyFunc : String | +| GlobalDataFlow.cs:215:89:215:89 | access to parameter x : String | GlobalDataFlow.cs:321:32:321:41 | sinkParam9 : String | GlobalDataFlow.cs:324:16:324:25 | access to parameter sinkParam9 : String | GlobalDataFlow.cs:215:76:215:90 | call to method ReturnCheck2 : String | +| GlobalDataFlow.cs:300:37:300:37 | access to parameter x : String | GlobalDataFlow.cs:387:46:387:46 | x : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | GlobalDataFlow.cs:300:17:300:38 | call to method ApplyFunc : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:298:26:298:26 | x : String | GlobalDataFlow.cs:301:16:301:41 | ... ? ... : ... : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:298:26:298:26 | x : String | GlobalDataFlow.cs:301:16:301:41 | ... ? ... : ... : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | +| GlobalDataFlow.cs:389:18:389:18 | access to parameter x : String | GlobalDataFlow.cs:300:27:300:28 | x0 : String | GlobalDataFlow.cs:300:33:300:34 | access to parameter x0 : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | +| GlobalDataFlow.cs:454:35:454:48 | "taint source" : String | GlobalDataFlow.cs:446:64:446:64 | s : String | GlobalDataFlow.cs:448:9:448:10 | [post] access to parameter sb [element] : String | GlobalDataFlow.cs:454:31:454:32 | [post] access to local variable sb [element] : String | +| GlobalDataFlow.cs:501:46:501:46 | access to local variable x : String | GlobalDataFlow.cs:81:79:81:79 | x : String | GlobalDataFlow.cs:81:84:81:84 | access to parameter x : String | GlobalDataFlow.cs:501:44:501:47 | delegate call : String | +| Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted : String | Splitting.cs:16:26:16:26 | x : String | Splitting.cs:16:32:16:32 | access to parameter x : String | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return : String | +| Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted : String | Splitting.cs:16:26:16:26 | x : String | Splitting.cs:16:32:16:32 | access to parameter x : String | Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return : String | +| Splitting.cs:20:29:20:29 | access to parameter s : String | Splitting.cs:16:26:16:26 | x : String | Splitting.cs:16:32:16:32 | access to parameter x : String | Splitting.cs:20:22:20:30 | call to method Return : String | +| Splitting.cs:21:28:21:32 | access to parameter value : String | Splitting.cs:16:26:16:26 | x : String | Splitting.cs:16:32:16:32 | access to parameter x : String | Splitting.cs:21:21:21:33 | call to method Return : String | +| Splitting.cs:31:19:31:25 | [b (line 24): false] access to parameter tainted : String | Splitting.cs:18:24:18:24 | s : String | Splitting.cs:20:22:20:30 | call to method Return : String | Splitting.cs:31:17:31:26 | [b (line 24): false] dynamic access to element : String | +| Splitting.cs:31:19:31:25 | [b (line 24): true] access to parameter tainted : String | Splitting.cs:18:24:18:24 | s : String | Splitting.cs:20:22:20:30 | call to method Return : String | Splitting.cs:31:17:31:26 | [b (line 24): true] dynamic access to element : String | #select | Capture.cs:12:19:12:24 | access to local variable sink27 | Capture.cs:7:20:7:26 | tainted : String | Capture.cs:12:19:12:24 | access to local variable sink27 | access to local variable sink27 | | Capture.cs:21:23:21:28 | access to local variable sink28 | Capture.cs:7:20:7:26 | tainted : String | Capture.cs:21:23:21:28 | access to local variable sink28 | access to local variable sink28 | diff --git a/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected b/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected index ae634781cd7..733387c87c5 100644 --- a/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected +++ b/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected @@ -144,6 +144,7 @@ nodes | Tuples.cs:89:24:89:37 | "taint source" : String | semmle.label | "taint source" : String | | Tuples.cs:90:14:90:14 | access to local variable r [property i] : String | semmle.label | access to local variable r [property i] : String | | Tuples.cs:90:14:90:16 | access to property i | semmle.label | access to property i | +subpaths #select | Tuples.cs:7:21:7:34 | "taint source" : String | Tuples.cs:7:21:7:34 | "taint source" : String | Tuples.cs:9:14:9:14 | access to local variable a | $@ | Tuples.cs:9:14:9:14 | access to local variable a | access to local variable a | | Tuples.cs:7:21:7:34 | "taint source" : String | Tuples.cs:7:21:7:34 | "taint source" : String | Tuples.cs:14:14:14:14 | access to local variable a | $@ | Tuples.cs:14:14:14:14 | access to local variable a | access to local variable a | diff --git a/csharp/ql/test/library-tests/dataflow/types/Types.expected b/csharp/ql/test/library-tests/dataflow/types/Types.expected index 93be8ab587a..52591455b1e 100644 --- a/csharp/ql/test/library-tests/dataflow/types/Types.expected +++ b/csharp/ql/test/library-tests/dataflow/types/Types.expected @@ -32,17 +32,21 @@ edges | Types.cs:74:9:74:9 | access to local variable d : D | Types.cs:16:30:16:30 | this : D | | Types.cs:77:22:77:22 | a : C | Types.cs:79:18:79:25 | SSA def(b) : C | | Types.cs:79:18:79:25 | SSA def(b) : C | Types.cs:80:18:80:18 | access to local variable b | -| Types.cs:90:22:90:22 | e : Types.E.E2 | Types.cs:92:26:92:26 | access to parameter e : Types.E.E2 | -| Types.cs:92:13:92:16 | [post] this access [field Field] : Types.E.E2 | Types.cs:93:13:93:16 | this access [field Field] : Types.E.E2 | -| Types.cs:92:26:92:26 | access to parameter e : Types.E.E2 | Types.cs:92:13:92:16 | [post] this access [field Field] : Types.E.E2 | -| Types.cs:93:13:93:16 | this access [field Field] : Types.E.E2 | Types.cs:113:34:113:34 | this [field Field] : Types.E.E2 | -| Types.cs:110:25:110:32 | object creation of type E2 : Types.E.E2 | Types.cs:90:22:90:22 | e : Types.E.E2 | -| Types.cs:113:34:113:34 | this [field Field] : Types.E.E2 | Types.cs:115:22:115:25 | this access [field Field] : Types.E.E2 | -| Types.cs:115:22:115:25 | this access [field Field] : Types.E.E2 | Types.cs:115:22:115:31 | access to field Field | +| Types.cs:90:22:90:22 | e : Types+E.E2 | Types.cs:92:26:92:26 | access to parameter e : Types+E.E2 | +| Types.cs:92:13:92:16 | [post] this access [field Field] : Types+E.E2 | Types.cs:93:13:93:16 | this access [field Field] : Types+E.E2 | +| Types.cs:92:26:92:26 | access to parameter e : Types+E.E2 | Types.cs:92:13:92:16 | [post] this access [field Field] : Types+E.E2 | +| Types.cs:93:13:93:16 | this access [field Field] : Types+E.E2 | Types.cs:113:34:113:34 | this [field Field] : Types+E.E2 | +| Types.cs:110:25:110:32 | object creation of type E2 : Types+E.E2 | Types.cs:90:22:90:22 | e : Types+E.E2 | +| Types.cs:113:34:113:34 | this [field Field] : Types+E.E2 | Types.cs:115:22:115:25 | this access [field Field] : Types+E.E2 | +| Types.cs:115:22:115:25 | this access [field Field] : Types+E.E2 | Types.cs:115:22:115:31 | access to field Field | | Types.cs:120:25:120:31 | object creation of type A : A | Types.cs:122:30:122:30 | access to local variable a : A | -| Types.cs:121:26:121:33 | object creation of type E2 : Types.E.E2 | Types.cs:123:30:123:31 | access to local variable e2 : Types.E.E2 | +| Types.cs:121:26:121:33 | object creation of type E2 : Types+E.E2 | Types.cs:123:30:123:31 | access to local variable e2 : Types+E.E2 | | Types.cs:122:30:122:30 | access to local variable a : A | Types.cs:122:22:122:31 | call to method Through | -| Types.cs:123:30:123:31 | access to local variable e2 : Types.E.E2 | Types.cs:123:22:123:32 | call to method Through | +| Types.cs:122:30:122:30 | access to local variable a : A | Types.cs:130:34:130:34 | x : A | +| Types.cs:123:30:123:31 | access to local variable e2 : Types+E.E2 | Types.cs:123:22:123:32 | call to method Through | +| Types.cs:123:30:123:31 | access to local variable e2 : Types+E.E2 | Types.cs:130:34:130:34 | x : Types+E.E2 | +| Types.cs:130:34:130:34 | x : A | Types.cs:130:40:130:40 | access to parameter x : A | +| Types.cs:130:34:130:34 | x : Types+E.E2 | Types.cs:130:40:130:40 | access to parameter x : Types+E.E2 | | Types.cs:138:21:138:25 | this [field Field] : Object | Types.cs:138:32:138:35 | this access [field Field] : Object | | Types.cs:138:32:138:35 | this access [field Field] : Object | Types.cs:153:30:153:30 | this [field Field] : Object | | Types.cs:144:13:144:13 | [post] access to parameter c [field Field] : Object | Types.cs:145:13:145:13 | access to parameter c [field Field] : Object | @@ -93,20 +97,24 @@ nodes | Types.cs:77:22:77:22 | a : C | semmle.label | a : C | | Types.cs:79:18:79:25 | SSA def(b) : C | semmle.label | SSA def(b) : C | | Types.cs:80:18:80:18 | access to local variable b | semmle.label | access to local variable b | -| Types.cs:90:22:90:22 | e : Types.E.E2 | semmle.label | e : Types.E.E2 | -| Types.cs:92:13:92:16 | [post] this access [field Field] : Types.E.E2 | semmle.label | [post] this access [field Field] : Types.E.E2 | -| Types.cs:92:26:92:26 | access to parameter e : Types.E.E2 | semmle.label | access to parameter e : Types.E.E2 | -| Types.cs:93:13:93:16 | this access [field Field] : Types.E.E2 | semmle.label | this access [field Field] : Types.E.E2 | -| Types.cs:110:25:110:32 | object creation of type E2 : Types.E.E2 | semmle.label | object creation of type E2 : Types.E.E2 | -| Types.cs:113:34:113:34 | this [field Field] : Types.E.E2 | semmle.label | this [field Field] : Types.E.E2 | -| Types.cs:115:22:115:25 | this access [field Field] : Types.E.E2 | semmle.label | this access [field Field] : Types.E.E2 | +| Types.cs:90:22:90:22 | e : Types+E.E2 | semmle.label | e : Types+E.E2 | +| Types.cs:92:13:92:16 | [post] this access [field Field] : Types+E.E2 | semmle.label | [post] this access [field Field] : Types+E.E2 | +| Types.cs:92:26:92:26 | access to parameter e : Types+E.E2 | semmle.label | access to parameter e : Types+E.E2 | +| Types.cs:93:13:93:16 | this access [field Field] : Types+E.E2 | semmle.label | this access [field Field] : Types+E.E2 | +| Types.cs:110:25:110:32 | object creation of type E2 : Types+E.E2 | semmle.label | object creation of type E2 : Types+E.E2 | +| Types.cs:113:34:113:34 | this [field Field] : Types+E.E2 | semmle.label | this [field Field] : Types+E.E2 | +| Types.cs:115:22:115:25 | this access [field Field] : Types+E.E2 | semmle.label | this access [field Field] : Types+E.E2 | | Types.cs:115:22:115:31 | access to field Field | semmle.label | access to field Field | | Types.cs:120:25:120:31 | object creation of type A : A | semmle.label | object creation of type A : A | -| Types.cs:121:26:121:33 | object creation of type E2 : Types.E.E2 | semmle.label | object creation of type E2 : Types.E.E2 | +| Types.cs:121:26:121:33 | object creation of type E2 : Types+E.E2 | semmle.label | object creation of type E2 : Types+E.E2 | | Types.cs:122:22:122:31 | call to method Through | semmle.label | call to method Through | | Types.cs:122:30:122:30 | access to local variable a : A | semmle.label | access to local variable a : A | | Types.cs:123:22:123:32 | call to method Through | semmle.label | call to method Through | -| Types.cs:123:30:123:31 | access to local variable e2 : Types.E.E2 | semmle.label | access to local variable e2 : Types.E.E2 | +| Types.cs:123:30:123:31 | access to local variable e2 : Types+E.E2 | semmle.label | access to local variable e2 : Types+E.E2 | +| Types.cs:130:34:130:34 | x : A | semmle.label | x : A | +| Types.cs:130:34:130:34 | x : Types+E.E2 | semmle.label | x : Types+E.E2 | +| Types.cs:130:40:130:40 | access to parameter x : A | semmle.label | access to parameter x : A | +| Types.cs:130:40:130:40 | access to parameter x : Types+E.E2 | semmle.label | access to parameter x : Types+E.E2 | | Types.cs:138:21:138:25 | this [field Field] : Object | semmle.label | this [field Field] : Object | | Types.cs:138:32:138:35 | this access [field Field] : Object | semmle.label | this access [field Field] : Object | | Types.cs:144:13:144:13 | [post] access to parameter c [field Field] : Object | semmle.label | [post] access to parameter c [field Field] : Object | @@ -115,6 +123,9 @@ nodes | Types.cs:153:30:153:30 | this [field Field] : Object | semmle.label | this [field Field] : Object | | Types.cs:153:42:153:45 | this access [field Field] : Object | semmle.label | this access [field Field] : Object | | Types.cs:153:42:153:51 | access to field Field | semmle.label | access to field Field | +subpaths +| Types.cs:122:30:122:30 | access to local variable a : A | Types.cs:130:34:130:34 | x : A | Types.cs:130:40:130:40 | access to parameter x : A | Types.cs:122:22:122:31 | call to method Through : A | +| Types.cs:123:30:123:31 | access to local variable e2 : Types+E.E2 | Types.cs:130:34:130:34 | x : Types+E.E2 | Types.cs:130:40:130:40 | access to parameter x : Types+E.E2 | Types.cs:123:22:123:32 | call to method Through : Types+E.E2 | #select | Types.cs:23:12:23:18 | object creation of type C : C | Types.cs:23:12:23:18 | object creation of type C : C | Types.cs:50:18:50:18 | access to local variable c | $@ | Types.cs:50:18:50:18 | access to local variable c | access to local variable c | | Types.cs:25:12:25:18 | object creation of type C : C | Types.cs:25:12:25:18 | object creation of type C : C | Types.cs:63:33:63:36 | (...) ... | $@ | Types.cs:63:33:63:36 | (...) ... | (...) ... | @@ -130,7 +141,7 @@ nodes | Types.cs:39:12:39:18 | object creation of type D : D | Types.cs:39:12:39:18 | object creation of type D : D | Types.cs:69:52:69:52 | access to parameter x | $@ | Types.cs:69:52:69:52 | access to parameter x | access to parameter x | | Types.cs:40:12:40:18 | object creation of type D : D | Types.cs:40:12:40:18 | object creation of type D : D | Types.cs:16:42:16:45 | this access | $@ | Types.cs:16:42:16:45 | this access | this access | | Types.cs:43:20:43:23 | null : null | Types.cs:43:20:43:23 | null : null | Types.cs:44:14:44:14 | access to local variable o | $@ | Types.cs:44:14:44:14 | access to local variable o | access to local variable o | -| Types.cs:110:25:110:32 | object creation of type E2 : Types.E.E2 | Types.cs:110:25:110:32 | object creation of type E2 : Types.E.E2 | Types.cs:115:22:115:31 | access to field Field | $@ | Types.cs:115:22:115:31 | access to field Field | access to field Field | +| Types.cs:110:25:110:32 | object creation of type E2 : Types+E.E2 | Types.cs:110:25:110:32 | object creation of type E2 : Types+E.E2 | Types.cs:115:22:115:31 | access to field Field | $@ | Types.cs:115:22:115:31 | access to field Field | access to field Field | | Types.cs:120:25:120:31 | object creation of type A : A | Types.cs:120:25:120:31 | object creation of type A : A | Types.cs:122:22:122:31 | call to method Through | $@ | Types.cs:122:22:122:31 | call to method Through | call to method Through | -| Types.cs:121:26:121:33 | object creation of type E2 : Types.E.E2 | Types.cs:121:26:121:33 | object creation of type E2 : Types.E.E2 | Types.cs:123:22:123:32 | call to method Through | $@ | Types.cs:123:22:123:32 | call to method Through | call to method Through | +| Types.cs:121:26:121:33 | object creation of type E2 : Types+E.E2 | Types.cs:121:26:121:33 | object creation of type E2 : Types+E.E2 | Types.cs:123:22:123:32 | call to method Through | $@ | Types.cs:123:22:123:32 | call to method Through | call to method Through | | Types.cs:144:23:144:34 | object creation of type Object : Object | Types.cs:144:23:144:34 | object creation of type Object : Object | Types.cs:153:42:153:51 | access to field Field | $@ | Types.cs:153:42:153:51 | access to field Field | access to field Field | diff --git a/csharp/ql/test/library-tests/dispatch/CallGraph.expected b/csharp/ql/test/library-tests/dispatch/CallGraph.expected index 29ede96fecb..213fc0eb4cf 100644 --- a/csharp/ql/test/library-tests/dispatch/CallGraph.expected +++ b/csharp/ql/test/library-tests/dispatch/CallGraph.expected @@ -236,3 +236,5 @@ | ViableCallable.cs:452:10:452:14 | M4<> | ViableCallable.cs:444:23:444:27 | M2<> | | ViableCallable.cs:458:10:458:14 | M5<> | ViableCallable.cs:430:22:430:26 | M2<> | | ViableCallable.cs:458:10:458:14 | M5<> | ViableCallable.cs:444:23:444:27 | M2<> | +| ViableCallable.cs:475:10:475:12 | Run | ViableCallable.cs:468:10:468:11 | M2 | +| ViableCallable.cs:475:10:475:12 | Run | ViableCallable.cs:473:17:473:18 | M1 | diff --git a/csharp/ql/test/library-tests/dispatch/GetADynamicTarget.expected b/csharp/ql/test/library-tests/dispatch/GetADynamicTarget.expected index 5bd5d631f21..fb0547dffcd 100644 --- a/csharp/ql/test/library-tests/dispatch/GetADynamicTarget.expected +++ b/csharp/ql/test/library-tests/dispatch/GetADynamicTarget.expected @@ -469,3 +469,5 @@ | ViableCallable.cs:455:9:455:30 | call to method M2 | C17.M2(Func) | | ViableCallable.cs:461:9:461:30 | call to method M2 | C16.M2(Func) | | ViableCallable.cs:461:9:461:30 | call to method M2 | C17.M2(Func) | +| ViableCallable.cs:478:9:478:14 | call to method M1 | C18.M1() | +| ViableCallable.cs:481:9:481:14 | call to method M2 | I2.M2() | diff --git a/csharp/ql/test/library-tests/dispatch/ViableCallable.cs b/csharp/ql/test/library-tests/dispatch/ViableCallable.cs index d8c725eb95a..c742789fef3 100644 --- a/csharp/ql/test/library-tests/dispatch/ViableCallable.cs +++ b/csharp/ql/test/library-tests/dispatch/ViableCallable.cs @@ -461,3 +461,23 @@ class C17 : C16 c.M2(() => default(T)); } } + +interface I2 +{ + void M1(); + void M2() => throw null; +} + +class C18 : I2 +{ + public void M1() { } + + void Run(I2 i) + { + // Viable callables: C18.M1() + i.M1(); + + // Viable callables: I2.M2() + i.M2(); + } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/dispatch/viableCallable.expected b/csharp/ql/test/library-tests/dispatch/viableCallable.expected index 5b3b2fef76b..95aa00747e4 100644 --- a/csharp/ql/test/library-tests/dispatch/viableCallable.expected +++ b/csharp/ql/test/library-tests/dispatch/viableCallable.expected @@ -251,3 +251,5 @@ | ViableCallable.cs:419:9:419:21 | call to method M | M<> | A4 | | ViableCallable.cs:423:9:423:21 | call to method M | M<> | A4 | | ViableCallable.cs:423:9:423:21 | call to method M | M<> | A5 | +| ViableCallable.cs:478:9:478:14 | call to method M1 | M1 | C18 | +| ViableCallable.cs:481:9:481:14 | call to method M2 | M2 | I2 | diff --git a/csharp/ql/test/library-tests/frameworks/EntityFramework/Dataflow.expected b/csharp/ql/test/library-tests/frameworks/EntityFramework/Dataflow.expected index 2adf27813df..18a086d8227 100644 --- a/csharp/ql/test/library-tests/frameworks/EntityFramework/Dataflow.expected +++ b/csharp/ql/test/library-tests/frameworks/EntityFramework/Dataflow.expected @@ -341,6 +341,7 @@ nodes | EntityFrameworkCore.cs:245:18:245:46 | access to property Addresses [element, property Street] : String | semmle.label | access to property Addresses [element, property Street] : String | | EntityFrameworkCore.cs:245:18:245:54 | call to method First
    [property Street] : String | semmle.label | call to method First
    [property Street] : String | | EntityFrameworkCore.cs:245:18:245:61 | access to property Street | semmle.label | access to property Street | +subpaths #select | EntityFramework.cs:129:18:129:25 | access to property Title | EntityFramework.cs:124:25:124:33 | "tainted" : String | EntityFramework.cs:129:18:129:25 | access to property Title | $@ | EntityFramework.cs:124:25:124:33 | "tainted" : String | "tainted" : String | | EntityFramework.cs:204:18:204:41 | access to property Name | EntityFramework.cs:61:24:61:32 | "tainted" : String | EntityFramework.cs:204:18:204:41 | access to property Name | $@ | EntityFramework.cs:61:24:61:32 | "tainted" : String | "tainted" : String | diff --git a/csharp/ql/test/library-tests/frameworks/ServiceStack/SinksExternal.cs b/csharp/ql/test/library-tests/frameworks/ServiceStack/SinksExternal.cs new file mode 100644 index 00000000000..65e77d237c9 --- /dev/null +++ b/csharp/ql/test/library-tests/frameworks/ServiceStack/SinksExternal.cs @@ -0,0 +1,61 @@ +using System.Collections.Generic; +using System.Linq; +using ServiceStack; +using System.Threading.Tasks; +using System; +using Microsoft.Extensions.ObjectPool; +using System.IO; + +namespace ServiceStackTest +{ + public class ResponseDto { } + public class ReqDto1 : IReturn { } + + public class ReqDto2 : IReturnVoid { } + + public class C + { + public async Task M() + { + var client = new JsonServiceClient(""); + + client.DeserializeFromStream(new MemoryStream()); // not a sink + + client.Get(new ReqDto1()); + client.Get(new ReqDto2()); + client.Get("relativeOrAbsoluteUrl"); // not a sink + client.Get(new object()); + client.Get("relativeOrAbsoluteUrl"); // not a sink + client.Get(new object()); + + await client.GetAsync("relativeOrAbsoluteUrl"); // not a sink + await client.GetAsync(new object()); + await client.GetAsync(new ReqDto1()); + await client.GetAsync(new ReqDto2()); + + + client.CustomMethod("GET", new ReqDto2()); + client.CustomMethod("GET", "relativeOrAbsoluteUrl", new ReqDto1()); + client.CustomMethod("GET", new ReqDto1()); + client.CustomMethod("GET", new object()); + client.CustomMethod("GET", "relativeOrAbsoluteUrl", new object()); + client.CustomMethod("GET", (IReturnVoid)null); + await client.CustomMethodAsync("GET", new ReqDto2()); + await client.CustomMethodAsync("GET", "relativeOrAbsoluteUrl", new ReqDto1()); + await client.CustomMethodAsync("GET", new ReqDto1()); + await client.CustomMethodAsync("GET", new object()); + + client.DownloadBytes("GET", "requestUri", new object()); + await client.DownloadBytesAsync("GET", "relativeOrAbsoluteUrl", new object()); + + client.Head(new object()); + client.Patch(new object()); + client.Post(new object()); + client.Put(new object()); + + client.Send(new object()); + client.Publish(new ReqDto1()); + client.SendOneWay(new object()); + } + } +} diff --git a/csharp/ql/test/library-tests/frameworks/ServiceStack/SinksInjection.cs b/csharp/ql/test/library-tests/frameworks/ServiceStack/SinksInjection.cs new file mode 100644 index 00000000000..19c8f14a582 --- /dev/null +++ b/csharp/ql/test/library-tests/frameworks/ServiceStack/SinksInjection.cs @@ -0,0 +1,74 @@ +using System.Collections.Generic; +using System.Linq; +using ServiceStack; +using System.Threading.Tasks; +using System; +using Microsoft.AspNetCore.Components.Forms; +using ServiceStack.OrmLite; + +namespace ServiceStackTest +{ + public class Table + { + public int Column { get; set; } + } + + public class Sql + { + public static async Task M() + { + ServiceStack.OrmLite.SqlExpression expr = null; + + expr = expr.Select(t => t.Column); // ok + + expr = expr + .UnsafeAnd("SQL") + .UnsafeFrom("SQL") + .UnsafeGroupBy("SQL") + .UnsafeHaving("SQL") + .UnsafeOr("SQL") + .UnsafeOrderBy("SQL") + .UnsafeSelect("SQL") + .UnsafeWhere("SQL"); + + var untyped = expr.GetUntypedSqlExpression(); + + untyped + .UnsafeAnd("SQL") + .UnsafeFrom("SQL") + .UnsafeOr("SQL") + .UnsafeSelect("SQL") + .UnsafeWhere("SQL") + .Where("SQL"); // safe + + System.Data.IDbConnection conn = null; + + var row = conn.SingleById
    (1); // ok + + var rows = conn.Select
    (typeof(Table), "SQL", null); + rows = await conn.SelectAsync
    (typeof(Table), "SQL", null); + + var count = conn.RowCount("SQL"); + count = await conn.RowCountAsync("SQL"); + + conn.ExecuteSql("SQL", null); + await conn.ExecuteSqlAsync("SQL", null); + } + + public static async Task Redis() + { + ServiceStack.Redis.IRedisClient client = null; + + client.SetValue("key", "value"); // ok + + var s = client.LoadLuaScript("script"); + client.ExecLua("script", new[] { "" }, new[] { "" }); + client.ExecLuaSha("SHA", new[] { "" }, new[] { "" }); // ok + client.Custom("command", "arg"); // false negative, params sinks doesn't work + + ServiceStack.Redis.IRedisClientAsync asyncClient = null; + s = await asyncClient.LoadLuaScriptAsync("script"); + asyncClient.ExecLuaAsync("script", new[] { "" }, new[] { "" }); + } + } +} diff --git a/csharp/ql/test/library-tests/frameworks/ServiceStack/SinksXss.cs b/csharp/ql/test/library-tests/frameworks/ServiceStack/SinksXss.cs new file mode 100644 index 00000000000..df3bbd155de --- /dev/null +++ b/csharp/ql/test/library-tests/frameworks/ServiceStack/SinksXss.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using System.Linq; +using ServiceStack; +using System.Threading.Tasks; +using System; + +namespace ServiceStackTest +{ + public class XssServices : Service + { + public object Get(Request1 request) + { + return ""); + } + + // GOOD: use the method `writeText` that performs escaping appropriate for the markup language being rendered. + public void encodeBegin2(FacesContext facesContext, UIComponent component) throws IOException + { + super.encodeBegin(facesContext, component); + + Map requestParameters = facesContext.getExternalContext().getRequestParameterMap(); + String windowId = requestParameters.get("window_id"); + + ResponseWriter writer = facesContext.getResponseWriter(); + writer.write(""); + } + + public void testAllSources(FacesContext facesContext) throws IOException + { + ExternalContext ec = facesContext.getExternalContext(); + ResponseWriter writer = facesContext.getResponseWriter(); + writer.write(ec.getRequestParameterMap().keySet().iterator().next()); // $xss + writer.write(ec.getRequestParameterNames().next()); // $xss + writer.write(ec.getRequestParameterValuesMap().get("someKey")[0]); // $xss + writer.write(ec.getRequestParameterValuesMap().keySet().iterator().next()); // $xss + writer.write(ec.getRequestPathInfo()); // $xss + writer.write(((Cookie)ec.getRequestCookieMap().get("someKey")).getName()); // $xss + writer.write(ec.getRequestHeaderMap().get("someKey")); // $xss + writer.write(ec.getRequestHeaderValuesMap().get("someKey")[0]); // $xss + } +} diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/SpringXSS.java b/java/ql/test/query-tests/security/CWE-079/semmle/tests/SpringXSS.java index 744fe853b67..49ea5165fd4 100644 --- a/java/ql/test/query-tests/security/CWE-079/semmle/tests/SpringXSS.java +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/SpringXSS.java @@ -28,11 +28,11 @@ public class SpringXSS { } else { if(chainDirectly) { - return builder.contentType(MediaType.APPLICATION_JSON).body(userControlled); // $SPURIOUS: xss + return builder.contentType(MediaType.APPLICATION_JSON).body(userControlled); } else { ResponseEntity.BodyBuilder builder2 = builder.contentType(MediaType.APPLICATION_JSON); - return builder2.body(userControlled); // $SPURIOUS: xss + return builder2.body(userControlled); } } @@ -60,7 +60,7 @@ public class SpringXSS { @GetMapping(value = "/xyz", produces = MediaType.TEXT_HTML_VALUE) public static ResponseEntity methodContentTypeUnsafe(String userControlled) { - return ResponseEntity.ok(userControlled); // $MISSING: xss + return ResponseEntity.ok(userControlled); // $xss } @GetMapping(value = "/xyz", produces = "text/html") @@ -75,7 +75,7 @@ public class SpringXSS { @GetMapping(value = "/xyz", produces = MediaType.APPLICATION_JSON_VALUE) public static ResponseEntity methodContentTypeSafeOverriddenWithUnsafe(String userControlled) { - return ResponseEntity.ok().contentType(MediaType.TEXT_HTML).body(userControlled); // $MISSING: xss + return ResponseEntity.ok().contentType(MediaType.TEXT_HTML).body(userControlled); // $xss } @GetMapping(value = "/xyz", produces = MediaType.TEXT_HTML_VALUE) @@ -105,12 +105,12 @@ public class SpringXSS { private static class ClassContentTypeSafe { @GetMapping(value = "/abc") public ResponseEntity test(String userControlled) { - return ResponseEntity.ok(userControlled); // $SPURIOUS: xss + return ResponseEntity.ok(userControlled); } @GetMapping(value = "/abc") public String testDirectReturn(String userControlled) { - return userControlled; // $SPURIOUS: xss + return userControlled; } @GetMapping(value = "/xyz", produces = {"text/html"}) @@ -139,12 +139,12 @@ public class SpringXSS { @GetMapping(value = "/xyz", produces = {"application/json"}) public ResponseEntity overridesWithSafe(String userControlled) { - return ResponseEntity.ok(userControlled); // $SPURIOUS: xss + return ResponseEntity.ok(userControlled); } @GetMapping(value = "/abc") public ResponseEntity overridesWithSafe2(String userControlled) { - return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(userControlled); // $SPURIOUS: xss + return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(userControlled); } } diff --git a/java/ql/test/query-tests/security/CWE-079/semmle/tests/options b/java/ql/test/query-tests/security/CWE-079/semmle/tests/options index 719c5e3dd57..22487fb2daf 100644 --- a/java/ql/test/query-tests/security/CWE-079/semmle/tests/options +++ b/java/ql/test/query-tests/security/CWE-079/semmle/tests/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/javax-ws-rs-api-2.1.1/:${testdir}/../../../../../stubs/springframework-5.3.8 +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/javax-ws-rs-api-2.1.1/:${testdir}/../../../../../stubs/springframework-5.3.8:${testdir}/../../../../../stubs/javax-faces-2.3/ diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTaintedLocal.expected b/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTaintedLocal.expected index 4ecdc32c204..aea462f3861 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTaintedLocal.expected +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTaintedLocal.expected @@ -4,9 +4,13 @@ edges | Test.java:29:30:29:42 | args : String[] | Test.java:36:47:36:52 | query1 | | Test.java:29:30:29:42 | args : String[] | Test.java:42:57:42:62 | query2 | | Test.java:29:30:29:42 | args : String[] | Test.java:50:62:50:67 | query3 | -| Test.java:29:30:29:42 | args : String[] | Test.java:62:47:62:61 | querySbToString | +| Test.java:29:30:29:42 | args : String[] | Test.java:58:19:58:26 | category : String | | Test.java:29:30:29:42 | args : String[] | Test.java:70:40:70:44 | query | | Test.java:29:30:29:42 | args : String[] | Test.java:78:46:78:50 | query | +| Test.java:58:4:58:10 | querySb [post update] : StringBuilder | Test.java:60:29:60:35 | querySb : StringBuilder | +| Test.java:58:19:58:26 | category : String | Test.java:58:4:58:10 | querySb [post update] : StringBuilder | +| Test.java:60:29:60:35 | querySb : StringBuilder | Test.java:60:29:60:46 | toString(...) : String | +| Test.java:60:29:60:46 | toString(...) : String | Test.java:62:47:62:61 | querySbToString | | Test.java:183:33:183:45 | args : String[] | Test.java:209:47:209:68 | queryWithUserTableName | | Test.java:213:26:213:38 | args : String[] | Test.java:214:11:214:14 | args : String[] | | Test.java:213:26:213:38 | args : String[] | Test.java:218:14:218:17 | args : String[] | @@ -20,6 +24,10 @@ nodes | Test.java:36:47:36:52 | query1 | semmle.label | query1 | | Test.java:42:57:42:62 | query2 | semmle.label | query2 | | Test.java:50:62:50:67 | query3 | semmle.label | query3 | +| Test.java:58:4:58:10 | querySb [post update] : StringBuilder | semmle.label | querySb [post update] : StringBuilder | +| Test.java:58:19:58:26 | category : String | semmle.label | category : String | +| Test.java:60:29:60:35 | querySb : StringBuilder | semmle.label | querySb : StringBuilder | +| Test.java:60:29:60:46 | toString(...) : String | semmle.label | toString(...) : String | | Test.java:62:47:62:61 | querySbToString | semmle.label | querySbToString | | Test.java:70:40:70:44 | query | semmle.label | query | | Test.java:78:46:78:50 | query | semmle.label | query | @@ -28,6 +36,7 @@ nodes | Test.java:213:26:213:38 | args : String[] | semmle.label | args : String[] | | Test.java:214:11:214:14 | args : String[] | semmle.label | args : String[] | | Test.java:218:14:218:17 | args : String[] | semmle.label | args : String[] | +subpaths #select | Mongo.java:17:45:17:67 | parse(...) | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:17:45:17:67 | parse(...) | Query might include code from $@. | Mongo.java:10:29:10:41 | args | this user input | | Mongo.java:21:49:21:52 | json | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:21:49:21:52 | json | Query might include code from $@. | Mongo.java:10:29:10:41 | args | this user input | diff --git a/java/ql/test/query-tests/security/CWE-090/LdapInjection.expected b/java/ql/test/query-tests/security/CWE-090/LdapInjection.expected index 34e6033320c..e296c8e92aa 100644 --- a/java/ql/test/query-tests/security/CWE-090/LdapInjection.expected +++ b/java/ql/test/query-tests/security/CWE-090/LdapInjection.expected @@ -28,7 +28,8 @@ edges | LdapInjection.java:147:76:147:109 | uBadSRDNAsync : String | LdapInjection.java:151:19:151:19 | s | | LdapInjection.java:155:31:155:70 | uBadFilterCreateNOT : String | LdapInjection.java:156:58:156:115 | createNOTFilter(...) | | LdapInjection.java:160:31:160:75 | uBadFilterCreateToString : String | LdapInjection.java:161:58:161:107 | toString(...) | -| LdapInjection.java:165:32:165:82 | uBadFilterCreateToStringBuffer : String | LdapInjection.java:168:58:168:69 | toString(...) | +| LdapInjection.java:165:32:165:82 | uBadFilterCreateToStringBuffer : String | LdapInjection.java:168:58:168:58 | b : StringBuilder | +| LdapInjection.java:168:58:168:58 | b : StringBuilder | LdapInjection.java:168:58:168:69 | toString(...) | | LdapInjection.java:172:32:172:78 | uBadSearchRequestDuplicate : String | LdapInjection.java:176:14:176:26 | duplicate(...) | | LdapInjection.java:180:32:180:80 | uBadROSearchRequestDuplicate : String | LdapInjection.java:184:14:184:26 | duplicate(...) | | LdapInjection.java:188:32:188:74 | uBadSearchRequestSetDN : String | LdapInjection.java:192:14:192:14 | s | @@ -49,7 +50,8 @@ edges | LdapInjection.java:276:31:276:68 | sBadLdapQueryBase : String | LdapInjection.java:277:12:277:66 | base(...) | | LdapInjection.java:281:31:281:71 | sBadLdapQueryComplex : String | LdapInjection.java:282:24:282:98 | is(...) | | LdapInjection.java:286:31:286:69 | sBadFilterToString : String | LdapInjection.java:287:18:287:83 | toString(...) | -| LdapInjection.java:291:31:291:67 | sBadFilterEncode : String | LdapInjection.java:294:18:294:29 | toString(...) | +| LdapInjection.java:291:31:291:67 | sBadFilterEncode : String | LdapInjection.java:294:18:294:18 | s : StringBuffer | +| LdapInjection.java:294:18:294:18 | s : StringBuffer | LdapInjection.java:294:18:294:29 | toString(...) | | LdapInjection.java:314:30:314:54 | aBad : String | LdapInjection.java:316:36:316:55 | ... + ... | | LdapInjection.java:314:57:314:83 | aBadDN : String | LdapInjection.java:316:14:316:33 | ... + ... | | LdapInjection.java:320:30:320:54 | aBad : String | LdapInjection.java:322:65:322:84 | ... + ... | @@ -113,6 +115,7 @@ nodes | LdapInjection.java:160:31:160:75 | uBadFilterCreateToString : String | semmle.label | uBadFilterCreateToString : String | | LdapInjection.java:161:58:161:107 | toString(...) | semmle.label | toString(...) | | LdapInjection.java:165:32:165:82 | uBadFilterCreateToStringBuffer : String | semmle.label | uBadFilterCreateToStringBuffer : String | +| LdapInjection.java:168:58:168:58 | b : StringBuilder | semmle.label | b : StringBuilder | | LdapInjection.java:168:58:168:69 | toString(...) | semmle.label | toString(...) | | LdapInjection.java:172:32:172:78 | uBadSearchRequestDuplicate : String | semmle.label | uBadSearchRequestDuplicate : String | | LdapInjection.java:176:14:176:26 | duplicate(...) | semmle.label | duplicate(...) | @@ -155,6 +158,7 @@ nodes | LdapInjection.java:286:31:286:69 | sBadFilterToString : String | semmle.label | sBadFilterToString : String | | LdapInjection.java:287:18:287:83 | toString(...) | semmle.label | toString(...) | | LdapInjection.java:291:31:291:67 | sBadFilterEncode : String | semmle.label | sBadFilterEncode : String | +| LdapInjection.java:294:18:294:18 | s : StringBuffer | semmle.label | s : StringBuffer | | LdapInjection.java:294:18:294:29 | toString(...) | semmle.label | toString(...) | | LdapInjection.java:314:30:314:54 | aBad : String | semmle.label | aBad : String | | LdapInjection.java:314:57:314:83 | aBadDN : String | semmle.label | aBadDN : String | @@ -170,6 +174,7 @@ nodes | LdapInjection.java:338:14:338:14 | s | semmle.label | s | | LdapInjection.java:342:30:342:72 | aBadDNSearchRequestGet : String | semmle.label | aBadDNSearchRequestGet : String | | LdapInjection.java:346:14:346:24 | getBase(...) | semmle.label | getBase(...) | +subpaths #select | LdapInjection.java:47:16:47:35 | ... + ... | LdapInjection.java:45:55:45:81 | jBadDN : String | LdapInjection.java:47:16:47:35 | ... + ... | LDAP query might include code from $@. | LdapInjection.java:45:55:45:81 | jBadDN | this user input | | LdapInjection.java:47:38:47:57 | ... + ... | LdapInjection.java:45:28:45:52 | jBad : String | LdapInjection.java:47:38:47:57 | ... + ... | LDAP query might include code from $@. | LdapInjection.java:45:28:45:52 | jBad | this user input | diff --git a/java/ql/test/query-tests/security/CWE-094/InsecureBeanValidation.expected b/java/ql/test/query-tests/security/CWE-094/InsecureBeanValidation.expected index 91b794a0682..87cfbf16ef4 100644 --- a/java/ql/test/query-tests/security/CWE-094/InsecureBeanValidation.expected +++ b/java/ql/test/query-tests/security/CWE-094/InsecureBeanValidation.expected @@ -3,5 +3,6 @@ edges nodes | InsecureBeanValidation.java:7:28:7:40 | object : String | semmle.label | object : String | | InsecureBeanValidation.java:11:64:11:68 | value | semmle.label | value | +subpaths #select | InsecureBeanValidation.java:11:64:11:68 | value | InsecureBeanValidation.java:7:28:7:40 | object : String | InsecureBeanValidation.java:11:64:11:68 | value | Custom constraint error message contains unsanitized user data | diff --git a/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.expected b/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/experimental/query-tests/security/CWE-094/SpelInjection.java b/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.java similarity index 76% rename from java/ql/test/experimental/query-tests/security/CWE-094/SpelInjection.java rename to java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.java index 9eeb552ef34..d10bcfa6686 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-094/SpelInjection.java +++ b/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.java @@ -3,11 +3,12 @@ import java.io.InputStream; import java.net.Socket; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; +import org.springframework.expression.spel.standard.SpelExpression; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.SimpleEvaluationContext; import org.springframework.expression.spel.support.StandardEvaluationContext; -public class SpelInjection { +public class SpelInjectionTest { private static final ExpressionParser PARSER = new SpelExpressionParser(); @@ -20,7 +21,18 @@ public class SpelInjection { ExpressionParser parser = new SpelExpressionParser(); Expression expression = parser.parseExpression(input); - expression.getValue(); + expression.getValue(); // $hasSpelInjection + } + + public void testGetValueWithParseRaw(Socket socket) throws IOException { + InputStream in = socket.getInputStream(); + + byte[] bytes = new byte[1024]; + int n = in.read(bytes); + String input = new String(bytes, 0, n); + SpelExpressionParser parser = new SpelExpressionParser(); + SpelExpression expression = parser.parseRaw(input); + expression.getValue(); // $hasSpelInjection } public void testGetValueWithChainedCalls(Socket socket) throws IOException { @@ -31,7 +43,7 @@ public class SpelInjection { String input = new String(bytes, 0, n); Expression expression = new SpelExpressionParser().parseExpression(input); - expression.getValue(); + expression.getValue(); // $hasSpelInjection } public void testSetValueWithRootObject(Socket socket) throws IOException { @@ -45,7 +57,7 @@ public class SpelInjection { Object root = new Object(); Object value = new Object(); - expression.setValue(root, value); + expression.setValue(root, value); // $hasSpelInjection } public void testGetValueWithStaticParser(Socket socket) throws IOException { @@ -56,7 +68,7 @@ public class SpelInjection { String input = new String(bytes, 0, n); Expression expression = PARSER.parseExpression(input); - expression.getValue(); + expression.getValue(); // $hasSpelInjection } public void testGetValueType(Socket socket) throws IOException { @@ -67,7 +79,7 @@ public class SpelInjection { String input = new String(bytes, 0, n); Expression expression = PARSER.parseExpression(input); - expression.getValueType(); + expression.getValueType(); // $hasSpelInjection } public void testWithStandardEvaluationContext(Socket socket) throws IOException { @@ -80,7 +92,7 @@ public class SpelInjection { Expression expression = PARSER.parseExpression(input); StandardEvaluationContext context = new StandardEvaluationContext(); - expression.getValue(context); + expression.getValue(context); // $hasSpelInjection } public void testWithSimpleEvaluationContext(Socket socket) throws IOException { @@ -93,8 +105,7 @@ public class SpelInjection { Expression expression = PARSER.parseExpression(input); SimpleEvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build(); - // the expression is evaluated in a limited context - expression.getValue(context); + expression.getValue(context); // Safe - the expression is evaluated in a limited context } } diff --git a/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.ql b/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.ql new file mode 100644 index 00000000000..1da99aa3de8 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.ql @@ -0,0 +1,22 @@ +import java +import semmle.code.java.dataflow.TaintTracking +import semmle.code.java.dataflow.FlowSources +import semmle.code.java.security.SpelInjectionQuery +import TestUtilities.InlineExpectationsTest + +class HasSpelInjectionTest extends InlineExpectationsTest { + HasSpelInjectionTest() { this = "HasSpelInjectionTest" } + + override string getARelevantTag() { result = "hasSpelInjection" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasSpelInjection" and + exists(DataFlow::Node src, DataFlow::Node sink, SpelInjectionConfig conf | + conf.hasFlow(src, sink) + | + sink.getLocation() = location and + element = sink.toString() and + value = "" + ) + } +} diff --git a/java/ql/test/query-tests/security/CWE-113/semmle/tests/ResponseSplitting.expected b/java/ql/test/query-tests/security/CWE-113/semmle/tests/ResponseSplitting.expected index 1b4efe7781e..35cba00aa6b 100644 --- a/java/ql/test/query-tests/security/CWE-113/semmle/tests/ResponseSplitting.expected +++ b/java/ql/test/query-tests/security/CWE-113/semmle/tests/ResponseSplitting.expected @@ -7,6 +7,7 @@ nodes | ResponseSplitting.java:23:23:23:28 | cookie | semmle.label | cookie | | ResponseSplitting.java:28:38:28:72 | getParameter(...) | semmle.label | getParameter(...) | | ResponseSplitting.java:29:38:29:72 | getParameter(...) | semmle.label | getParameter(...) | +subpaths #select | ResponseSplitting.java:23:23:23:28 | cookie | ResponseSplitting.java:22:39:22:66 | getParameter(...) : String | ResponseSplitting.java:23:23:23:28 | cookie | Response-splitting vulnerability due to this $@. | ResponseSplitting.java:22:39:22:66 | getParameter(...) | user-provided value | | ResponseSplitting.java:28:38:28:72 | getParameter(...) | ResponseSplitting.java:28:38:28:72 | getParameter(...) | ResponseSplitting.java:28:38:28:72 | getParameter(...) | Response-splitting vulnerability due to this $@. | ResponseSplitting.java:28:38:28:72 | getParameter(...) | user-provided value | diff --git a/java/ql/test/query-tests/security/CWE-129/semmle/tests/ImproperValidationOfArrayConstructionCodeSpecified.expected b/java/ql/test/query-tests/security/CWE-129/semmle/tests/ImproperValidationOfArrayConstructionCodeSpecified.expected index 96e17758535..a124f5731a3 100644 --- a/java/ql/test/query-tests/security/CWE-129/semmle/tests/ImproperValidationOfArrayConstructionCodeSpecified.expected +++ b/java/ql/test/query-tests/security/CWE-129/semmle/tests/ImproperValidationOfArrayConstructionCodeSpecified.expected @@ -3,5 +3,6 @@ edges nodes | Test.java:105:16:105:16 | 0 : Number | semmle.label | 0 : Number | | Test.java:107:27:107:30 | size | semmle.label | size | +subpaths #select | Test.java:110:30:110:30 | 0 | Test.java:105:16:105:16 | 0 : Number | Test.java:107:27:107:30 | size | The $@ is accessed here, but the array is initialized using $@ which may be zero. | Test.java:107:19:107:31 | new int[] | array | Test.java:105:16:105:16 | 0 | literal value 0 | diff --git a/java/ql/test/query-tests/security/CWE-129/semmle/tests/ImproperValidationOfArrayConstructionLocal.expected b/java/ql/test/query-tests/security/CWE-129/semmle/tests/ImproperValidationOfArrayConstructionLocal.expected index 4778b39b05c..4ba2d5e8549 100644 --- a/java/ql/test/query-tests/security/CWE-129/semmle/tests/ImproperValidationOfArrayConstructionLocal.expected +++ b/java/ql/test/query-tests/security/CWE-129/semmle/tests/ImproperValidationOfArrayConstructionLocal.expected @@ -1,10 +1,15 @@ edges -| Test.java:76:27:76:60 | getProperty(...) : String | Test.java:80:31:80:34 | size | -| Test.java:76:27:76:60 | getProperty(...) : String | Test.java:86:34:86:37 | size | +| Test.java:76:27:76:60 | getProperty(...) : String | Test.java:78:37:78:48 | userProperty : String | +| Test.java:78:37:78:48 | userProperty : String | Test.java:78:37:78:55 | trim(...) : String | +| Test.java:78:37:78:55 | trim(...) : String | Test.java:80:31:80:34 | size | +| Test.java:78:37:78:55 | trim(...) : String | Test.java:86:34:86:37 | size | nodes | Test.java:76:27:76:60 | getProperty(...) : String | semmle.label | getProperty(...) : String | +| Test.java:78:37:78:48 | userProperty : String | semmle.label | userProperty : String | +| Test.java:78:37:78:55 | trim(...) : String | semmle.label | trim(...) : String | | Test.java:80:31:80:34 | size | semmle.label | size | | Test.java:86:34:86:37 | size | semmle.label | size | +subpaths #select | Test.java:83:34:83:34 | 0 | Test.java:76:27:76:60 | getProperty(...) : String | Test.java:80:31:80:34 | size | The $@ is accessed here, but the array is initialized using $@ which may be zero. | Test.java:80:23:80:35 | new int[] | array | Test.java:76:27:76:60 | getProperty(...) | User-provided value | | Test.java:89:37:89:37 | 0 | Test.java:76:27:76:60 | getProperty(...) : String | Test.java:86:34:86:37 | size | The $@ is accessed here, but the array is initialized using $@ which may be zero. | Test.java:86:26:86:38 | new int[] | array | Test.java:76:27:76:60 | getProperty(...) | User-provided value | diff --git a/java/ql/test/query-tests/security/CWE-129/semmle/tests/ImproperValidationOfArrayIndexCodeSpecified.expected b/java/ql/test/query-tests/security/CWE-129/semmle/tests/ImproperValidationOfArrayIndexCodeSpecified.expected index ce91f8c47fd..16de93aaec8 100644 --- a/java/ql/test/query-tests/security/CWE-129/semmle/tests/ImproperValidationOfArrayIndexCodeSpecified.expected +++ b/java/ql/test/query-tests/security/CWE-129/semmle/tests/ImproperValidationOfArrayIndexCodeSpecified.expected @@ -24,6 +24,7 @@ nodes | Test.java:112:17:112:17 | 0 : Number | semmle.label | 0 : Number | | Test.java:115:32:115:36 | index | semmle.label | index | | Test.java:121:30:121:30 | 0 | semmle.label | 0 | +subpaths #select | Test.java:44:30:44:34 | index | Test.java:41:17:41:48 | nextInt(...) : Number | Test.java:44:30:44:34 | index | $@ flows to the index used in this array access, and may cause the operation to throw an ArrayIndexOutOfBoundsException. | Test.java:41:17:41:48 | nextInt(...) | Random value | | Test.java:62:30:62:34 | index | Test.java:59:17:59:42 | nextInt(...) : Number | Test.java:62:30:62:34 | index | $@ flows to the index used in this array access, and may cause the operation to throw an ArrayIndexOutOfBoundsException. | Test.java:59:17:59:42 | nextInt(...) | Random value | diff --git a/java/ql/test/query-tests/security/CWE-129/semmle/tests/ImproperValidationOfArrayIndexLocal.expected b/java/ql/test/query-tests/security/CWE-129/semmle/tests/ImproperValidationOfArrayIndexLocal.expected index dcd18ff8cbc..e23a7c4239e 100644 --- a/java/ql/test/query-tests/security/CWE-129/semmle/tests/ImproperValidationOfArrayIndexLocal.expected +++ b/java/ql/test/query-tests/security/CWE-129/semmle/tests/ImproperValidationOfArrayIndexLocal.expected @@ -1,7 +1,12 @@ edges -| Test.java:14:27:14:60 | getProperty(...) : String | Test.java:19:34:19:38 | index | +| Test.java:14:27:14:60 | getProperty(...) : String | Test.java:16:38:16:49 | userProperty : String | +| Test.java:16:38:16:49 | userProperty : String | Test.java:16:38:16:56 | trim(...) : String | +| Test.java:16:38:16:56 | trim(...) : String | Test.java:19:34:19:38 | index | nodes | Test.java:14:27:14:60 | getProperty(...) : String | semmle.label | getProperty(...) : String | +| Test.java:16:38:16:49 | userProperty : String | semmle.label | userProperty : String | +| Test.java:16:38:16:56 | trim(...) : String | semmle.label | trim(...) : String | | Test.java:19:34:19:38 | index | semmle.label | index | +subpaths #select | Test.java:19:34:19:38 | index | Test.java:14:27:14:60 | getProperty(...) : String | Test.java:19:34:19:38 | index | $@ flows to here and is used as an index causing an ArrayIndexOutOfBoundsException. | Test.java:14:27:14:60 | getProperty(...) | User-provided value | diff --git a/java/ql/test/query-tests/security/CWE-134/semmle/tests/ExternallyControlledFormatString.expected b/java/ql/test/query-tests/security/CWE-134/semmle/tests/ExternallyControlledFormatString.expected index 6c7afc63831..3bfd4609e98 100644 --- a/java/ql/test/query-tests/security/CWE-134/semmle/tests/ExternallyControlledFormatString.expected +++ b/java/ql/test/query-tests/security/CWE-134/semmle/tests/ExternallyControlledFormatString.expected @@ -7,5 +7,6 @@ nodes | Test.java:34:20:34:32 | userParameter : String | semmle.label | userParameter : String | | Test.java:37:31:37:43 | format : String | semmle.label | format : String | | Test.java:39:25:39:30 | format | semmle.label | format | +subpaths #select | Test.java:39:25:39:30 | format | Test.java:33:30:33:74 | getParameter(...) : String | Test.java:39:25:39:30 | format | $@ flows to here and is used in a format string. | Test.java:33:30:33:74 | getParameter(...) | User-provided value | diff --git a/java/ql/test/query-tests/security/CWE-134/semmle/tests/ExternallyControlledFormatStringLocal.expected b/java/ql/test/query-tests/security/CWE-134/semmle/tests/ExternallyControlledFormatStringLocal.expected index 4d3ea1db5bc..b5426ced220 100644 --- a/java/ql/test/query-tests/security/CWE-134/semmle/tests/ExternallyControlledFormatStringLocal.expected +++ b/java/ql/test/query-tests/security/CWE-134/semmle/tests/ExternallyControlledFormatStringLocal.expected @@ -11,6 +11,7 @@ nodes | Test.java:23:23:23:34 | userProperty | semmle.label | userProperty | | Test.java:25:28:25:39 | userProperty | semmle.label | userProperty | | Test.java:27:44:27:55 | userProperty | semmle.label | userProperty | +subpaths #select | Test.java:19:19:19:30 | userProperty | Test.java:17:27:17:60 | getProperty(...) : String | Test.java:19:19:19:30 | userProperty | $@ flows to here and is used in a format string. | Test.java:17:27:17:60 | getProperty(...) | User-provided value | | Test.java:21:23:21:34 | userProperty | Test.java:17:27:17:60 | getProperty(...) : String | Test.java:21:23:21:34 | userProperty | $@ flows to here and is used in a format string. | Test.java:17:27:17:60 | getProperty(...) | User-provided value | diff --git a/java/ql/test/query-tests/security/CWE-190/semmle/tests/ArithmeticTaintedLocal.expected b/java/ql/test/query-tests/security/CWE-190/semmle/tests/ArithmeticTaintedLocal.expected index 637b605a06f..e2b12ae730e 100644 --- a/java/ql/test/query-tests/security/CWE-190/semmle/tests/ArithmeticTaintedLocal.expected +++ b/java/ql/test/query-tests/security/CWE-190/semmle/tests/ArithmeticTaintedLocal.expected @@ -9,18 +9,24 @@ edges | ArithmeticTainted.java:18:40:18:56 | readerInputStream : InputStreamReader | ArithmeticTainted.java:18:21:18:57 | new BufferedReader(...) : BufferedReader | | ArithmeticTainted.java:19:26:19:39 | readerBuffered : BufferedReader | ArithmeticTainted.java:19:26:19:50 | readLine(...) : String | | ArithmeticTainted.java:19:26:19:39 | readerBuffered : BufferedReader | ArithmeticTainted.java:19:26:19:50 | readLine(...) : String | -| ArithmeticTainted.java:19:26:19:50 | readLine(...) : String | ArithmeticTainted.java:32:17:32:20 | data | -| ArithmeticTainted.java:19:26:19:50 | readLine(...) : String | ArithmeticTainted.java:40:17:40:20 | data | -| ArithmeticTainted.java:19:26:19:50 | readLine(...) : String | ArithmeticTainted.java:50:17:50:20 | data | -| ArithmeticTainted.java:19:26:19:50 | readLine(...) : String | ArithmeticTainted.java:64:20:64:23 | data : Number | -| ArithmeticTainted.java:19:26:19:50 | readLine(...) : String | ArithmeticTainted.java:95:37:95:40 | data | -| ArithmeticTainted.java:19:26:19:50 | readLine(...) : String | ArithmeticTainted.java:118:9:118:12 | data : Number | -| ArithmeticTainted.java:19:26:19:50 | readLine(...) : String | ArithmeticTainted.java:119:10:119:13 | data : Number | -| ArithmeticTainted.java:19:26:19:50 | readLine(...) : String | ArithmeticTainted.java:120:10:120:13 | data : Number | -| ArithmeticTainted.java:19:26:19:50 | readLine(...) : String | ArithmeticTainted.java:121:10:121:13 | data : Number | +| ArithmeticTainted.java:19:26:19:50 | readLine(...) : String | ArithmeticTainted.java:21:29:21:40 | stringNumber : String | +| ArithmeticTainted.java:19:26:19:50 | readLine(...) : String | ArithmeticTainted.java:21:29:21:40 | stringNumber : String | +| ArithmeticTainted.java:21:29:21:40 | stringNumber : String | ArithmeticTainted.java:21:29:21:47 | trim(...) : String | +| ArithmeticTainted.java:21:29:21:40 | stringNumber : String | ArithmeticTainted.java:21:29:21:47 | trim(...) : String | +| ArithmeticTainted.java:21:29:21:47 | trim(...) : String | ArithmeticTainted.java:32:17:32:20 | data | +| ArithmeticTainted.java:21:29:21:47 | trim(...) : String | ArithmeticTainted.java:40:17:40:20 | data | +| ArithmeticTainted.java:21:29:21:47 | trim(...) : String | ArithmeticTainted.java:50:17:50:20 | data | +| ArithmeticTainted.java:21:29:21:47 | trim(...) : String | ArithmeticTainted.java:64:20:64:23 | data : Number | +| ArithmeticTainted.java:21:29:21:47 | trim(...) : String | ArithmeticTainted.java:95:37:95:40 | data | +| ArithmeticTainted.java:21:29:21:47 | trim(...) : String | ArithmeticTainted.java:118:9:118:12 | data : Number | +| ArithmeticTainted.java:21:29:21:47 | trim(...) : String | ArithmeticTainted.java:119:10:119:13 | data : Number | +| ArithmeticTainted.java:21:29:21:47 | trim(...) : String | ArithmeticTainted.java:120:10:120:13 | data : Number | +| ArithmeticTainted.java:21:29:21:47 | trim(...) : String | ArithmeticTainted.java:121:10:121:13 | data : Number | | ArithmeticTainted.java:64:4:64:10 | tainted [post update] [dat] : Number | ArithmeticTainted.java:66:18:66:24 | tainted [dat] : Number | | ArithmeticTainted.java:64:20:64:23 | data : Number | ArithmeticTainted.java:64:4:64:10 | tainted [post update] [dat] : Number | +| ArithmeticTainted.java:64:20:64:23 | data : Number | Holder.java:12:22:12:26 | d : Number | | ArithmeticTainted.java:66:18:66:24 | tainted [dat] : Number | ArithmeticTainted.java:66:18:66:34 | getData(...) : Number | +| ArithmeticTainted.java:66:18:66:24 | tainted [dat] : Number | Holder.java:16:13:16:19 | parameter this [dat] : Number | | ArithmeticTainted.java:66:18:66:34 | getData(...) : Number | ArithmeticTainted.java:71:17:71:23 | herring | | ArithmeticTainted.java:118:9:118:12 | data : Number | ArithmeticTainted.java:125:26:125:33 | data : Number | | ArithmeticTainted.java:119:10:119:13 | data : Number | ArithmeticTainted.java:129:27:129:34 | data : Number | @@ -30,6 +36,10 @@ edges | ArithmeticTainted.java:129:27:129:34 | data : Number | ArithmeticTainted.java:131:5:131:8 | data | | ArithmeticTainted.java:133:27:133:34 | data : Number | ArithmeticTainted.java:135:3:135:6 | data | | ArithmeticTainted.java:137:27:137:34 | data : Number | ArithmeticTainted.java:139:5:139:8 | data | +| Holder.java:12:22:12:26 | d : Number | Holder.java:13:9:13:9 | d : Number | +| Holder.java:13:9:13:9 | d : Number | Holder.java:13:3:13:5 | this <.field> [post update] [dat] : Number | +| Holder.java:16:13:16:19 | parameter this [dat] : Number | Holder.java:17:10:17:12 | this <.field> [dat] : Number | +| Holder.java:17:10:17:12 | this <.field> [dat] : Number | Holder.java:17:10:17:12 | dat : Number | nodes | ArithmeticTainted.java:17:24:17:64 | new InputStreamReader(...) : InputStreamReader | semmle.label | new InputStreamReader(...) : InputStreamReader | | ArithmeticTainted.java:17:24:17:64 | new InputStreamReader(...) : InputStreamReader | semmle.label | new InputStreamReader(...) : InputStreamReader | @@ -43,6 +53,10 @@ nodes | ArithmeticTainted.java:19:26:19:39 | readerBuffered : BufferedReader | semmle.label | readerBuffered : BufferedReader | | ArithmeticTainted.java:19:26:19:50 | readLine(...) : String | semmle.label | readLine(...) : String | | ArithmeticTainted.java:19:26:19:50 | readLine(...) : String | semmle.label | readLine(...) : String | +| ArithmeticTainted.java:21:29:21:40 | stringNumber : String | semmle.label | stringNumber : String | +| ArithmeticTainted.java:21:29:21:40 | stringNumber : String | semmle.label | stringNumber : String | +| ArithmeticTainted.java:21:29:21:47 | trim(...) : String | semmle.label | trim(...) : String | +| ArithmeticTainted.java:21:29:21:47 | trim(...) : String | semmle.label | trim(...) : String | | ArithmeticTainted.java:32:17:32:20 | data | semmle.label | data | | ArithmeticTainted.java:40:17:40:20 | data | semmle.label | data | | ArithmeticTainted.java:50:17:50:20 | data | semmle.label | data | @@ -64,6 +78,15 @@ nodes | ArithmeticTainted.java:135:3:135:6 | data | semmle.label | data | | ArithmeticTainted.java:137:27:137:34 | data : Number | semmle.label | data : Number | | ArithmeticTainted.java:139:5:139:8 | data | semmle.label | data | +| Holder.java:12:22:12:26 | d : Number | semmle.label | d : Number | +| Holder.java:13:3:13:5 | this <.field> [post update] [dat] : Number | semmle.label | this <.field> [post update] [dat] : Number | +| Holder.java:13:9:13:9 | d : Number | semmle.label | d : Number | +| Holder.java:16:13:16:19 | parameter this [dat] : Number | semmle.label | parameter this [dat] : Number | +| Holder.java:17:10:17:12 | dat : Number | semmle.label | dat : Number | +| Holder.java:17:10:17:12 | this <.field> [dat] : Number | semmle.label | this <.field> [dat] : Number | +subpaths +| ArithmeticTainted.java:64:20:64:23 | data : Number | Holder.java:12:22:12:26 | d : Number | Holder.java:13:3:13:5 | this <.field> [post update] [dat] : Number | ArithmeticTainted.java:64:4:64:10 | tainted [post update] [dat] : Number | +| ArithmeticTainted.java:66:18:66:24 | tainted [dat] : Number | Holder.java:16:13:16:19 | parameter this [dat] : Number | Holder.java:17:10:17:12 | dat : Number | ArithmeticTainted.java:66:18:66:34 | getData(...) : Number | #select | ArithmeticTainted.java:32:17:32:25 | ... + ... | ArithmeticTainted.java:17:46:17:54 | System.in : InputStream | ArithmeticTainted.java:32:17:32:20 | data | $@ flows to here and is used in arithmetic, potentially causing an overflow. | ArithmeticTainted.java:17:46:17:54 | System.in | User-provided value | | ArithmeticTainted.java:40:17:40:25 | ... - ... | ArithmeticTainted.java:17:46:17:54 | System.in : InputStream | ArithmeticTainted.java:40:17:40:20 | data | $@ flows to here and is used in arithmetic, potentially causing an underflow. | ArithmeticTainted.java:17:46:17:54 | System.in | User-provided value | diff --git a/java/ql/test/query-tests/security/CWE-190/semmle/tests/ArithmeticUncontrolled.expected b/java/ql/test/query-tests/security/CWE-190/semmle/tests/ArithmeticUncontrolled.expected index e0f4cdff7b9..07f29d1e2f9 100644 --- a/java/ql/test/query-tests/security/CWE-190/semmle/tests/ArithmeticUncontrolled.expected +++ b/java/ql/test/query-tests/security/CWE-190/semmle/tests/ArithmeticUncontrolled.expected @@ -10,6 +10,7 @@ nodes | Test.java:245:15:245:35 | nextInt(...) : Number | semmle.label | nextInt(...) : Number | | Test.java:249:17:249:21 | data2 | semmle.label | data2 | | Test.java:280:37:280:41 | data2 | semmle.label | data2 | +subpaths #select | Test.java:210:17:210:24 | ... + ... | Test.java:206:14:206:57 | nextInt(...) : Number | Test.java:210:17:210:20 | data | $@ flows to here and is used in arithmetic, potentially causing an overflow. | Test.java:206:14:206:57 | nextInt(...) | Uncontrolled value | | Test.java:241:37:241:46 | ... + ... | Test.java:206:14:206:57 | nextInt(...) : Number | Test.java:241:37:241:40 | data | $@ flows to here and is used in arithmetic, potentially causing an overflow. | Test.java:206:14:206:57 | nextInt(...) | Uncontrolled value | diff --git a/java/ql/test/query-tests/security/CWE-190/semmle/tests/ArithmeticWithExtremeValues.expected b/java/ql/test/query-tests/security/CWE-190/semmle/tests/ArithmeticWithExtremeValues.expected index 5083958b51f..574dc3392a0 100644 --- a/java/ql/test/query-tests/security/CWE-190/semmle/tests/ArithmeticWithExtremeValues.expected +++ b/java/ql/test/query-tests/security/CWE-190/semmle/tests/ArithmeticWithExtremeValues.expected @@ -21,6 +21,7 @@ nodes | Test.java:195:41:195:41 | s | semmle.label | s | | Test.java:199:12:199:28 | Integer.MAX_VALUE : Number | semmle.label | Integer.MAX_VALUE : Number | | Test.java:202:37:202:37 | i | semmle.label | i | +subpaths #select | Test.java:96:8:96:12 | ... + ... | Test.java:93:8:93:24 | Integer.MAX_VALUE : Number | Test.java:96:8:96:8 | i | Variable i is assigned an extreme value $@, and may cause an overflow. | Test.java:93:8:93:24 | Integer.MAX_VALUE | MAX_VALUE | | Test.java:111:13:111:17 | ... - ... | Test.java:109:13:109:26 | Long.MIN_VALUE : Number | Test.java:111:13:111:13 | i | Variable i is assigned an extreme value $@, and may cause an underflow. | Test.java:109:13:109:26 | Long.MIN_VALUE | MIN_VALUE | diff --git a/java/ql/test/query-tests/security/CWE-297/InsecureJakartaMailTest.java b/java/ql/test/query-tests/security/CWE-297/InsecureJakartaMailTest.java new file mode 100644 index 00000000000..2dd5cab08ec --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-297/InsecureJakartaMailTest.java @@ -0,0 +1,42 @@ +import java.util.Properties; + +import jakarta.mail.Authenticator; +import jakarta.mail.PasswordAuthentication; +import jakarta.mail.Session; + +class InsecureJakartaMailTest { + public void testJavaMail() { + final Properties properties = new Properties(); + properties.put("mail.transport.protocol", "protocol"); + properties.put("mail.smtp.host", "hostname"); + properties.put("mail.smtp.socketFactory.class", "classname"); + + final jakarta.mail.Authenticator authenticator = new jakarta.mail.Authenticator() { + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication("username", "password"); + } + }; + if (null != authenticator) { + properties.put("mail.smtp.auth", "true"); + } + final Session session = Session.getInstance(properties, authenticator); // $hasInsecureJavaMail + } + + public void testSecureJavaMail() { + final Properties properties = new Properties(); + properties.put("mail.transport.protocol", "protocol"); + properties.put("mail.smtp.host", "hostname"); + properties.put("mail.smtp.socketFactory.class", "classname"); + + final jakarta.mail.Authenticator authenticator = new jakarta.mail.Authenticator() { + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication("username", "password"); + } + }; + if (null != authenticator) { + properties.put("mail.smtp.auth", "true"); + properties.put("mail.smtp.ssl.checkserveridentity", "true"); + } + final Session session = Session.getInstance(properties, authenticator); // Safe + } +} diff --git a/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.expected b/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.java b/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.java new file mode 100644 index 00000000000..a9880c20339 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.java @@ -0,0 +1,44 @@ +import java.util.Properties; + +import javax.mail.Authenticator; +import javax.mail.PasswordAuthentication; +import javax.mail.Session; + +class InsecureJavaMailTest { + public void testJavaMail() { + final Properties properties = new Properties(); + properties.put("mail.transport.protocol", "protocol"); + properties.put("mail.smtp.host", "hostname"); + properties.put("mail.smtp.socketFactory.class", "classname"); + + final javax.mail.Authenticator authenticator = new javax.mail.Authenticator() { + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication("username", "password"); + } + }; + if (null != authenticator) { + properties.put("mail.smtp.auth", "true"); + } + final Session session = Session.getInstance(properties, authenticator); // $hasInsecureJavaMail + } + + public void testSecureJavaMail() { + final Properties properties = new Properties(); + properties.put("mail.transport.protocol", "protocol"); + properties.put("mail.smtp.host", "hostname"); + properties.put("mail.smtp.socketFactory.class", "classname"); + + final javax.mail.Authenticator authenticator = new javax.mail.Authenticator() { + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication("username", "password"); + } + }; + if (null != authenticator) { + properties.put("mail.smtp.auth", "true"); + properties.put("mail.smtp.ssl.checkserveridentity", "true"); + } + final Session session = Session.getInstance(properties, authenticator); // Safe + } + + +} diff --git a/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.ql b/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.ql new file mode 100644 index 00000000000..137dde369f9 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-297/InsecureJavaMailTest.ql @@ -0,0 +1,24 @@ +import java +import semmle.code.java.security.Mail +import TestUtilities.InlineExpectationsTest + +class InsecureJavaMailTest extends InlineExpectationsTest { + InsecureJavaMailTest() { this = "HasInsecureJavaMailTest" } + + override string getARelevantTag() { result = "hasInsecureJavaMail" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasInsecureJavaMail" and + exists(MethodAccess ma | + ma.getLocation() = location and + element = ma.toString() and + value = "" + | + ma.getMethod() instanceof MailSessionGetInstanceMethod and + isInsecureMailPropertyConfig(ma.getArgument(0).(VarAccess).getVariable()) + or + enablesEmailSsl(ma) and + not hasSslCertificateCheck(ma.getQualifier().(VarAccess).getVariable()) + ) + } +} diff --git a/java/ql/test/query-tests/security/CWE-297/InsecureSimpleEmailTest.java b/java/ql/test/query-tests/security/CWE-297/InsecureSimpleEmailTest.java new file mode 100644 index 00000000000..5940dbbd457 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-297/InsecureSimpleEmailTest.java @@ -0,0 +1,62 @@ +import org.apache.commons.mail.DefaultAuthenticator; +import org.apache.commons.mail.Email; +import org.apache.commons.mail.SimpleEmail; + +public class InsecureSimpleEmailTest { + public void test() throws Exception { + // with setSSLOnConnect + { + Email email = new SimpleEmail(); + email.setHostName("config.hostName"); + email.setSmtpPort(25); + email.setAuthenticator(new DefaultAuthenticator("config.username", "config.password")); + email.setSSLOnConnect(true); // $hasInsecureJavaMail + email.setFrom("fromAddress"); + email.setSubject("subject"); + email.setMsg("body"); + email.addTo("toAddress"); + email.send(); + } + // with setStartTLSRequired + { + Email email = new SimpleEmail(); + email.setHostName("config.hostName"); + email.setSmtpPort(25); + email.setAuthenticator(new DefaultAuthenticator("config.username", "config.password")); + email.setStartTLSRequired(true); // $hasInsecureJavaMail + email.setFrom("fromAddress"); + email.setSubject("subject"); + email.setMsg("body"); + email.addTo("toAddress"); + email.send(); + } + // safe with setSSLOnConnect + { + Email email = new SimpleEmail(); + email.setHostName("config.hostName"); + email.setSmtpPort(25); + email.setAuthenticator(new DefaultAuthenticator("config.username", "config.password")); + email.setSSLOnConnect(true); // Safe + email.setSSLCheckServerIdentity(true); + email.setFrom("fromAddress"); + email.setSubject("subject"); + email.setMsg("body"); + email.addTo("toAddress"); + email.send(); + } + // safe with setStartTLSRequired + { + Email email = new SimpleEmail(); + email.setHostName("config.hostName"); + email.setSmtpPort(25); + email.setAuthenticator(new DefaultAuthenticator("config.username", "config.password")); + email.setStartTLSRequired(true); // Safe + email.setSSLCheckServerIdentity(true); + email.setFrom("fromAddress"); + email.setSubject("subject"); + email.setMsg("body"); + email.addTo("toAddress"); + email.send(); + } + } +} diff --git a/java/ql/test/query-tests/security/CWE-297/UnsafeHostnameVerification.expected b/java/ql/test/query-tests/security/CWE-297/UnsafeHostnameVerification.expected index acb9f1eabe0..405b02b4877 100644 --- a/java/ql/test/query-tests/security/CWE-297/UnsafeHostnameVerification.expected +++ b/java/ql/test/query-tests/security/CWE-297/UnsafeHostnameVerification.expected @@ -13,6 +13,7 @@ nodes | UnsafeHostnameVerification.java:88:37:93:9 | new (...) : new HostnameVerifier(...) { ... } | semmle.label | new (...) : new HostnameVerifier(...) { ... } | | UnsafeHostnameVerification.java:94:55:94:62 | verifier | semmle.label | verifier | | UnsafeHostnameVerification.java:97:72:102:5 | new (...) : new HostnameVerifier(...) { ... } | semmle.label | new (...) : new HostnameVerifier(...) { ... } | +subpaths #select | UnsafeHostnameVerification.java:14:55:19:9 | new (...) | UnsafeHostnameVerification.java:14:55:19:9 | new (...) | UnsafeHostnameVerification.java:14:55:19:9 | new (...) | $@ that is defined $@ and accepts any certificate as valid, is used here. | UnsafeHostnameVerification.java:14:55:19:9 | new (...) | This hostname verifier | UnsafeHostnameVerification.java:14:59:14:74 | new HostnameVerifier(...) { ... } | here | | UnsafeHostnameVerification.java:26:55:26:71 | ...->... | UnsafeHostnameVerification.java:26:55:26:71 | ...->... | UnsafeHostnameVerification.java:26:55:26:71 | ...->... | $@ that is defined $@ and accepts any certificate as valid, is used here. | UnsafeHostnameVerification.java:26:55:26:71 | ...->... | This hostname verifier | UnsafeHostnameVerification.java:26:55:26:71 | new HostnameVerifier(...) { ... } | here | diff --git a/java/ql/test/query-tests/security/CWE-297/options b/java/ql/test/query-tests/security/CWE-297/options new file mode 100644 index 00000000000..6fcd80260e3 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-297/options @@ -0,0 +1 @@ +// semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/apache-commons-email-1.6.0:${testdir}/../../../stubs/javamail-api-1.6.2:${testdir}/../../../stubs/jakarta-mail-2.0.1 diff --git a/java/ql/test/query-tests/security/CWE-311/CWE-319/HttpsUrls.expected b/java/ql/test/query-tests/security/CWE-311/CWE-319/HttpsUrls.expected index e4bae134108..af4bc51c793 100644 --- a/java/ql/test/query-tests/security/CWE-311/CWE-319/HttpsUrls.expected +++ b/java/ql/test/query-tests/security/CWE-311/CWE-319/HttpsUrls.expected @@ -17,6 +17,7 @@ nodes | HttpsUrlsTest.java:55:50:55:50 | u | semmle.label | u | | HttpsUrlsTest.java:87:23:87:28 | "http" : String | semmle.label | "http" : String | | HttpsUrlsTest.java:92:50:92:50 | u | semmle.label | u | +subpaths #select | HttpsUrlsTest.java:28:50:28:67 | openConnection(...) | HttpsUrlsTest.java:23:23:23:31 | "http://" : String | HttpsUrlsTest.java:28:50:28:50 | u | URL may have been constructed with HTTP protocol, using $@. | HttpsUrlsTest.java:23:23:23:31 | "http://" | this source | | HttpsUrlsTest.java:41:50:41:67 | openConnection(...) | HttpsUrlsTest.java:36:23:36:28 | "http" : String | HttpsUrlsTest.java:41:50:41:50 | u | URL may have been constructed with HTTP protocol, using $@. | HttpsUrlsTest.java:36:23:36:28 | "http" | this source | diff --git a/java/ql/test/query-tests/security/CWE-327/semmle/tests/BrokenCryptoAlgorithm.expected b/java/ql/test/query-tests/security/CWE-327/semmle/tests/BrokenCryptoAlgorithm.expected index b8af298b907..19ab13ed803 100644 --- a/java/ql/test/query-tests/security/CWE-327/semmle/tests/BrokenCryptoAlgorithm.expected +++ b/java/ql/test/query-tests/security/CWE-327/semmle/tests/BrokenCryptoAlgorithm.expected @@ -2,6 +2,7 @@ edges nodes | Test.java:19:45:19:49 | "DES" | semmle.label | "DES" | | Test.java:42:33:42:37 | "RC2" | semmle.label | "RC2" | +subpaths #select -| Test.java:19:20:19:50 | getInstance(...) | Test.java:19:45:19:49 | "DES" | Test.java:19:45:19:49 | "DES" | Cryptographic algorithm $@ is weak and should not be used. | Test.java:19:45:19:49 | "DES" | "DES" | -| Test.java:42:14:42:38 | getInstance(...) | Test.java:42:33:42:37 | "RC2" | Test.java:42:33:42:37 | "RC2" | Cryptographic algorithm $@ is weak and should not be used. | Test.java:42:33:42:37 | "RC2" | "RC2" | +| Test.java:19:20:19:50 | getInstance(...) | Test.java:19:45:19:49 | "DES" | Test.java:19:45:19:49 | "DES" | Cryptographic algorithm $@ is weak and should not be used. | Test.java:19:45:19:49 | "DES" | DES | +| Test.java:42:14:42:38 | getInstance(...) | Test.java:42:33:42:37 | "RC2" | Test.java:42:33:42:37 | "RC2" | Cryptographic algorithm $@ is weak and should not be used. | Test.java:42:33:42:37 | "RC2" | RC2 | diff --git a/java/ql/test/query-tests/security/CWE-327/semmle/tests/MaybeBrokenCryptoAlgorithm.expected b/java/ql/test/query-tests/security/CWE-327/semmle/tests/MaybeBrokenCryptoAlgorithm.expected index 946aa5c8d4c..f61954d848a 100644 --- a/java/ql/test/query-tests/security/CWE-327/semmle/tests/MaybeBrokenCryptoAlgorithm.expected +++ b/java/ql/test/query-tests/security/CWE-327/semmle/tests/MaybeBrokenCryptoAlgorithm.expected @@ -1,5 +1,6 @@ edges nodes | Test.java:34:48:34:52 | "foo" | semmle.label | "foo" | +subpaths #select -| Test.java:34:21:34:53 | new SecretKeySpec(...) | Test.java:34:48:34:52 | "foo" | Test.java:34:48:34:52 | "foo" | Cryptographic algorithm $@ may not be secure, consider using a different algorithm. | Test.java:34:48:34:52 | "foo" | "foo" | +| Test.java:34:21:34:53 | new SecretKeySpec(...) | Test.java:34:48:34:52 | "foo" | Test.java:34:48:34:52 | "foo" | Cryptographic algorithm $@ may not be secure, consider using a different algorithm. | Test.java:34:48:34:52 | "foo" | foo | diff --git a/java/ql/test/query-tests/security/CWE-502/FlexjsonServlet.java b/java/ql/test/query-tests/security/CWE-502/FlexjsonServlet.java new file mode 100644 index 00000000000..c7e5c1ce587 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-502/FlexjsonServlet.java @@ -0,0 +1,126 @@ +import java.io.IOException; +import java.io.Reader; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import flexjson.JSONDeserializer; +import flexjson.factories.ExistingObjectFactory; + +import com.example.User; +import com.thirdparty.Person; + +public class FlexjsonServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + // GOOD: a final class type is specified + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + JSONDeserializer deserializer = new JSONDeserializer<>(); + User user = deserializer.deserialize(req.getReader(), User.class); + } + + @Override + // GOOD: a non-null class type is specified which is not the generic `Object` type + public void doHead(HttpServletRequest req, HttpServletResponse resp) throws IOException { + JSONDeserializer deserializer = new JSONDeserializer(); + Person person = deserializer.deserialize(req.getReader(), Person.class); + } + + @Override + // BAD: allow class name to be controlled by remote source + public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { + JSONDeserializer deserializer = new JSONDeserializer<>(); + User user = (User) deserializer.deserialize(req.getReader()); // $unsafeDeserialization + + } + + @Override + // BAD: allow class name to be controlled by remote source + public void doTrace(HttpServletRequest req, HttpServletResponse resp) throws IOException { + JSONDeserializer deserializer = new JSONDeserializer<>(); + User user = (User) deserializer.deserialize(req.getReader()); // $unsafeDeserialization + + } + + @Override + // BAD: specify overly generic class type + public void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException { + JSONDeserializer deserializer = new JSONDeserializer(); + User user = (User) deserializer.deserialize(req.getReader(), Object.class); // $unsafeDeserialization + } + + private Person fromJsonToPerson(String json) { + return new JSONDeserializer().use(null, Person.class).deserialize(json); + } + + // GOOD: Specify the class to deserialize with `use` + public void doPut2(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String json = req.getParameter("json"); + Person person = fromJsonToPerson(json); + } + + // BAD: Specify a concrete class type to `use` with `ObjectFactory` + public void doPut3(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String json = req.getParameter("json"); + Person person = new JSONDeserializer().use(Person.class, new ExistingObjectFactory(new Person())).deserialize(json); // $unsafeDeserialization + } + + // GOOD: Specify a null path to `use` with a concrete class type + public void doPut4(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String json = req.getParameter("json"); + Person person = new JSONDeserializer().use(null, Person.class).deserialize(json); + } + + // BAD: Specify a non-null json path to `use` with a concrete class type + public void doPut5(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String json = req.getParameter("json"); + Person person = new JSONDeserializer().use("abc", Person.class).deserialize(json); // $unsafeDeserialization + } + + // GOOD: Specify a null json path to `use` with `ObjectFactory` + public void doPut6(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String json = req.getParameter("json"); + Person person = new JSONDeserializer().use(new ExistingObjectFactory(new Person()), "abc", null).deserialize(json); + } + + // GOOD: Specify a concrete class type to deserialize with `ObjectFactory` + public void doPut7(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String json = req.getParameter("json"); + Person person = new JSONDeserializer().deserialize(json, new ExistingObjectFactory(new Person())); + } + + // GOOD: Specify the class type to deserialize into + public void doPut8(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String json = req.getParameter("json"); + Person person = new JSONDeserializer().deserializeInto(json, new Person()); + } + + // GOOD: Specify a null json path to `use` with a concrete class type, interwoven with irrelevant use directives + public void doPut9(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String json = req.getParameter("json"); + Person person = new JSONDeserializer().use(Person.class, null).use(null, Person.class).use(String.class, null).deserialize(json); + } + + // GOOD: Specify a null json path to `use` with a concrete class type, interwoven with irrelevant use directives, without using fluent method chaining + public void doPut10(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String json = req.getParameter("json"); + JSONDeserializer deserializer = new JSONDeserializer(); + deserializer.use(Person.class, null); + deserializer.use(null, Person.class); + deserializer.use(String.class, null); + Person person = deserializer.deserialize(json); + } + + // BAD: Specify a non-null json path to `use` with a concrete class type, interwoven with irrelevant use directives, without using fluent method chaining + public void doPut11(HttpServletRequest req, HttpServletResponse resp) throws IOException { + String json = req.getParameter("json"); + JSONDeserializer deserializer = new JSONDeserializer(); + deserializer.use(Person.class, null); + deserializer.use("someKey", Person.class); + deserializer.use(String.class, null); + Person person = deserializer.deserialize(json); // $unsafeDeserialization + } +} diff --git a/java/ql/test/query-tests/security/CWE-502/options b/java/ql/test/query-tests/security/CWE-502/options index 79476eded38..cdd0375684e 100644 --- a/java/ql/test/query-tests/security/CWE-502/options +++ b/java/ql/test/query-tests/security/CWE-502/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/snakeyaml-1.21:${testdir}/../../../stubs/xstream-1.4.10:${testdir}/../../../stubs/kryo-4.0.2:${testdir}/../../../stubs/jsr311-api-1.1.1:${testdir}/../../../stubs/fastjson-1.2.74:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/jyaml-1.3:${testdir}/../../../stubs/json-io-4.10.0:${testdir}/../../../stubs/yamlbeans-1.09:${testdir}/../../../stubs/hessian-4.0.38:${testdir}/../../../stubs/castor-1.4.1:${testdir}/../../../stubs/jackson-databind-2.12:${testdir}/../../../stubs/jackson-core-2.12:${testdir}/../../../stubs/jabsorb-1.3.2:${testdir}/../../../stubs/json-java-20210307:${testdir}/../../../stubs/joddjson-6.0.3 +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/snakeyaml-1.21:${testdir}/../../../stubs/xstream-1.4.10:${testdir}/../../../stubs/kryo-4.0.2:${testdir}/../../../stubs/jsr311-api-1.1.1:${testdir}/../../../stubs/fastjson-1.2.74:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/jyaml-1.3:${testdir}/../../../stubs/json-io-4.10.0:${testdir}/../../../stubs/yamlbeans-1.09:${testdir}/../../../stubs/hessian-4.0.38:${testdir}/../../../stubs/castor-1.4.1:${testdir}/../../../stubs/jackson-databind-2.12:${testdir}/../../../stubs/jackson-core-2.12:${testdir}/../../../stubs/jabsorb-1.3.2:${testdir}/../../../stubs/json-java-20210307:${testdir}/../../../stubs/joddjson-6.0.3:${testdir}/../../../stubs/flexjson-2.1 diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.expected b/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.java b/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.java new file mode 100644 index 00000000000..2098dd4139c --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.java @@ -0,0 +1,253 @@ +import org.apache.http.RequestLine; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.message.BasicHttpRequest; +import org.apache.http.message.BasicRequestLine; + +import java.net.URI; +import java.net.URL; +import java.net.HttpURLConnection; +import java.net.URLConnection; +import java.util.Base64; +import javax.net.ssl.HttpsURLConnection; + +public class InsecureBasicAuthTest { + /** + * Test basic authentication with Apache HTTP POST request using string constructor. + */ + public void testApacheHttpRequest(String username, String password) { + String host = "www.example.com"; + String authString = username + ":" + password; + byte[] authEncBytes = Base64.getEncoder().encode(authString.getBytes()); + String authStringEnc = new String(authEncBytes); + { + HttpRequestBase post = new HttpPost("http://" + host + "/rest/getuser.do?uid=abcdx"); + post.setHeader("Accept", "application/json"); + post.setHeader("Content-type", "application/json"); + post.addHeader("Authorization", "Basic " + authStringEnc); // $hasInsecureBasicAuth + } + { + HttpRequestBase post = new HttpPost("https://" + host + "/rest/getuser.do?uid=abcdx"); + post.setHeader("Accept", "application/json"); + post.setHeader("Content-type", "application/json"); + post.addHeader("Authorization", "Basic " + authStringEnc); // Safe + } + } + + /** + * Test basic authentication with Apache HTTP GET request. + */ + public void testApacheHttpRequest2(String url) throws java.io.IOException { + { + String urlStr = "http://www.example.com:8000/payment/retrieve"; + HttpGet get = new HttpGet(urlStr); + get.setHeader("Accept", "application/json"); + get.setHeader("Authorization", // $hasInsecureBasicAuth + "Basic " + new String(Base64.getEncoder().encode("admin:test".getBytes()))); + } + { + String urlStr = "https://www.example.com:8000/payment/retrieve"; + HttpGet get = new HttpGet(urlStr); + get.setHeader("Accept", "application/json"); + get.setHeader("Authorization", // Safe + "Basic " + new String(Base64.getEncoder().encode("admin:test".getBytes()))); + } + } + + /** + * Test basic authentication with Apache HTTP POST request using URI create method. + */ + public void testApacheHttpRequest3(String username, String password) { + String authString = username + ":" + password; + byte[] authEncBytes = Base64.getEncoder().encode(authString.getBytes()); + String authStringEnc = new String(authEncBytes); + { + String uriStr = "http://www.example.com/rest/getuser.do?uid=abcdx"; + HttpRequestBase post = new HttpPost(URI.create(uriStr)); + post.setHeader("Accept", "application/json"); + post.setHeader("Content-type", "application/json"); + post.addHeader("Authorization", "Basic " + authStringEnc); // $hasInsecureBasicAuth + } + { + String uriStr = "https://www.example.com/rest/getuser.do?uid=abcdx"; + HttpRequestBase post = new HttpPost(URI.create(uriStr)); + post.setHeader("Accept", "application/json"); + post.setHeader("Content-type", "application/json"); + post.addHeader("Authorization", "Basic " + authStringEnc); // Safe + } + } + + /** + * Test basic authentication with Apache HTTP POST request using the URI constructor with one + * argument. + */ + public void testApacheHttpRequest4(String username, String password) throws Exception { + String authString = username + ":" + password; + byte[] authEncBytes = Base64.getEncoder().encode(authString.getBytes()); + String authStringEnc = new String(authEncBytes); + { + String uriStr = "http://www.example.com/rest/getuser.do?uid=abcdx"; + URI uri = new URI(uriStr); + HttpRequestBase post = new HttpPost(uri); + post.setHeader("Accept", "application/json"); + post.setHeader("Content-type", "application/json"); + post.addHeader("Authorization", "Basic " + authStringEnc); // $hasInsecureBasicAuth + } + { + String uriStr = "https://www.example.com/rest/getuser.do?uid=abcdx"; + URI uri = new URI(uriStr); + HttpRequestBase post = new HttpPost(uri); + post.setHeader("Accept", "application/json"); + post.setHeader("Content-type", "application/json"); + post.addHeader("Authorization", "Basic " + authStringEnc); // Safe + } + } + + /** + * Test basic authentication with Apache HTTP POST request using a URI constructor with multiple + * arguments. + */ + public void testApacheHttpRequest5(String username, String password) throws Exception { + String authString = username + ":" + password; + byte[] authEncBytes = Base64.getEncoder().encode(authString.getBytes()); + String authStringEnc = new String(authEncBytes); + { + HttpRequestBase post = + new HttpPost(new URI("http", "www.example.com", "/test", "abc=123", null)); + post.setHeader("Accept", "application/json"); + post.setHeader("Content-type", "application/json"); + post.addHeader("Authorization", "Basic " + authStringEnc); // $hasInsecureBasicAuth + } + { + HttpRequestBase post = + new HttpPost(new URI("https", "www.example.com", "/test", "abc=123", null)); + post.setHeader("Accept", "application/json"); + post.setHeader("Content-type", "application/json"); + post.addHeader("Authorization", "Basic " + authStringEnc); // Safe + } + } + + /** + * Test basic authentication with Apache HTTP `BasicHttpRequest` using string constructor. + */ + public void testApacheHttpRequest6(String username, String password) { + String authString = username + ":" + password; + byte[] authEncBytes = Base64.getEncoder().encode(authString.getBytes()); + String authStringEnc = new String(authEncBytes); + { + String uriStr = "http://www.example.com/rest/getuser.do?uid=abcdx"; + BasicHttpRequest post = new BasicHttpRequest("POST", uriStr); + post.setHeader("Accept", "application/json"); + post.setHeader("Content-type", "application/json"); + post.addHeader("Authorization", "Basic " + authStringEnc); // $hasInsecureBasicAuth + } + { + String uriStr = "https://www.example.com/rest/getuser.do?uid=abcdx"; + BasicHttpRequest post = new BasicHttpRequest("POST", uriStr); + post.setHeader("Accept", "application/json"); + post.setHeader("Content-type", "application/json"); + post.addHeader("Authorization", "Basic " + authStringEnc); // Safe + } + } + + /** + * Test basic authentication with Apache HTTP `BasicHttpRequest` using `RequestLine`. + */ + public void testApacheHttpRequest7(String username, String password) { + String authString = username + ":" + password; + byte[] authEncBytes = Base64.getEncoder().encode(authString.getBytes()); + String authStringEnc = new String(authEncBytes); + { + String uriStr = "http://www.example.com/rest/getuser.do?uid=abcdx"; + RequestLine requestLine = new BasicRequestLine("POST", uriStr, null); + BasicHttpRequest post = new BasicHttpRequest(requestLine); + post.setHeader("Accept", "application/json"); + post.setHeader("Content-type", "application/json"); + post.addHeader("Authorization", "Basic " + authStringEnc); // $hasInsecureBasicAuth + } + { + String uriStr = "https://www.example.com/rest/getuser.do?uid=abcdx"; + RequestLine requestLine = new BasicRequestLine("POST", uriStr, null); + BasicHttpRequest post = new BasicHttpRequest(requestLine); + post.setHeader("Accept", "application/json"); + post.setHeader("Content-type", "application/json"); + post.addHeader("Authorization", "Basic " + authStringEnc); // Safe + } + } + + /** + * Test basic authentication with Java HTTP URL connection using the `URL(String spec)` + * constructor. + */ + public void testHttpUrlConnection(String username, String password) throws Exception { + String authString = username + ":" + password; + String encoding = Base64.getEncoder().encodeToString(authString.getBytes("UTF-8")); + { + String urlStr = "http://www.example.com/rest/getuser.do?uid=abcdx"; + URL url = new URL(urlStr); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("POST"); + conn.setDoOutput(true); + conn.setRequestProperty("Authorization", "Basic " + encoding); // $hasInsecureBasicAuth + } + { + String urlStr = "https://www.example.com/rest/getuser.do?uid=abcdx"; + URL url = new URL(urlStr); + HttpURLConnection conn = (HttpsURLConnection) url.openConnection(); + conn.setRequestMethod("POST"); + conn.setDoOutput(true); + conn.setRequestProperty("Authorization", "Basic " + encoding); // Safe + } + } + + /** + * Test basic authentication with Java HTTP URL connection using the `URL(String protocol, + * String host, String file)` constructor. + */ + public void testHttpUrlConnection2(String username, String password) throws Exception { + String authString = username + ":" + password; + String encoding = Base64.getEncoder().encodeToString(authString.getBytes("UTF-8")); + String host = "www.example.com"; + String path = "/rest/getuser.do?uid=abcdx"; + { + String protocol = "http"; + URL url = new URL(protocol, host, path); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("POST"); + conn.setDoOutput(true); + conn.setRequestProperty("Authorization", "Basic " + encoding); // $hasInsecureBasicAuth + } + { + String protocol = "https"; + URL url = new URL(protocol, host, path); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("POST"); + conn.setDoOutput(true); + conn.setRequestProperty("Authorization", "Basic " + encoding); // Safe + } + } + + /** + * Test basic authentication with Java HTTP URL connection using a constructor with private URL. + */ + public void testHttpUrlConnection3(String username, String password) throws Exception { + String host = "LOCALHOST"; + String authString = username + ":" + password; + String encoding = Base64.getEncoder().encodeToString(authString.getBytes("UTF-8")); + { + HttpURLConnection conn = (HttpURLConnection) new URL( + "http://" + (((host + "/rest/getuser.do") + "?uid=abcdx"))).openConnection(); + conn.setRequestMethod("POST"); + conn.setDoOutput(true); + conn.setRequestProperty("Authorization", "Basic " + encoding); // Safe + } + { + HttpURLConnection conn = (HttpURLConnection) new URL( + "https://" + (((host + "/rest/getuser.do") + "?uid=abcdx"))).openConnection(); + conn.setRequestMethod("POST"); + conn.setDoOutput(true); + conn.setRequestProperty("Authorization", "Basic " + encoding); // Safe + } + } +} diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.ql b/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.ql new file mode 100644 index 00000000000..53064d42bd5 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-522/InsecureBasicAuthTest.ql @@ -0,0 +1,20 @@ +import java +import semmle.code.java.security.InsecureBasicAuthQuery +import TestUtilities.InlineExpectationsTest + +class HasInsecureBasicAuthTest extends InlineExpectationsTest { + HasInsecureBasicAuthTest() { this = "HasInsecureBasicAuthTest" } + + override string getARelevantTag() { result = "hasInsecureBasicAuth" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasInsecureBasicAuth" and + exists(DataFlow::Node src, DataFlow::Node sink, BasicAuthFlowConfig conf | + conf.hasFlow(src, sink) + | + sink.getLocation() = location and + element = sink.toString() and + value = "" + ) + } +} diff --git a/java/ql/test/experimental/query-tests/security/CWE-522/options b/java/ql/test/query-tests/security/CWE-522/options similarity index 68% rename from java/ql/test/experimental/query-tests/security/CWE-522/options rename to java/ql/test/query-tests/security/CWE-522/options index 7eaf4cb235f..2e6054aac45 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-522/options +++ b/java/ql/test/query-tests/security/CWE-522/options @@ -1 +1 @@ -// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/apache-http-4.4.13 +// semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/apache-http-4.4.13 diff --git a/java/ql/test/query-tests/security/CWE-601/semmle/tests/UrlRedirect.expected b/java/ql/test/query-tests/security/CWE-601/semmle/tests/UrlRedirect.expected index 21db09a43a8..0b64242ffa0 100644 --- a/java/ql/test/query-tests/security/CWE-601/semmle/tests/UrlRedirect.expected +++ b/java/ql/test/query-tests/security/CWE-601/semmle/tests/UrlRedirect.expected @@ -6,6 +6,7 @@ nodes | UrlRedirect.java:36:58:36:89 | getParameter(...) : String | semmle.label | getParameter(...) : String | | UrlRedirect.java:39:34:39:63 | getParameter(...) | semmle.label | getParameter(...) | | UrlRedirect.java:42:43:42:72 | getParameter(...) | semmle.label | getParameter(...) | +subpaths #select | UrlRedirect.java:23:25:23:54 | getParameter(...) | UrlRedirect.java:23:25:23:54 | getParameter(...) | UrlRedirect.java:23:25:23:54 | getParameter(...) | Potentially untrusted URL redirection due to $@. | UrlRedirect.java:23:25:23:54 | getParameter(...) | user-provided value | | UrlRedirect.java:36:25:36:89 | ... + ... | UrlRedirect.java:36:58:36:89 | getParameter(...) : String | UrlRedirect.java:36:25:36:89 | ... + ... | Potentially untrusted URL redirection due to $@. | UrlRedirect.java:36:58:36:89 | getParameter(...) | user-provided value | diff --git a/java/ql/test/query-tests/security/CWE-611/XXE.expected b/java/ql/test/query-tests/security/CWE-611/XXE.expected index e2fcffee125..017659e9a0b 100644 --- a/java/ql/test/query-tests/security/CWE-611/XXE.expected +++ b/java/ql/test/query-tests/security/CWE-611/XXE.expected @@ -18,29 +18,37 @@ edges | SchemaTests.java:45:56:45:76 | getInputStream(...) : InputStream | SchemaTests.java:45:39:45:77 | new StreamSource(...) | | SimpleXMLTests.java:24:63:24:83 | getInputStream(...) : InputStream | SimpleXMLTests.java:24:41:24:84 | new InputStreamReader(...) | | SimpleXMLTests.java:30:5:30:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:30:32:30:32 | b [post update] : byte[] | -| SimpleXMLTests.java:30:32:30:32 | b [post update] : byte[] | SimpleXMLTests.java:31:41:31:53 | new String(...) | +| SimpleXMLTests.java:30:32:30:32 | b [post update] : byte[] | SimpleXMLTests.java:31:52:31:52 | b : byte[] | +| SimpleXMLTests.java:31:52:31:52 | b : byte[] | SimpleXMLTests.java:31:41:31:53 | new String(...) | | SimpleXMLTests.java:37:5:37:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:37:32:37:32 | b [post update] : byte[] | -| SimpleXMLTests.java:37:32:37:32 | b [post update] : byte[] | SimpleXMLTests.java:38:41:38:53 | new String(...) | +| SimpleXMLTests.java:37:32:37:32 | b [post update] : byte[] | SimpleXMLTests.java:38:52:38:52 | b : byte[] | +| SimpleXMLTests.java:38:52:38:52 | b : byte[] | SimpleXMLTests.java:38:41:38:53 | new String(...) | | SimpleXMLTests.java:43:63:43:83 | getInputStream(...) : InputStream | SimpleXMLTests.java:43:41:43:84 | new InputStreamReader(...) | | SimpleXMLTests.java:68:59:68:79 | getInputStream(...) : InputStream | SimpleXMLTests.java:68:37:68:80 | new InputStreamReader(...) | | SimpleXMLTests.java:73:59:73:79 | getInputStream(...) : InputStream | SimpleXMLTests.java:73:37:73:80 | new InputStreamReader(...) | | SimpleXMLTests.java:78:48:78:68 | getInputStream(...) : InputStream | SimpleXMLTests.java:78:26:78:69 | new InputStreamReader(...) | | SimpleXMLTests.java:83:48:83:68 | getInputStream(...) : InputStream | SimpleXMLTests.java:83:26:83:69 | new InputStreamReader(...) | | SimpleXMLTests.java:89:5:89:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:89:32:89:32 | b [post update] : byte[] | -| SimpleXMLTests.java:89:32:89:32 | b [post update] : byte[] | SimpleXMLTests.java:90:37:90:49 | new String(...) | +| SimpleXMLTests.java:89:32:89:32 | b [post update] : byte[] | SimpleXMLTests.java:90:48:90:48 | b : byte[] | +| SimpleXMLTests.java:90:48:90:48 | b : byte[] | SimpleXMLTests.java:90:37:90:49 | new String(...) | | SimpleXMLTests.java:96:5:96:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:96:32:96:32 | b [post update] : byte[] | -| SimpleXMLTests.java:96:32:96:32 | b [post update] : byte[] | SimpleXMLTests.java:97:37:97:49 | new String(...) | +| SimpleXMLTests.java:96:32:96:32 | b [post update] : byte[] | SimpleXMLTests.java:97:48:97:48 | b : byte[] | +| SimpleXMLTests.java:97:48:97:48 | b : byte[] | SimpleXMLTests.java:97:37:97:49 | new String(...) | | SimpleXMLTests.java:103:5:103:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:103:32:103:32 | b [post update] : byte[] | -| SimpleXMLTests.java:103:32:103:32 | b [post update] : byte[] | SimpleXMLTests.java:104:26:104:38 | new String(...) | +| SimpleXMLTests.java:103:32:103:32 | b [post update] : byte[] | SimpleXMLTests.java:104:37:104:37 | b : byte[] | +| SimpleXMLTests.java:104:37:104:37 | b : byte[] | SimpleXMLTests.java:104:26:104:38 | new String(...) | | SimpleXMLTests.java:110:5:110:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:110:32:110:32 | b [post update] : byte[] | -| SimpleXMLTests.java:110:32:110:32 | b [post update] : byte[] | SimpleXMLTests.java:111:26:111:38 | new String(...) | +| SimpleXMLTests.java:110:32:110:32 | b [post update] : byte[] | SimpleXMLTests.java:111:37:111:37 | b : byte[] | +| SimpleXMLTests.java:111:37:111:37 | b : byte[] | SimpleXMLTests.java:111:26:111:38 | new String(...) | | SimpleXMLTests.java:119:44:119:64 | getInputStream(...) : InputStream | SimpleXMLTests.java:119:22:119:65 | new InputStreamReader(...) | | SimpleXMLTests.java:129:44:129:64 | getInputStream(...) : InputStream | SimpleXMLTests.java:129:22:129:65 | new InputStreamReader(...) | | SimpleXMLTests.java:139:44:139:64 | getInputStream(...) : InputStream | SimpleXMLTests.java:139:22:139:65 | new InputStreamReader(...) | | SimpleXMLTests.java:145:5:145:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:145:32:145:32 | b [post update] : byte[] | -| SimpleXMLTests.java:145:32:145:32 | b [post update] : byte[] | SimpleXMLTests.java:146:22:146:34 | new String(...) | +| SimpleXMLTests.java:145:32:145:32 | b [post update] : byte[] | SimpleXMLTests.java:146:33:146:33 | b : byte[] | +| SimpleXMLTests.java:146:33:146:33 | b : byte[] | SimpleXMLTests.java:146:22:146:34 | new String(...) | | SimpleXMLTests.java:152:5:152:25 | getInputStream(...) : InputStream | SimpleXMLTests.java:152:32:152:32 | b [post update] : byte[] | -| SimpleXMLTests.java:152:32:152:32 | b [post update] : byte[] | SimpleXMLTests.java:153:22:153:34 | new String(...) | +| SimpleXMLTests.java:152:32:152:32 | b [post update] : byte[] | SimpleXMLTests.java:153:33:153:33 | b : byte[] | +| SimpleXMLTests.java:153:33:153:33 | b : byte[] | SimpleXMLTests.java:153:22:153:34 | new String(...) | | TransformerTests.java:20:44:20:64 | getInputStream(...) : InputStream | TransformerTests.java:20:27:20:65 | new StreamSource(...) | | TransformerTests.java:21:40:21:60 | getInputStream(...) : InputStream | TransformerTests.java:21:23:21:61 | new StreamSource(...) | | TransformerTests.java:71:44:71:64 | getInputStream(...) : InputStream | TransformerTests.java:71:27:71:65 | new StreamSource(...) | @@ -123,9 +131,11 @@ nodes | SimpleXMLTests.java:30:5:30:25 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream | | SimpleXMLTests.java:30:32:30:32 | b [post update] : byte[] | semmle.label | b [post update] : byte[] | | SimpleXMLTests.java:31:41:31:53 | new String(...) | semmle.label | new String(...) | +| SimpleXMLTests.java:31:52:31:52 | b : byte[] | semmle.label | b : byte[] | | SimpleXMLTests.java:37:5:37:25 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream | | SimpleXMLTests.java:37:32:37:32 | b [post update] : byte[] | semmle.label | b [post update] : byte[] | | SimpleXMLTests.java:38:41:38:53 | new String(...) | semmle.label | new String(...) | +| SimpleXMLTests.java:38:52:38:52 | b : byte[] | semmle.label | b : byte[] | | SimpleXMLTests.java:43:41:43:84 | new InputStreamReader(...) | semmle.label | new InputStreamReader(...) | | SimpleXMLTests.java:43:63:43:83 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream | | SimpleXMLTests.java:48:37:48:57 | getInputStream(...) | semmle.label | getInputStream(...) | @@ -143,15 +153,19 @@ nodes | SimpleXMLTests.java:89:5:89:25 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream | | SimpleXMLTests.java:89:32:89:32 | b [post update] : byte[] | semmle.label | b [post update] : byte[] | | SimpleXMLTests.java:90:37:90:49 | new String(...) | semmle.label | new String(...) | +| SimpleXMLTests.java:90:48:90:48 | b : byte[] | semmle.label | b : byte[] | | SimpleXMLTests.java:96:5:96:25 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream | | SimpleXMLTests.java:96:32:96:32 | b [post update] : byte[] | semmle.label | b [post update] : byte[] | | SimpleXMLTests.java:97:37:97:49 | new String(...) | semmle.label | new String(...) | +| SimpleXMLTests.java:97:48:97:48 | b : byte[] | semmle.label | b : byte[] | | SimpleXMLTests.java:103:5:103:25 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream | | SimpleXMLTests.java:103:32:103:32 | b [post update] : byte[] | semmle.label | b [post update] : byte[] | | SimpleXMLTests.java:104:26:104:38 | new String(...) | semmle.label | new String(...) | +| SimpleXMLTests.java:104:37:104:37 | b : byte[] | semmle.label | b : byte[] | | SimpleXMLTests.java:110:5:110:25 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream | | SimpleXMLTests.java:110:32:110:32 | b [post update] : byte[] | semmle.label | b [post update] : byte[] | | SimpleXMLTests.java:111:26:111:38 | new String(...) | semmle.label | new String(...) | +| SimpleXMLTests.java:111:37:111:37 | b : byte[] | semmle.label | b : byte[] | | SimpleXMLTests.java:115:22:115:42 | getInputStream(...) | semmle.label | getInputStream(...) | | SimpleXMLTests.java:119:22:119:65 | new InputStreamReader(...) | semmle.label | new InputStreamReader(...) | | SimpleXMLTests.java:119:44:119:64 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream | @@ -164,9 +178,11 @@ nodes | SimpleXMLTests.java:145:5:145:25 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream | | SimpleXMLTests.java:145:32:145:32 | b [post update] : byte[] | semmle.label | b [post update] : byte[] | | SimpleXMLTests.java:146:22:146:34 | new String(...) | semmle.label | new String(...) | +| SimpleXMLTests.java:146:33:146:33 | b : byte[] | semmle.label | b : byte[] | | SimpleXMLTests.java:152:5:152:25 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream | | SimpleXMLTests.java:152:32:152:32 | b [post update] : byte[] | semmle.label | b [post update] : byte[] | | SimpleXMLTests.java:153:22:153:34 | new String(...) | semmle.label | new String(...) | +| SimpleXMLTests.java:153:33:153:33 | b : byte[] | semmle.label | b : byte[] | | TransformerTests.java:20:27:20:65 | new StreamSource(...) | semmle.label | new StreamSource(...) | | TransformerTests.java:20:44:20:64 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream | | TransformerTests.java:21:23:21:61 | new StreamSource(...) | semmle.label | new StreamSource(...) | @@ -231,6 +247,7 @@ nodes | XmlInputFactoryTests.java:48:34:48:54 | getInputStream(...) | semmle.label | getInputStream(...) | | XmlInputFactoryTests.java:55:35:55:55 | getInputStream(...) | semmle.label | getInputStream(...) | | XmlInputFactoryTests.java:56:34:56:54 | getInputStream(...) | semmle.label | getInputStream(...) | +subpaths #select | DocumentBuilderTests.java:14:19:14:39 | getInputStream(...) | DocumentBuilderTests.java:14:19:14:39 | getInputStream(...) | DocumentBuilderTests.java:14:19:14:39 | getInputStream(...) | Unsafe parsing of XML file from $@. | DocumentBuilderTests.java:14:19:14:39 | getInputStream(...) | user input | | DocumentBuilderTests.java:42:19:42:39 | getInputStream(...) | DocumentBuilderTests.java:42:19:42:39 | getInputStream(...) | DocumentBuilderTests.java:42:19:42:39 | getInputStream(...) | Unsafe parsing of XML file from $@. | DocumentBuilderTests.java:42:19:42:39 | getInputStream(...) | user input | diff --git a/java/ql/test/query-tests/security/CWE-681/semmle/tests/NumericCastTaintedLocal.expected b/java/ql/test/query-tests/security/CWE-681/semmle/tests/NumericCastTaintedLocal.expected index 90e1b421f97..2897a088743 100644 --- a/java/ql/test/query-tests/security/CWE-681/semmle/tests/NumericCastTaintedLocal.expected +++ b/java/ql/test/query-tests/security/CWE-681/semmle/tests/NumericCastTaintedLocal.expected @@ -3,13 +3,18 @@ edges | Test.java:11:6:11:46 | new InputStreamReader(...) : InputStreamReader | Test.java:10:36:11:47 | new BufferedReader(...) : BufferedReader | | Test.java:11:28:11:36 | System.in : InputStream | Test.java:11:6:11:46 | new InputStreamReader(...) : InputStreamReader | | Test.java:12:26:12:39 | readerBuffered : BufferedReader | Test.java:12:26:12:50 | readLine(...) : String | -| Test.java:12:26:12:50 | readLine(...) : String | Test.java:21:22:21:25 | data | +| Test.java:12:26:12:50 | readLine(...) : String | Test.java:14:27:14:38 | stringNumber : String | +| Test.java:14:27:14:38 | stringNumber : String | Test.java:14:27:14:45 | trim(...) : String | +| Test.java:14:27:14:45 | trim(...) : String | Test.java:21:22:21:25 | data | nodes | Test.java:10:36:11:47 | new BufferedReader(...) : BufferedReader | semmle.label | new BufferedReader(...) : BufferedReader | | Test.java:11:6:11:46 | new InputStreamReader(...) : InputStreamReader | semmle.label | new InputStreamReader(...) : InputStreamReader | | Test.java:11:28:11:36 | System.in : InputStream | semmle.label | System.in : InputStream | | Test.java:12:26:12:39 | readerBuffered : BufferedReader | semmle.label | readerBuffered : BufferedReader | | Test.java:12:26:12:50 | readLine(...) : String | semmle.label | readLine(...) : String | +| Test.java:14:27:14:38 | stringNumber : String | semmle.label | stringNumber : String | +| Test.java:14:27:14:45 | trim(...) : String | semmle.label | trim(...) : String | | Test.java:21:22:21:25 | data | semmle.label | data | +subpaths #select | Test.java:21:17:21:25 | (...)... | Test.java:11:28:11:36 | System.in : InputStream | Test.java:21:22:21:25 | data | $@ flows to here and is cast to a narrower type, potentially causing truncation. | Test.java:11:28:11:36 | System.in | User-provided value | diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedAzureCredentials.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedAzureCredentials.java new file mode 100644 index 00000000000..d243e18d608 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedAzureCredentials.java @@ -0,0 +1,66 @@ +import com.azure.identity.ClientSecretCredential; +import com.azure.identity.ClientSecretCredentialBuilder; +import com.azure.identity.UsernamePasswordCredential; +import com.azure.identity.UsernamePasswordCredentialBuilder; +import com.azure.security.keyvault.secrets.SecretClient; +import com.azure.security.keyvault.secrets.SecretClientBuilder; + +public class HardcodedAzureCredentials { + private final String clientId = "81734019-15a3-50t8-3253-5abe78abc3a1"; + private final String username = "username@example.onmicrosoft.com"; + private final String clientSecret = "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_"; + private final String tenantId = "22f367ce-535x-357w-2179-a33517mn166h"; + + //BAD: hard-coded username/password credentials + public void testHardcodedUsernamePassword(String input) { + UsernamePasswordCredential usernamePasswordCredential = new UsernamePasswordCredentialBuilder() + .clientId(clientId) + .username(username) + .password(clientSecret) + .build(); + + SecretClient client = new SecretClientBuilder() + .vaultUrl("https://myKeyVault.vault.azure.net") + .credential(usernamePasswordCredential) + .buildClient(); + } + + //GOOD: username/password credentials stored as environment variables + public void testEnvironmentUsernamePassword(String input) { + UsernamePasswordCredential usernamePasswordCredential = new UsernamePasswordCredentialBuilder() + .clientId(clientId) + .username(System.getenv("myUsername")) + .password(System.getenv("mySuperSecurePass")) + .build(); + + SecretClient client = new SecretClientBuilder() + .vaultUrl("https://myKeyVault.vault.azure.net") + .credential(usernamePasswordCredential) + .buildClient(); + } + + //BAD: hard-coded client secret + public void testHardcodedClientSecret(String input) { + ClientSecretCredential defaultCredential = new ClientSecretCredentialBuilder() + .clientId(clientId) + .clientSecret(clientSecret) + .tenantId(tenantId) + .build(); + } + + //GOOD: client secret stored as environment variables + public void testEnvironmentClientSecret(String input) { + ClientSecretCredential defaultCredential = new ClientSecretCredentialBuilder() + .clientId(clientId) + .clientSecret(System.getenv("myClientSecret")) + .tenantId(tenantId) + .build(); + } + + public static void main(String[] args) { + new HardcodedAzureCredentials().testHardcodedUsernamePassword(args[0]); + new HardcodedAzureCredentials().testEnvironmentUsernamePassword(args[0]); + new HardcodedAzureCredentials().testHardcodedClientSecret(args[0]); + new HardcodedAzureCredentials().testEnvironmentClientSecret(args[0]); + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected index ccd0259322e..33b8879d9e5 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.expected @@ -10,6 +10,25 @@ edges | FileCredentialTest.java:13:14:13:20 | "admin" : String | FileCredentialTest.java:19:13:19:13 | u : String | | FileCredentialTest.java:19:13:19:13 | u : String | FileCredentialTest.java:22:38:22:45 | v : String | | FileCredentialTest.java:22:38:22:45 | v : String | FileCredentialTest.java:23:36:23:36 | v | +| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | +| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | HardcodedAzureCredentials.java:63:3:63:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | +| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [username] : String | HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String | +| HardcodedAzureCredentials.java:10:2:10:68 | this <.field> [post update] [username] : String | HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [username] : String | +| HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" : String | HardcodedAzureCredentials.java:10:2:10:68 | this <.field> [post update] [username] : String | +| HardcodedAzureCredentials.java:11:2:11:74 | this <.field> [post update] [clientSecret] : String | HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | +| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | HardcodedAzureCredentials.java:11:2:11:74 | this <.field> [post update] [clientSecret] : String | +| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [clientSecret] : String | HardcodedAzureCredentials.java:19:13:19:24 | this <.field> [clientSecret] : String | +| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [username] : String | HardcodedAzureCredentials.java:18:13:18:20 | this <.field> [username] : String | +| HardcodedAzureCredentials.java:18:13:18:20 | this <.field> [username] : String | HardcodedAzureCredentials.java:18:13:18:20 | username | +| HardcodedAzureCredentials.java:19:13:19:24 | this <.field> [clientSecret] : String | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | +| HardcodedAzureCredentials.java:43:14:43:38 | parameter this [clientSecret] : String | HardcodedAzureCredentials.java:46:17:46:28 | this <.field> [clientSecret] : String | +| HardcodedAzureCredentials.java:46:17:46:28 | this <.field> [clientSecret] : String | HardcodedAzureCredentials.java:46:17:46:28 | clientSecret | +| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | HardcodedAzureCredentials.java:15:14:15:42 | parameter this [clientSecret] : String | +| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String | HardcodedAzureCredentials.java:15:14:15:42 | parameter this [username] : String | +| HardcodedAzureCredentials.java:63:3:63:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | HardcodedAzureCredentials.java:43:14:43:38 | parameter this [clientSecret] : String | +| HardcodedShiroKey.java:9:46:9:54 | "TEST123" : String | HardcodedShiroKey.java:9:46:9:65 | getBytes(...) | +| HardcodedShiroKey.java:18:61:18:86 | "4AvVhmFLUs0KTA3Kprsdag==" : String | HardcodedShiroKey.java:18:46:18:87 | decode(...) | +| HardcodedShiroKey.java:26:83:26:108 | "6ZmI6I2j5Y+R5aSn5ZOlAA==" : String | HardcodedShiroKey.java:26:46:26:109 | decode(...) | | Test.java:9:16:9:22 | "admin" : String | Test.java:12:13:12:15 | usr : String | | Test.java:9:16:9:22 | "admin" : String | Test.java:15:36:15:38 | usr | | Test.java:9:16:9:22 | "admin" : String | Test.java:17:39:17:41 | usr | @@ -42,6 +61,30 @@ nodes | FileCredentialTest.java:23:36:23:36 | v | semmle.label | v | | HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | semmle.label | "ACCESS_KEY" | | HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | semmle.label | "SECRET_KEY" | +| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | semmle.label | this <.method> [post update] [clientSecret] : String | +| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [username] : String | semmle.label | this <.method> [post update] [username] : String | +| HardcodedAzureCredentials.java:10:2:10:68 | this <.field> [post update] [username] : String | semmle.label | this <.field> [post update] [username] : String | +| HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" : String | semmle.label | "username@example.onmicrosoft.com" : String | +| HardcodedAzureCredentials.java:11:2:11:74 | this <.field> [post update] [clientSecret] : String | semmle.label | this <.field> [post update] [clientSecret] : String | +| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | semmle.label | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | +| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [clientSecret] : String | semmle.label | parameter this [clientSecret] : String | +| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [username] : String | semmle.label | parameter this [username] : String | +| HardcodedAzureCredentials.java:18:13:18:20 | this <.field> [username] : String | semmle.label | this <.field> [username] : String | +| HardcodedAzureCredentials.java:18:13:18:20 | username | semmle.label | username | +| HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | semmle.label | clientSecret | +| HardcodedAzureCredentials.java:19:13:19:24 | this <.field> [clientSecret] : String | semmle.label | this <.field> [clientSecret] : String | +| HardcodedAzureCredentials.java:43:14:43:38 | parameter this [clientSecret] : String | semmle.label | parameter this [clientSecret] : String | +| HardcodedAzureCredentials.java:46:17:46:28 | clientSecret | semmle.label | clientSecret | +| HardcodedAzureCredentials.java:46:17:46:28 | this <.field> [clientSecret] : String | semmle.label | this <.field> [clientSecret] : String | +| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | semmle.label | new HardcodedAzureCredentials(...) [clientSecret] : String | +| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String | semmle.label | new HardcodedAzureCredentials(...) [username] : String | +| HardcodedAzureCredentials.java:63:3:63:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | semmle.label | new HardcodedAzureCredentials(...) [clientSecret] : String | +| HardcodedShiroKey.java:9:46:9:54 | "TEST123" : String | semmle.label | "TEST123" : String | +| HardcodedShiroKey.java:9:46:9:65 | getBytes(...) | semmle.label | getBytes(...) | +| HardcodedShiroKey.java:18:46:18:87 | decode(...) | semmle.label | decode(...) | +| HardcodedShiroKey.java:18:61:18:86 | "4AvVhmFLUs0KTA3Kprsdag==" : String | semmle.label | "4AvVhmFLUs0KTA3Kprsdag==" : String | +| HardcodedShiroKey.java:26:46:26:109 | decode(...) | semmle.label | decode(...) | +| HardcodedShiroKey.java:26:83:26:108 | "6ZmI6I2j5Y+R5aSn5ZOlAA==" : String | semmle.label | "6ZmI6I2j5Y+R5aSn5ZOlAA==" : String | | Test.java:9:16:9:22 | "admin" : String | semmle.label | "admin" : String | | Test.java:10:17:10:24 | "123456" : String | semmle.label | "123456" : String | | Test.java:12:13:12:15 | usr : String | semmle.label | usr : String | @@ -63,6 +106,7 @@ nodes | Test.java:29:51:29:65 | password : String | semmle.label | password : String | | Test.java:30:36:30:39 | user | semmle.label | user | | Test.java:30:42:30:49 | password | semmle.label | password | +subpaths #select | CredentialsTest.java:7:34:7:41 | "123456" | CredentialsTest.java:7:34:7:41 | "123456" : String | CredentialsTest.java:13:39:13:39 | p | Hard-coded value flows to $@. | CredentialsTest.java:13:39:13:39 | p | sensitive API call | | CredentialsTest.java:7:34:7:41 | "123456" | CredentialsTest.java:7:34:7:41 | "123456" : String | CredentialsTest.java:18:39:18:39 | q | Hard-coded value flows to $@. | CredentialsTest.java:18:39:18:39 | q | sensitive API call | @@ -72,6 +116,12 @@ nodes | FileCredentialTest.java:18:35:18:41 | "admin" | FileCredentialTest.java:18:35:18:41 | "admin" | FileCredentialTest.java:18:35:18:41 | "admin" | Hard-coded value flows to $@. | FileCredentialTest.java:18:35:18:41 | "admin" | sensitive API call | | HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | Hard-coded value flows to $@. | HardcodedAWSCredentials.java:8:50:8:61 | "ACCESS_KEY" | sensitive API call | | HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | Hard-coded value flows to $@. | HardcodedAWSCredentials.java:8:64:8:75 | "SECRET_KEY" | sensitive API call | +| HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" | HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" : String | HardcodedAzureCredentials.java:18:13:18:20 | username | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:18:13:18:20 | username | sensitive API call | +| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" | HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | sensitive API call | +| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" | HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | HardcodedAzureCredentials.java:46:17:46:28 | clientSecret | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:46:17:46:28 | clientSecret | sensitive API call | +| HardcodedShiroKey.java:9:46:9:54 | "TEST123" | HardcodedShiroKey.java:9:46:9:54 | "TEST123" : String | HardcodedShiroKey.java:9:46:9:65 | getBytes(...) | Hard-coded value flows to $@. | HardcodedShiroKey.java:9:46:9:65 | getBytes(...) | sensitive API call | +| HardcodedShiroKey.java:18:61:18:86 | "4AvVhmFLUs0KTA3Kprsdag==" | HardcodedShiroKey.java:18:61:18:86 | "4AvVhmFLUs0KTA3Kprsdag==" : String | HardcodedShiroKey.java:18:46:18:87 | decode(...) | Hard-coded value flows to $@. | HardcodedShiroKey.java:18:46:18:87 | decode(...) | sensitive API call | +| HardcodedShiroKey.java:26:83:26:108 | "6ZmI6I2j5Y+R5aSn5ZOlAA==" | HardcodedShiroKey.java:26:83:26:108 | "6ZmI6I2j5Y+R5aSn5ZOlAA==" : String | HardcodedShiroKey.java:26:46:26:109 | decode(...) | Hard-coded value flows to $@. | HardcodedShiroKey.java:26:46:26:109 | decode(...) | sensitive API call | | Test.java:9:16:9:22 | "admin" | Test.java:9:16:9:22 | "admin" : String | Test.java:15:36:15:38 | usr | Hard-coded value flows to $@. | Test.java:15:36:15:38 | usr | sensitive API call | | Test.java:9:16:9:22 | "admin" | Test.java:9:16:9:22 | "admin" : String | Test.java:17:39:17:41 | usr | Hard-coded value flows to $@. | Test.java:17:39:17:41 | usr | sensitive API call | | Test.java:9:16:9:22 | "admin" | Test.java:9:16:9:22 | "admin" : String | Test.java:18:39:18:41 | usr | Hard-coded value flows to $@. | Test.java:18:39:18:41 | usr | sensitive API call | diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected index 05e47dacf3f..a960464f0d9 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsSourceCall.expected @@ -1,11 +1,40 @@ edges +| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | +| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [username] : String | HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String | +| HardcodedAzureCredentials.java:10:2:10:68 | this <.field> [post update] [username] : String | HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [username] : String | +| HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" : String | HardcodedAzureCredentials.java:10:2:10:68 | this <.field> [post update] [username] : String | +| HardcodedAzureCredentials.java:11:2:11:74 | this <.field> [post update] [clientSecret] : String | HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | +| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | HardcodedAzureCredentials.java:11:2:11:74 | this <.field> [post update] [clientSecret] : String | +| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [clientSecret] : String | HardcodedAzureCredentials.java:19:13:19:24 | this <.field> [clientSecret] : String | +| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [username] : String | HardcodedAzureCredentials.java:18:13:18:20 | this <.field> [username] : String | +| HardcodedAzureCredentials.java:18:13:18:20 | this <.field> [username] : String | HardcodedAzureCredentials.java:18:13:18:20 | username | +| HardcodedAzureCredentials.java:19:13:19:24 | this <.field> [clientSecret] : String | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | +| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | HardcodedAzureCredentials.java:15:14:15:42 | parameter this [clientSecret] : String | +| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String | HardcodedAzureCredentials.java:15:14:15:42 | parameter this [username] : String | | Test.java:10:17:10:24 | "123456" : String | Test.java:26:17:26:20 | pass | | User.java:2:43:2:50 | "123456" : String | User.java:5:15:5:24 | DEFAULT_PW | nodes +| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [clientSecret] : String | semmle.label | this <.method> [post update] [clientSecret] : String | +| HardcodedAzureCredentials.java:8:14:8:38 | this <.method> [post update] [username] : String | semmle.label | this <.method> [post update] [username] : String | +| HardcodedAzureCredentials.java:10:2:10:68 | this <.field> [post update] [username] : String | semmle.label | this <.field> [post update] [username] : String | +| HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" : String | semmle.label | "username@example.onmicrosoft.com" : String | +| HardcodedAzureCredentials.java:11:2:11:74 | this <.field> [post update] [clientSecret] : String | semmle.label | this <.field> [post update] [clientSecret] : String | +| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | semmle.label | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | +| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [clientSecret] : String | semmle.label | parameter this [clientSecret] : String | +| HardcodedAzureCredentials.java:15:14:15:42 | parameter this [username] : String | semmle.label | parameter this [username] : String | +| HardcodedAzureCredentials.java:18:13:18:20 | this <.field> [username] : String | semmle.label | this <.field> [username] : String | +| HardcodedAzureCredentials.java:18:13:18:20 | username | semmle.label | username | +| HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | semmle.label | clientSecret | +| HardcodedAzureCredentials.java:19:13:19:24 | this <.field> [clientSecret] : String | semmle.label | this <.field> [clientSecret] : String | +| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [clientSecret] : String | semmle.label | new HardcodedAzureCredentials(...) [clientSecret] : String | +| HardcodedAzureCredentials.java:61:3:61:33 | new HardcodedAzureCredentials(...) [username] : String | semmle.label | new HardcodedAzureCredentials(...) [username] : String | | Test.java:10:17:10:24 | "123456" : String | semmle.label | "123456" : String | | Test.java:26:17:26:20 | pass | semmle.label | pass | | User.java:2:43:2:50 | "123456" : String | semmle.label | "123456" : String | | User.java:5:15:5:24 | DEFAULT_PW | semmle.label | DEFAULT_PW | +subpaths #select +| HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" | HardcodedAzureCredentials.java:10:34:10:67 | "username@example.onmicrosoft.com" : String | HardcodedAzureCredentials.java:18:13:18:20 | username | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:18:13:18:20 | username | sensitive call | +| HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" | HardcodedAzureCredentials.java:11:38:11:73 | "1n1.qAc~3Q-1t38aF79Xzv5AUEfR5-ct3_" : String | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | Hard-coded value flows to $@. | HardcodedAzureCredentials.java:19:13:19:24 | clientSecret | sensitive call | | Test.java:10:17:10:24 | "123456" | Test.java:10:17:10:24 | "123456" : String | Test.java:26:17:26:20 | pass | Hard-coded value flows to $@. | Test.java:26:17:26:20 | pass | sensitive call | | User.java:2:43:2:50 | "123456" | User.java:2:43:2:50 | "123456" : String | User.java:5:15:5:24 | DEFAULT_PW | Hard-coded value flows to $@. | User.java:5:15:5:24 | DEFAULT_PW | sensitive call | diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedShiroKey.java b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedShiroKey.java new file mode 100644 index 00000000000..3647af01ed1 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedShiroKey.java @@ -0,0 +1,40 @@ +import org.apache.shiro.web.mgt.CookieRememberMeManager; + + +public class HardcodedShiroKey { + + //BAD: hard-coded shiro key + public void testHardcodedShiroKey(String input) { + CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); + cookieRememberMeManager.setCipherKey("TEST123".getBytes()); + + } + + + //BAD: hard-coded shiro key encoded by java.util.Base64 + public void testHardcodedbase64ShiroKey1(String input) { + CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); + java.util.Base64.Decoder decoder = java.util.Base64.getDecoder(); + cookieRememberMeManager.setCipherKey(decoder.decode("4AvVhmFLUs0KTA3Kprsdag==")); + + } + + + //BAD: hard-coded shiro key encoded by org.apache.shiro.codec.Base64 + public void testHardcodedbase64ShiroKey2(String input) { + CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); + cookieRememberMeManager.setCipherKey(org.apache.shiro.codec.Base64.decode("6ZmI6I2j5Y+R5aSn5ZOlAA==")); + + } + + //GOOD: random shiro key + public void testRandomShiroKey(String input) { + CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); + } + + + + + + +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-798/semmle/tests/options b/java/ql/test/query-tests/security/CWE-798/semmle/tests/options index e13da5319f0..2d21958e299 100644 --- a/java/ql/test/query-tests/security/CWE-798/semmle/tests/options +++ b/java/ql/test/query-tests/security/CWE-798/semmle/tests/options @@ -1 +1 @@ -// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/amazon-aws-sdk-1.11.700 +// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/amazon-aws-sdk-1.11.700:${testdir}/../../../../../stubs/azure-sdk-for-java:${testdir}/../../../../../stubs/shiro-core-1.4.0 diff --git a/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypass.expected b/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypass.expected deleted file mode 100644 index efa1016bbb7..00000000000 --- a/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypass.expected +++ /dev/null @@ -1,24 +0,0 @@ -edges -| Test.java:17:26:17:38 | args : String[] | Test.java:25:6:25:21 | ... == ... | -| Test.java:31:6:31:27 | getValue(...) : String | Test.java:31:6:31:43 | equals(...) | -| Test.java:36:6:36:27 | getValue(...) : String | Test.java:36:6:36:36 | ... == ... | -| Test.java:81:6:81:27 | getValue(...) : String | Test.java:81:6:81:36 | ... == ... | -| Test.java:91:6:91:27 | getValue(...) : String | Test.java:91:6:91:36 | ... == ... | -nodes -| Test.java:17:26:17:38 | args : String[] | semmle.label | args : String[] | -| Test.java:25:6:25:21 | ... == ... | semmle.label | ... == ... | -| Test.java:31:6:31:27 | getValue(...) : String | semmle.label | getValue(...) : String | -| Test.java:31:6:31:43 | equals(...) | semmle.label | equals(...) | -| Test.java:36:6:36:27 | getValue(...) : String | semmle.label | getValue(...) : String | -| Test.java:36:6:36:36 | ... == ... | semmle.label | ... == ... | -| Test.java:81:6:81:27 | getValue(...) : String | semmle.label | getValue(...) : String | -| Test.java:81:6:81:36 | ... == ... | semmle.label | ... == ... | -| Test.java:91:6:91:27 | getValue(...) : String | semmle.label | getValue(...) : String | -| Test.java:91:6:91:36 | ... == ... | semmle.label | ... == ... | -#select -| Test.java:26:4:26:24 | login(...) | Test.java:17:26:17:38 | args : String[] | Test.java:25:6:25:21 | ... == ... | Sensitive method may not be executed depending on $@, which flows from $@. | Test.java:25:6:25:21 | ... == ... | this condition | Test.java:17:26:17:38 | args | user input | -| Test.java:32:4:32:24 | login(...) | Test.java:31:6:31:27 | getValue(...) : String | Test.java:31:6:31:43 | equals(...) | Sensitive method may not be executed depending on $@, which flows from $@. | Test.java:31:6:31:43 | equals(...) | this condition | Test.java:31:6:31:27 | getValue(...) | user input | -| Test.java:37:4:37:24 | login(...) | Test.java:36:6:36:27 | getValue(...) : String | Test.java:36:6:36:36 | ... == ... | Sensitive method may not be executed depending on $@, which flows from $@. | Test.java:36:6:36:36 | ... == ... | this condition | Test.java:36:6:36:27 | getValue(...) | user input | -| Test.java:39:4:39:30 | reCheckAuth(...) | Test.java:36:6:36:27 | getValue(...) : String | Test.java:36:6:36:36 | ... == ... | Sensitive method may not be executed depending on $@, which flows from $@. | Test.java:36:6:36:36 | ... == ... | this condition | Test.java:36:6:36:27 | getValue(...) | user input | -| Test.java:82:4:82:24 | login(...) | Test.java:81:6:81:27 | getValue(...) : String | Test.java:81:6:81:36 | ... == ... | Sensitive method may not be executed depending on $@, which flows from $@. | Test.java:81:6:81:36 | ... == ... | this condition | Test.java:81:6:81:27 | getValue(...) | user input | -| Test.java:92:4:92:24 | login(...) | Test.java:91:6:91:27 | getValue(...) : String | Test.java:91:6:91:36 | ... == ... | Sensitive method may not be executed depending on $@, which flows from $@. | Test.java:91:6:91:36 | ... == ... | this condition | Test.java:91:6:91:27 | getValue(...) | user input | diff --git a/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypass.qlref b/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypass.qlref deleted file mode 100644 index 82d29b30b17..00000000000 --- a/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypass.qlref +++ /dev/null @@ -1 +0,0 @@ -Security/CWE/CWE-807/ConditionalBypass.ql \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.expected b/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/query-tests/security/CWE-807/semmle/tests/Test.java b/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.java similarity index 52% rename from java/ql/test/query-tests/security/CWE-807/semmle/tests/Test.java rename to java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.java index 5d9b8db623c..51dd5379005 100644 --- a/java/ql/test/query-tests/security/CWE-807/semmle/tests/Test.java +++ b/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.java @@ -2,58 +2,45 @@ // http://cwe.mitre.org/data/definitions/807.html package test.cwe807.semmle.tests; - - - import java.net.InetAddress; import java.net.Inet4Address; import java.net.UnknownHostException; import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; import org.apache.shiro.SecurityUtils; import org.apache.shiro.subject.Subject; -class Test { - public static void main(String[] args) throws UnknownHostException { - String user = args[0]; - String password = args[1]; - - String isAdmin = args[3]; - +class ConditionalBypassTest { + public static void main(HttpServletRequest request) throws Exception { + String user = request.getParameter("user"); + String password = request.getParameter("password"); + + String isAdmin = request.getParameter("isAdmin"); + // BAD: login is only executed if isAdmin is false, but isAdmin // is controlled by the user - if(isAdmin=="false") + if (isAdmin == "false") // $ hasConditionalBypassTest login(user, password); - + Cookie adminCookie = getCookies()[0]; // BAD: login is only executed if the cookie value is false, but the cookie // is controlled by the user - if(adminCookie.getValue().equals("false")) + if (adminCookie.getValue().equals("false")) // $ hasConditionalBypassTest login(user, password); - - // FALSE POSITIVES: both methods are conditionally executed, but they probably + + // GOOD: both methods are conditionally executed, but they probably // both perform the security-critical action - if(adminCookie.getValue()=="false") { + if (adminCookie.getValue() == "false") { // Safe login(user, password); } else { reCheckAuth(user, password); } - + // FALSE NEGATIVE: we have no way of telling that the skipped method is sensitive - if(adminCookie.getValue()=="false") + if (adminCookie.getValue() == "false") // $ MISSING: $ hasConditionalBypassTest doReallyImportantSecurityWork(); - - // Apache Shiro permissions system - String whatDoTheyWantToDo = args[4]; - Subject subject = SecurityUtils.getSubject(); - // BAD: permissions decision made using tainted data - if(subject.isPermitted("domain:sublevel:" + whatDoTheyWantToDo)) - doIt(); - - // GOOD: use fixed checks - if(subject.isPermitted("domain:sublevel:whatTheMethodDoes")) - doIt(); - + InetAddress local = InetAddress.getLocalHost(); // GOOD: reverse DNS on localhost is fine if (local.getCanonicalHostName().equals("localhost")) { @@ -63,68 +50,129 @@ class Test { login(user, password); } } - + public static void test(String user, String password) { Cookie adminCookie = getCookies()[0]; // GOOD: login always happens - if(adminCookie.getValue()=="false") + if (adminCookie.getValue() == "false") login(user, password); else { - // do something else login(user, password); } } - + public static void test2(String user, String password) { Cookie adminCookie = getCookies()[0]; // BAD: login may happen once or twice - if(adminCookie.getValue()=="false") + if (adminCookie.getValue() == "false") // $ hasConditionalBypassTest login(user, password); else { // do something else + doIt(); } login(user, password); } - + public static void test3(String user, String password) { Cookie adminCookie = getCookies()[0]; - if(adminCookie.getValue()=="false") + // BAD: login may not happen + if (adminCookie.getValue() == "false") // $ hasConditionalBypassTest login(user, password); else { // do something else - // BAD: login may not happen - return; + doIt(); } + return; } - + public static void test4(String user, String password) { Cookie adminCookie = getCookies()[0]; // GOOD: login always happens - if(adminCookie.getValue()=="false") { + if (adminCookie.getValue() == "false") { login(user, password); return; } - + // do other things login(user, password); return; } - + + public static void test5(String user, String password) throws Exception { + Cookie adminCookie = getCookies()[0]; + // GOOD: exit with Exception if condition is not met + if (adminCookie.getValue() == "false") { + throw new Exception(); + } + + login(user, password); + } + + public static void test6(String user, String password) { + Cookie adminCookie = getCookies()[0]; + // GOOD: exit with return if condition is not met + if (adminCookie.getValue() == "false") { + return; + } + + login(user, password); + } + + public static void test7(String user, String password) { + Cookie adminCookie = getCookies()[0]; + // BAD: login is bypasseable + if (adminCookie.getValue() == "false") { // $ hasConditionalBypassTest + login(user, password); + return; + } else { + doIt(); + } + } + + public static void test8(String user, String password) { + Cookie adminCookie = getCookies()[0]; + { + // BAD: login may not happen + if (adminCookie.getValue() == "false") // $ hasConditionalBypassTest + authorize(user, password); + else { + // do something else + doIt(); + } + } + { + // obtainAuthor is not sensitive, so this is safe + if (adminCookie.getValue() == "false") + obtainAuthor(); + else { + doIt(); + } + } + } + public static void login(String user, String password) { // login } - + public static void reCheckAuth(String user, String password) { // login } - + + public static void authorize(String user, String password) { + // login + } + + public static String obtainAuthor() { + return ""; + } + public static Cookie[] getCookies() { // get cookies from a servlet return new Cookie[0]; } - + public static void doIt() {} - + public static void doReallyImportantSecurityWork() { // login, authenticate, everything } diff --git a/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.ql b/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.ql new file mode 100644 index 00000000000..8fc8fe9b9af --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-807/semmle/tests/ConditionalBypassTest.ql @@ -0,0 +1,20 @@ +import java +import semmle.code.java.security.ConditionalBypassQuery +import TestUtilities.InlineExpectationsTest + +class ConditionalBypassTest extends InlineExpectationsTest { + ConditionalBypassTest() { this = "ConditionalBypassTest" } + + override string getARelevantTag() { result = "hasConditionalBypassTest" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasConditionalBypassTest" and + exists(DataFlow::Node src, DataFlow::Node sink, ConditionalBypassFlowConfig conf | + conf.hasFlow(src, sink) + | + sink.getLocation() = location and + element = sink.toString() and + value = "" + ) + } +} diff --git a/java/ql/test/query-tests/security/CWE-807/semmle/tests/TaintedPermissionsCheck.expected b/java/ql/test/query-tests/security/CWE-807/semmle/tests/TaintedPermissionsCheck.expected index 39d8074bf36..10622bf7d90 100644 --- a/java/ql/test/query-tests/security/CWE-807/semmle/tests/TaintedPermissionsCheck.expected +++ b/java/ql/test/query-tests/security/CWE-807/semmle/tests/TaintedPermissionsCheck.expected @@ -1,7 +1,8 @@ edges -| Test.java:17:26:17:38 | args : String[] | Test.java:50:26:50:64 | ... + ... | +| TaintedPermissionsCheckTest.java:12:19:12:48 | getParameter(...) : String | TaintedPermissionsCheckTest.java:15:27:15:53 | ... + ... | nodes -| Test.java:17:26:17:38 | args : String[] | semmle.label | args : String[] | -| Test.java:50:26:50:64 | ... + ... | semmle.label | ... + ... | +| TaintedPermissionsCheckTest.java:12:19:12:48 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| TaintedPermissionsCheckTest.java:15:27:15:53 | ... + ... | semmle.label | ... + ... | +subpaths #select -| Test.java:50:6:50:65 | isPermitted(...) | Test.java:17:26:17:38 | args : String[] | Test.java:50:26:50:64 | ... + ... | Permissions check uses user-controlled $@. | Test.java:17:26:17:38 | args | data | +| TaintedPermissionsCheckTest.java:15:7:15:54 | isPermitted(...) | TaintedPermissionsCheckTest.java:12:19:12:48 | getParameter(...) : String | TaintedPermissionsCheckTest.java:15:27:15:53 | ... + ... | Permissions check uses user-controlled $@. | TaintedPermissionsCheckTest.java:12:19:12:48 | getParameter(...) | data | diff --git a/java/ql/test/query-tests/security/CWE-807/semmle/tests/TaintedPermissionsCheckTest.java b/java/ql/test/query-tests/security/CWE-807/semmle/tests/TaintedPermissionsCheckTest.java new file mode 100644 index 00000000000..622538b7e35 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-807/semmle/tests/TaintedPermissionsCheckTest.java @@ -0,0 +1,25 @@ +// Test case for CWE-807 (Reliance on Untrusted Inputs in a Security Decision) +// http://cwe.mitre.org/data/definitions/807.html +package test.cwe807.semmle.tests; + +import javax.servlet.http.HttpServletRequest; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; + +class TaintedPermissionsCheckTest { + public static void main(HttpServletRequest request) throws Exception { + // Apache Shiro permissions system + String action = request.getParameter("action"); + Subject subject = SecurityUtils.getSubject(); + // BAD: permissions decision made using tainted data + if (subject.isPermitted("domain:sublevel:" + action)) + doIt(); + + // GOOD: use fixed checks + if (subject.isPermitted("domain:sublevel:whatTheMethodDoes")) + doIt(); + } + + public static void doIt() {} + +} diff --git a/java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/Configuration.java b/java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/Configuration.java similarity index 100% rename from java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/Configuration.java rename to java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/Configuration.java diff --git a/java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/lib/SourceResolver.java b/java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/lib/SourceResolver.java similarity index 100% rename from java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/lib/SourceResolver.java rename to java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/lib/SourceResolver.java diff --git a/java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/om/NotationSet.java b/java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/om/NotationSet.java similarity index 100% rename from java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/om/NotationSet.java rename to java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/om/NotationSet.java diff --git a/java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/AbstractXsltTransformer.java b/java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/AbstractXsltTransformer.java similarity index 100% rename from java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/AbstractXsltTransformer.java rename to java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/AbstractXsltTransformer.java diff --git a/java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/Destination.java b/java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/Destination.java similarity index 100% rename from java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/Destination.java rename to java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/Destination.java diff --git a/java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/Processor.java b/java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/Processor.java similarity index 100% rename from java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/Processor.java rename to java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/Processor.java diff --git a/java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/QName.java b/java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/QName.java similarity index 100% rename from java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/QName.java rename to java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/QName.java diff --git a/java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/SaxonApiException.java b/java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/SaxonApiException.java similarity index 100% rename from java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/SaxonApiException.java rename to java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/SaxonApiException.java diff --git a/java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/SaxonApiUncheckedException.java b/java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/SaxonApiUncheckedException.java similarity index 100% rename from java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/SaxonApiUncheckedException.java rename to java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/SaxonApiUncheckedException.java diff --git a/java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XdmItem.java b/java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XdmItem.java similarity index 100% rename from java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XdmItem.java rename to java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XdmItem.java diff --git a/java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XdmValue.java b/java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XdmValue.java similarity index 100% rename from java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XdmValue.java rename to java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XdmValue.java diff --git a/java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/Xslt30Transformer.java b/java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/Xslt30Transformer.java similarity index 100% rename from java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/Xslt30Transformer.java rename to java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/Xslt30Transformer.java diff --git a/java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XsltCompiler.java b/java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XsltCompiler.java similarity index 100% rename from java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XsltCompiler.java rename to java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XsltCompiler.java diff --git a/java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XsltExecutable.java b/java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XsltExecutable.java similarity index 100% rename from java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XsltExecutable.java rename to java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XsltExecutable.java diff --git a/java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XsltPackage.java b/java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XsltPackage.java similarity index 100% rename from java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XsltPackage.java rename to java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XsltPackage.java diff --git a/java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XsltTransformer.java b/java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XsltTransformer.java similarity index 100% rename from java/ql/test/experimental/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XsltTransformer.java rename to java/ql/test/stubs/Saxon-HE-9.9.1-7/net/sf/saxon/s9api/XsltTransformer.java diff --git a/java/ql/test/stubs/android/android/accounts/Account.java b/java/ql/test/stubs/android/android/accounts/Account.java new file mode 100644 index 00000000000..806f076452e --- /dev/null +++ b/java/ql/test/stubs/android/android/accounts/Account.java @@ -0,0 +1,21 @@ +// Generated automatically from android.accounts.Account for testing purposes + +package android.accounts; + +import android.os.Parcel; +import android.os.Parcelable; + +public class Account implements Parcelable +{ + protected Account() {} + public Account(Parcel p0){} + public Account(String p0, String p1){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public final String name = null; + public final String type = null; + public int describeContents(){ return 0; } + public int hashCode(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/BroadcastReceiver.java b/java/ql/test/stubs/android/android/content/BroadcastReceiver.java index 1d73018c96d..93375c04d85 100644 --- a/java/ql/test/stubs/android/android/content/BroadcastReceiver.java +++ b/java/ql/test/stubs/android/android/content/BroadcastReceiver.java @@ -1,255 +1,45 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Generated automatically from android.content.BroadcastReceiver for testing purposes + package android.content; +import android.content.Context; +import android.content.Intent; import android.os.Bundle; -/** - * Base class for code that will receive intents sent by sendBroadcast(). - * - *

    If you don't need to send broadcasts across applications, consider using - * this class with {@link android.support.v4.content.LocalBroadcastManager} instead - * of the more general facilities described below. This will give you a much - * more efficient implementation (no cross-process communication needed) and allow - * you to avoid thinking about any security issues related to other applications - * being able to receive or send your broadcasts. - * - *

    You can either dynamically register an instance of this class with - * {@link Context#registerReceiver Context.registerReceiver()} - * or statically publish an implementation through the - * {@link android.R.styleable#AndroidManifestReceiver <receiver>} - * tag in your AndroidManifest.xml. - * - *

    Note: - *    If registering a receiver in your - * {@link android.app.Activity#onResume() Activity.onResume()} - * implementation, you should unregister it in - * {@link android.app.Activity#onPause() Activity.onPause()}. - * (You won't receive intents when paused, - * and this will cut down on unnecessary system overhead). Do not unregister in - * {@link android.app.Activity#onSaveInstanceState(android.os.Bundle) Activity.onSaveInstanceState()}, - * because this won't be called if the user moves back in the history - * stack. - * - *

    There are two major classes of broadcasts that can be received:

    - *
      - *
    • Normal broadcasts (sent with {@link Context#sendBroadcast(Intent) - * Context.sendBroadcast}) are completely asynchronous. All receivers of the - * broadcast are run in an undefined order, often at the same time. This is - * more efficient, but means that receivers cannot use the result or abort - * APIs included here. - *
    • Ordered broadcasts (sent with {@link Context#sendOrderedBroadcast(Intent, String) - * Context.sendOrderedBroadcast}) are delivered to one receiver at a time. - * As each receiver executes in turn, it can propagate a result to the next - * receiver, or it can completely abort the broadcast so that it won't be passed - * to other receivers. The order receivers run in can be controlled with the - * {@link android.R.styleable#AndroidManifestIntentFilter_priority - * android:priority} attribute of the matching intent-filter; receivers with - * the same priority will be run in an arbitrary order. - *
    - * - *

    Even in the case of normal broadcasts, the system may in some - * situations revert to delivering the broadcast one receiver at a time. In - * particular, for receivers that may require the creation of a process, only - * one will be run at a time to avoid overloading the system with new processes. - * In this situation, however, the non-ordered semantics hold: these receivers still - * cannot return results or abort their broadcast.

    - * - *

    Note that, although the Intent class is used for sending and receiving - * these broadcasts, the Intent broadcast mechanism here is completely separate - * from Intents that are used to start Activities with - * {@link Context#startActivity Context.startActivity()}. - * There is no way for a BroadcastReceiver - * to see or capture Intents used with startActivity(); likewise, when - * you broadcast an Intent, you will never find or start an Activity. - * These two operations are semantically very different: starting an - * Activity with an Intent is a foreground operation that modifies what the - * user is currently interacting with; broadcasting an Intent is a background - * operation that the user is not normally aware of. - * - *

    The BroadcastReceiver class (when launched as a component through - * a manifest's {@link android.R.styleable#AndroidManifestReceiver <receiver>} - * tag) is an important part of an - * application's overall lifecycle.

    - * - *

    Topics covered here: - *

      - *
    1. Security - *
    2. Receiver Lifecycle - *
    3. Process Lifecycle - *
    - * - *
    - *

    Developer Guides

    - *

    For information about how to use this class to receive and resolve intents, read the - * Intents and Intent Filters - * developer guide.

    - *
    - * - * - *

    Security

    - * - *

    Receivers used with the {@link Context} APIs are by their nature a - * cross-application facility, so you must consider how other applications - * may be able to abuse your use of them. Some things to consider are: - * - *

      - *
    • The Intent namespace is global. Make sure that Intent action names and - * other strings are written in a namespace you own, or else you may inadvertantly - * conflict with other applications. - *

    • When you use {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)}, - * any application may send broadcasts to that registered receiver. You can - * control who can send broadcasts to it through permissions described below. - *

    • When you publish a receiver in your application's manifest and specify - * intent-filters for it, any other application can send broadcasts to it regardless - * of the filters you specify. To prevent others from sending to it, make it - * unavailable to them with android:exported="false". - *

    • When you use {@link Context#sendBroadcast(Intent)} or related methods, - * normally any other application can receive these broadcasts. You can control who - * can receive such broadcasts through permissions described below. Alternatively, - * starting with {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH}, you - * can also safely restrict the broadcast to a single application with - * {@link Intent#setPackage(String) Intent.setPackage} - *

    - * - *

    None of these issues exist when using - * {@link android.support.v4.content.LocalBroadcastManager}, since intents - * broadcast it never go outside of the current process. - * - *

    Access permissions can be enforced by either the sender or receiver - * of a broadcast. - * - *

    To enforce a permission when sending, you supply a non-null - * permission argument to - * {@link Context#sendBroadcast(Intent, String)} or - * {@link Context#sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler, int, String, Bundle)}. - * Only receivers who have been granted this permission - * (by requesting it with the - * {@link android.R.styleable#AndroidManifestUsesPermission <uses-permission>} - * tag in their AndroidManifest.xml) will be able to receive - * the broadcast. - * - *

    To enforce a permission when receiving, you supply a non-null - * permission when registering your receiver -- either when calling - * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter, String, android.os.Handler)} - * or in the static - * {@link android.R.styleable#AndroidManifestReceiver <receiver>} - * tag in your AndroidManifest.xml. Only broadcasters who have - * been granted this permission (by requesting it with the - * {@link android.R.styleable#AndroidManifestUsesPermission <uses-permission>} - * tag in their AndroidManifest.xml) will be able to send an - * Intent to the receiver. - * - *

    See the Security and Permissions - * document for more information on permissions and security in general. - * - * - *

    Receiver Lifecycle

    - * - *

    A BroadcastReceiver object is only valid for the duration of the call - * to {@link #onReceive}. Once your code returns from this function, - * the system considers the object to be finished and no longer active. - * - *

    This has important repercussions to what you can do in an - * {@link #onReceive} implementation: anything that requires asynchronous - * operation is not available, because you will need to return from the - * function to handle the asynchronous operation, but at that point the - * BroadcastReceiver is no longer active and thus the system is free to kill - * its process before the asynchronous operation completes. - * - *

    In particular, you may not show a dialog or bind to a service from - * within a BroadcastReceiver. For the former, you should instead use the - * {@link android.app.NotificationManager} API. For the latter, you can - * use {@link android.content.Context#startService Context.startService()} to - * send a command to the service. - * - * - *

    Process Lifecycle

    - * - *

    A process that is currently executing a BroadcastReceiver (that is, - * currently running the code in its {@link #onReceive} method) is - * considered to be a foreground process and will be kept running by the - * system except under cases of extreme memory pressure. - * - *

    Once you return from onReceive(), the BroadcastReceiver is no longer - * active, and its hosting process is only as important as any other application - * components that are running in it. This is especially important because if - * that process was only hosting the BroadcastReceiver (a common case for - * applications that the user has never or not recently interacted with), then - * upon returning from onReceive() the system will consider its process - * to be empty and aggressively kill it so that resources are available for other - * more important processes. - * - *

    This means that for longer-running operations you will often use - * a {@link android.app.Service} in conjunction with a BroadcastReceiver to keep - * the containing process active for the entire time of your operation. - */ -public abstract class BroadcastReceiver { - - /** - * State for a result that is pending for a broadcast receiver. Returned - * by {@link BroadcastReceiver#goAsync() goAsync()} - * while in {@link BroadcastReceiver#onReceive BroadcastReceiver.onReceive()}. - * This allows you to return from onReceive() without having the broadcast - * terminate; you must call {@link #finish()} once you are done with the - * broadcast. This allows you to process the broadcast off of the main - * thread of your app. - * - *

    Note on threading: the state inside of this class is not itself - * thread-safe, however you can use it from any thread if you properly - * sure that you do not have races. Typically this means you will hand - * the entire object to another thread, which will be solely responsible - * for setting any results and finally calling {@link #finish()}. - */ - - public BroadcastReceiver() { +import android.os.IBinder; + +abstract public class BroadcastReceiver +{ + public BroadcastReceiver(){} + public IBinder peekService(Context p0, Intent p1){ return null; } + public abstract void onReceive(Context p0, Intent p1); + public final BroadcastReceiver.PendingResult goAsync(){ return null; } + public final Bundle getResultExtras(boolean p0){ return null; } + public final String getResultData(){ return null; } + public final boolean getAbortBroadcast(){ return false; } + public final boolean getDebugUnregister(){ return false; } + public final boolean isInitialStickyBroadcast(){ return false; } + public final boolean isOrderedBroadcast(){ return false; } + public final int getResultCode(){ return 0; } + public final void abortBroadcast(){} + public final void clearAbortBroadcast(){} + public final void setDebugUnregister(boolean p0){} + public final void setOrderedHint(boolean p0){} + public final void setResult(int p0, String p1, Bundle p2){} + public final void setResultCode(int p0){} + public final void setResultData(String p0){} + public final void setResultExtras(Bundle p0){} + static public class PendingResult + { + public final Bundle getResultExtras(boolean p0){ return null; } + public final String getResultData(){ return null; } + public final boolean getAbortBroadcast(){ return false; } + public final int getResultCode(){ return 0; } + public final void abortBroadcast(){} + public final void clearAbortBroadcast(){} + public final void finish(){} + public final void setResult(int p0, String p1, Bundle p2){} + public final void setResultCode(int p0){} + public final void setResultData(String p0){} + public final void setResultExtras(Bundle p0){} } - /** - * This method is called when the BroadcastReceiver is receiving an Intent - * broadcast. During this time you can use the other methods on - * BroadcastReceiver to view/modify the current result values. This method - * is always called within the main thread of its process, unless you - * explicitly asked for it to be scheduled on a different thread using - * {@link android.content.Context#registerReceiver(BroadcastReceiver, - * IntentFilter, String, android.os.Handler)}. When it runs on the main - * thread you should - * never perform long-running operations in it (there is a timeout of - * 10 seconds that the system allows before considering the receiver to - * be blocked and a candidate to be killed). You cannot launch a popup dialog - * in your implementation of onReceive(). - * - *

    If this BroadcastReceiver was launched through a <receiver> tag, - * then the object is no longer alive after returning from this - * function. This means you should not perform any operations that - * return a result to you asynchronously -- in particular, for interacting - * with services, you should use - * {@link Context#startService(Intent)} instead of - * {@link Context#bindService(Intent, ServiceConnection, int)}. If you wish - * to interact with a service that is already running, you can use - * {@link #peekService}. - * - *

    The Intent filters used in {@link android.content.Context#registerReceiver} - * and in application manifests are not guaranteed to be exclusive. They - * are hints to the operating system about how to find suitable recipients. It is - * possible for senders to force delivery to specific recipients, bypassing filter - * resolution. For this reason, {@link #onReceive(Context, Intent) onReceive()} - * implementations should respond only to known actions, ignoring any unexpected - * Intents that they may receive. - * - * @param context The Context in which the receiver is running. - * @param intent The Intent being received. - */ - public abstract void onReceive(Context context, Intent intent); -} \ No newline at end of file +} diff --git a/java/ql/test/stubs/android/android/content/ClipData.java b/java/ql/test/stubs/android/android/content/ClipData.java new file mode 100644 index 00000000000..490aff3323a --- /dev/null +++ b/java/ql/test/stubs/android/android/content/ClipData.java @@ -0,0 +1,51 @@ +// Generated automatically from android.content.ClipData for testing purposes + +package android.content; + +import android.content.ClipDescription; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Parcel; +import android.os.Parcelable; + +public class ClipData implements Parcelable +{ + protected ClipData() {} + public ClipData(CharSequence p0, String[] p1, ClipData.Item p2){} + public ClipData(ClipData p0){} + public ClipData(ClipDescription p0, ClipData.Item p1){} + public ClipData.Item getItemAt(int p0){ return null; } + public ClipDescription getDescription(){ return null; } + public String toString(){ return null; } + public int describeContents(){ return 0; } + public int getItemCount(){ return 0; } + public static ClipData newHtmlText(CharSequence p0, CharSequence p1, String p2){ return null; } + public static ClipData newIntent(CharSequence p0, Intent p1){ return null; } + public static ClipData newPlainText(CharSequence p0, CharSequence p1){ return null; } + public static ClipData newRawUri(CharSequence p0, Uri p1){ return null; } + public static ClipData newUri(ContentResolver p0, CharSequence p1, Uri p2){ return null; } + public static Parcelable.Creator CREATOR = null; + public void addItem(ClipData.Item p0){} + public void addItem(ContentResolver p0, ClipData.Item p1){} + public void writeToParcel(Parcel p0, int p1){} + static public class Item + { + protected Item() {} + public CharSequence coerceToStyledText(Context p0){ return null; } + public CharSequence coerceToText(Context p0){ return null; } + public CharSequence getText(){ return null; } + public Intent getIntent(){ return null; } + public Item(CharSequence p0){} + public Item(CharSequence p0, Intent p1, Uri p2){} + public Item(CharSequence p0, String p1){} + public Item(CharSequence p0, String p1, Intent p2, Uri p3){} + public Item(Intent p0){} + public Item(Uri p0){} + public String coerceToHtmlText(Context p0){ return null; } + public String getHtmlText(){ return null; } + public String toString(){ return null; } + public Uri getUri(){ return null; } + } +} diff --git a/java/ql/test/stubs/android/android/content/ClipDescription.java b/java/ql/test/stubs/android/android/content/ClipDescription.java new file mode 100644 index 00000000000..34fe5a59715 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/ClipDescription.java @@ -0,0 +1,32 @@ +// Generated automatically from android.content.ClipDescription for testing purposes + +package android.content; + +import android.os.Parcel; +import android.os.Parcelable; +import android.os.PersistableBundle; + +public class ClipDescription implements Parcelable +{ + protected ClipDescription() {} + public CharSequence getLabel(){ return null; } + public ClipDescription(CharSequence p0, String[] p1){} + public ClipDescription(ClipDescription p0){} + public PersistableBundle getExtras(){ return null; } + public String getMimeType(int p0){ return null; } + public String toString(){ return null; } + public String[] filterMimeTypes(String p0){ return null; } + public boolean hasMimeType(String p0){ return false; } + public int describeContents(){ return 0; } + public int getMimeTypeCount(){ return 0; } + public long getTimestamp(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static String MIMETYPE_TEXT_HTML = null; + public static String MIMETYPE_TEXT_INTENT = null; + public static String MIMETYPE_TEXT_PLAIN = null; + public static String MIMETYPE_TEXT_URILIST = null; + public static String MIMETYPE_UNKNOWN = null; + public static boolean compareMimeTypes(String p0, String p1){ return false; } + public void setExtras(PersistableBundle p0){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/ComponentCallbacks.java b/java/ql/test/stubs/android/android/content/ComponentCallbacks.java new file mode 100644 index 00000000000..51726693d00 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/ComponentCallbacks.java @@ -0,0 +1,11 @@ +// Generated automatically from android.content.ComponentCallbacks for testing purposes + +package android.content; + +import android.content.res.Configuration; + +public interface ComponentCallbacks +{ + void onConfigurationChanged(Configuration p0); + void onLowMemory(); +} diff --git a/java/ql/test/stubs/android/android/content/ComponentCallbacks2.java b/java/ql/test/stubs/android/android/content/ComponentCallbacks2.java new file mode 100644 index 00000000000..f8c83ab104d --- /dev/null +++ b/java/ql/test/stubs/android/android/content/ComponentCallbacks2.java @@ -0,0 +1,17 @@ +// Generated automatically from android.content.ComponentCallbacks2 for testing purposes + +package android.content; + +import android.content.ComponentCallbacks; + +public interface ComponentCallbacks2 extends ComponentCallbacks +{ + static int TRIM_MEMORY_BACKGROUND = 0; + static int TRIM_MEMORY_COMPLETE = 0; + static int TRIM_MEMORY_MODERATE = 0; + static int TRIM_MEMORY_RUNNING_CRITICAL = 0; + static int TRIM_MEMORY_RUNNING_LOW = 0; + static int TRIM_MEMORY_RUNNING_MODERATE = 0; + static int TRIM_MEMORY_UI_HIDDEN = 0; + void onTrimMemory(int p0); +} diff --git a/java/ql/test/stubs/android/android/content/ComponentName.java b/java/ql/test/stubs/android/android/content/ComponentName.java new file mode 100644 index 00000000000..2c72a0a5125 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/ComponentName.java @@ -0,0 +1,35 @@ +// Generated automatically from android.content.ComponentName for testing purposes + +package android.content; + +import android.content.Context; +import android.os.Parcel; +import android.os.Parcelable; + +public class ComponentName implements Cloneable, Comparable, Parcelable +{ + protected ComponentName() {} + public ComponentName clone(){ return null; } + public ComponentName(Context p0, Class p1){} + public ComponentName(Context p0, String p1){} + public ComponentName(Parcel p0){} + public ComponentName(String p0, String p1){} + public String flattenToShortString(){ return null; } + public String flattenToString(){ return null; } + public String getClassName(){ return null; } + public String getPackageName(){ return null; } + public String getShortClassName(){ return null; } + public String toShortString(){ return null; } + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public int compareTo(ComponentName p0){ return 0; } + public int describeContents(){ return 0; } + public int hashCode(){ return 0; } + public static ComponentName createRelative(Context p0, String p1){ return null; } + public static ComponentName createRelative(String p0, String p1){ return null; } + public static ComponentName readFromParcel(Parcel p0){ return null; } + public static ComponentName unflattenFromString(String p0){ return null; } + public static Parcelable.Creator CREATOR = null; + public static void writeToParcel(ComponentName p0, Parcel p1){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/ContentProvider.java b/java/ql/test/stubs/android/android/content/ContentProvider.java index dfbd61f2ae6..d0928e0e9d0 100644 --- a/java/ql/test/stubs/android/android/content/ContentProvider.java +++ b/java/ql/test/stubs/android/android/content/ContentProvider.java @@ -1,17 +1,82 @@ +// Generated automatically from android.content.ContentProvider for testing purposes + package android.content; +import android.content.ComponentCallbacks2; +import android.content.ContentProviderOperation; +import android.content.ContentProviderResult; +import android.content.ContentValues; +import android.content.Context; +import android.content.pm.PathPermission; +import android.content.pm.ProviderInfo; +import android.content.res.AssetFileDescriptor; +import android.content.res.Configuration; import android.database.Cursor; import android.net.Uri; +import android.os.Bundle; import android.os.CancellationSignal; +import android.os.ParcelFileDescriptor; +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.ArrayList; -public abstract class ContentProvider { - public abstract int delete(Uri uri, String selection, String[] selectionArgs); - - public abstract Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, - CancellationSignal cancellationSignal); - - public abstract Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder); - - public abstract int update(Uri uri, ContentValues values, String selection, String[] selectionArgs); - +abstract public class ContentProvider implements ComponentCallbacks2 +{ + protected boolean isTemporary(){ return false; } + protected final ParcelFileDescriptor openFileHelper(Uri p0, String p1){ return null; } + protected final void setPathPermissions(PathPermission[] p0){} + protected final void setReadPermission(String p0){} + protected final void setWritePermission(String p0){} + public ParcelFileDescriptor openPipeHelper(Uri p0, String p1, Bundle p2, T p3, ContentProvider.PipeDataWriter p4){ return null; } + public AssetFileDescriptor openAssetFile(Uri p0, String p1){ return null; } + public AssetFileDescriptor openAssetFile(Uri p0, String p1, CancellationSignal p2){ return null; } + public AssetFileDescriptor openTypedAssetFile(Uri p0, String p1, Bundle p2){ return null; } + public AssetFileDescriptor openTypedAssetFile(Uri p0, String p1, Bundle p2, CancellationSignal p3){ return null; } + public Bundle call(String p0, String p1, Bundle p2){ return null; } + public Bundle call(String p0, String p1, String p2, Bundle p3){ return null; } + public ContentProvider(){} + public ContentProviderResult[] applyBatch(ArrayList p0){ return null; } + public ContentProviderResult[] applyBatch(String p0, ArrayList p1){ return null; } + public Cursor query(Uri p0, String[] p1, Bundle p2, CancellationSignal p3){ return null; } + public Cursor query(Uri p0, String[] p1, String p2, String[] p3, String p4, CancellationSignal p5){ return null; } + public ParcelFileDescriptor openFile(Uri p0, String p1){ return null; } + public ParcelFileDescriptor openFile(Uri p0, String p1, CancellationSignal p2){ return null; } + public String[] getStreamTypes(Uri p0, String p1){ return null; } + public Uri canonicalize(Uri p0){ return null; } + public Uri insert(Uri p0, ContentValues p1, Bundle p2){ return null; } + public Uri uncanonicalize(Uri p0){ return null; } + public abstract Cursor query(Uri p0, String[] p1, String p2, String[] p3, String p4); + public abstract String getType(Uri p0); + public abstract Uri insert(Uri p0, ContentValues p1); + public abstract boolean onCreate(); + public abstract int delete(Uri p0, String p1, String[] p2); + public abstract int update(Uri p0, ContentValues p1, String p2, String[] p3); + public boolean refresh(Uri p0, Bundle p1, CancellationSignal p2){ return false; } + public class CallingIdentity + { + } + public final ContentProvider.CallingIdentity clearCallingIdentity(){ return null; } + public final Context getContext(){ return null; } + public final Context requireContext(){ return null; } + public final PathPermission[] getPathPermissions(){ return null; } + public final String getCallingAttributionTag(){ return null; } + public final String getCallingPackage(){ return null; } + public final String getCallingPackageUnchecked(){ return null; } + public final String getReadPermission(){ return null; } + public final String getWritePermission(){ return null; } + public final void restoreCallingIdentity(ContentProvider.CallingIdentity p0){} + public int bulkInsert(Uri p0, ContentValues[] p1){ return 0; } + public int delete(Uri p0, Bundle p1){ return 0; } + public int update(Uri p0, ContentValues p1, Bundle p2){ return 0; } + public void attachInfo(Context p0, ProviderInfo p1){} + public void dump(FileDescriptor p0, PrintWriter p1, String[] p2){} + public void onCallingPackageChanged(){} + public void onConfigurationChanged(Configuration p0){} + public void onLowMemory(){} + public void onTrimMemory(int p0){} + public void shutdown(){} + static public interface PipeDataWriter + { + void writeDataToPipe(ParcelFileDescriptor p0, Uri p1, String p2, Bundle p3, T p4); + } } diff --git a/java/ql/test/stubs/android/android/content/ContentProviderClient.java b/java/ql/test/stubs/android/android/content/ContentProviderClient.java new file mode 100644 index 00000000000..0cb6890ad1b --- /dev/null +++ b/java/ql/test/stubs/android/android/content/ContentProviderClient.java @@ -0,0 +1,49 @@ +// Generated automatically from android.content.ContentProviderClient for testing purposes + +package android.content; + +import android.content.ContentProvider; +import android.content.ContentProviderOperation; +import android.content.ContentProviderResult; +import android.content.ContentValues; +import android.content.res.AssetFileDescriptor; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.os.CancellationSignal; +import android.os.ParcelFileDescriptor; +import java.util.ArrayList; + +public class ContentProviderClient implements AutoCloseable +{ + protected void finalize(){} + public AssetFileDescriptor openAssetFile(Uri p0, String p1){ return null; } + public AssetFileDescriptor openAssetFile(Uri p0, String p1, CancellationSignal p2){ return null; } + public Bundle call(String p0, String p1, Bundle p2){ return null; } + public Bundle call(String p0, String p1, String p2, Bundle p3){ return null; } + public ContentProvider getLocalContentProvider(){ return null; } + public ContentProviderResult[] applyBatch(ArrayList p0){ return null; } + public ContentProviderResult[] applyBatch(String p0, ArrayList p1){ return null; } + public Cursor query(Uri p0, String[] p1, Bundle p2, CancellationSignal p3){ return null; } + public Cursor query(Uri p0, String[] p1, String p2, String[] p3, String p4){ return null; } + public Cursor query(Uri p0, String[] p1, String p2, String[] p3, String p4, CancellationSignal p5){ return null; } + public ParcelFileDescriptor openFile(Uri p0, String p1){ return null; } + public ParcelFileDescriptor openFile(Uri p0, String p1, CancellationSignal p2){ return null; } + public String getType(Uri p0){ return null; } + public String[] getStreamTypes(Uri p0, String p1){ return null; } + public Uri insert(Uri p0, ContentValues p1){ return null; } + public Uri insert(Uri p0, ContentValues p1, Bundle p2){ return null; } + public boolean refresh(Uri p0, Bundle p1, CancellationSignal p2){ return false; } + public boolean release(){ return false; } + public final AssetFileDescriptor openTypedAssetFile(Uri p0, String p1, Bundle p2, CancellationSignal p3){ return null; } + public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri p0, String p1, Bundle p2){ return null; } + public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri p0, String p1, Bundle p2, CancellationSignal p3){ return null; } + public final Uri canonicalize(Uri p0){ return null; } + public final Uri uncanonicalize(Uri p0){ return null; } + public int bulkInsert(Uri p0, ContentValues[] p1){ return 0; } + public int delete(Uri p0, Bundle p1){ return 0; } + public int delete(Uri p0, String p1, String[] p2){ return 0; } + public int update(Uri p0, ContentValues p1, Bundle p2){ return 0; } + public int update(Uri p0, ContentValues p1, String p2, String[] p3){ return 0; } + public void close(){} +} diff --git a/java/ql/test/stubs/android/android/content/ContentProviderOperation.java b/java/ql/test/stubs/android/android/content/ContentProviderOperation.java new file mode 100644 index 00000000000..59fb8b366ca --- /dev/null +++ b/java/ql/test/stubs/android/android/content/ContentProviderOperation.java @@ -0,0 +1,58 @@ +// Generated automatically from android.content.ContentProviderOperation for testing purposes + +package android.content; + +import android.content.ContentProvider; +import android.content.ContentProviderResult; +import android.content.ContentValues; +import android.net.Uri; +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; + +public class ContentProviderOperation implements Parcelable +{ + public Bundle resolveExtrasBackReferences(ContentProviderResult[] p0, int p1){ return null; } + public ContentProviderResult apply(ContentProvider p0, ContentProviderResult[] p1, int p2){ return null; } + public ContentValues resolveValueBackReferences(ContentProviderResult[] p0, int p1){ return null; } + public String toString(){ return null; } + public String[] resolveSelectionArgsBackReferences(ContentProviderResult[] p0, int p1){ return null; } + public Uri getUri(){ return null; } + public boolean isAssertQuery(){ return false; } + public boolean isCall(){ return false; } + public boolean isDelete(){ return false; } + public boolean isExceptionAllowed(){ return false; } + public boolean isInsert(){ return false; } + public boolean isReadOperation(){ return false; } + public boolean isUpdate(){ return false; } + public boolean isWriteOperation(){ return false; } + public boolean isYieldAllowed(){ return false; } + public int describeContents(){ return 0; } + public static ContentProviderOperation.Builder newAssertQuery(Uri p0){ return null; } + public static ContentProviderOperation.Builder newCall(Uri p0, String p1, String p2){ return null; } + public static ContentProviderOperation.Builder newDelete(Uri p0){ return null; } + public static ContentProviderOperation.Builder newInsert(Uri p0){ return null; } + public static ContentProviderOperation.Builder newUpdate(Uri p0){ return null; } + public static Parcelable.Creator CREATOR = null; + public void writeToParcel(Parcel p0, int p1){} + static public class Builder + { + protected Builder() {} + public ContentProviderOperation build(){ return null; } + public ContentProviderOperation.Builder withExceptionAllowed(boolean p0){ return null; } + public ContentProviderOperation.Builder withExpectedCount(int p0){ return null; } + public ContentProviderOperation.Builder withExtra(String p0, Object p1){ return null; } + public ContentProviderOperation.Builder withExtraBackReference(String p0, int p1){ return null; } + public ContentProviderOperation.Builder withExtraBackReference(String p0, int p1, String p2){ return null; } + public ContentProviderOperation.Builder withExtras(Bundle p0){ return null; } + public ContentProviderOperation.Builder withSelection(String p0, String[] p1){ return null; } + public ContentProviderOperation.Builder withSelectionBackReference(int p0, int p1){ return null; } + public ContentProviderOperation.Builder withSelectionBackReference(int p0, int p1, String p2){ return null; } + public ContentProviderOperation.Builder withValue(String p0, Object p1){ return null; } + public ContentProviderOperation.Builder withValueBackReference(String p0, int p1){ return null; } + public ContentProviderOperation.Builder withValueBackReference(String p0, int p1, String p2){ return null; } + public ContentProviderOperation.Builder withValueBackReferences(ContentValues p0){ return null; } + public ContentProviderOperation.Builder withValues(ContentValues p0){ return null; } + public ContentProviderOperation.Builder withYieldAllowed(boolean p0){ return null; } + } +} diff --git a/java/ql/test/stubs/android/android/content/ContentProviderResult.java b/java/ql/test/stubs/android/android/content/ContentProviderResult.java new file mode 100644 index 00000000000..b0f285d5c92 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/ContentProviderResult.java @@ -0,0 +1,26 @@ +// Generated automatically from android.content.ContentProviderResult for testing purposes + +package android.content; + +import android.net.Uri; +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; + +public class ContentProviderResult implements Parcelable +{ + protected ContentProviderResult() {} + public ContentProviderResult(Bundle p0){} + public ContentProviderResult(Parcel p0){} + public ContentProviderResult(Throwable p0){} + public ContentProviderResult(Uri p0){} + public ContentProviderResult(int p0){} + public String toString(){ return null; } + public final Bundle extras = null; + public final Integer count = null; + public final Throwable exception = null; + public final Uri uri = null; + public int describeContents(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/ContentResolver.java b/java/ql/test/stubs/android/android/content/ContentResolver.java index 27308ee87be..1d03e20ecf9 100644 --- a/java/ql/test/stubs/android/android/content/ContentResolver.java +++ b/java/ql/test/stubs/android/android/content/ContentResolver.java @@ -1,17 +1,160 @@ +// Generated automatically from android.content.ContentResolver for testing purposes + package android.content; +import android.accounts.Account; +import android.content.ContentProvider; +import android.content.ContentProviderClient; +import android.content.ContentProviderOperation; +import android.content.ContentProviderResult; +import android.content.ContentValues; +import android.content.Context; +import android.content.PeriodicSync; +import android.content.SyncAdapterType; +import android.content.SyncInfo; +import android.content.SyncRequest; +import android.content.SyncStatusObserver; +import android.content.UriPermission; +import android.content.res.AssetFileDescriptor; +import android.database.ContentObserver; import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.drawable.Icon; import android.net.Uri; +import android.os.Bundle; import android.os.CancellationSignal; +import android.os.ParcelFileDescriptor; +import android.util.Size; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; -public abstract class ContentResolver { - public abstract int delete(Uri uri, String selection, String[] selectionArgs); - - public abstract Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, - CancellationSignal cancellationSignal); - - public abstract Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder); - - public abstract int update(Uri uri, ContentValues values, String selection, String[] selectionArgs); - +abstract public class ContentResolver +{ + protected ContentResolver() {} + public Bitmap loadThumbnail(Uri p0, Size p1, CancellationSignal p2){ return null; } + public ContentProviderResult[] applyBatch(String p0, ArrayList p1){ return null; } + public ContentResolver(Context p0){} + public List getOutgoingPersistedUriPermissions(){ return null; } + public List getPersistedUriPermissions(){ return null; } + public String[] getStreamTypes(Uri p0, String p1){ return null; } + public final AssetFileDescriptor openAssetFile(Uri p0, String p1, CancellationSignal p2){ return null; } + public final AssetFileDescriptor openAssetFileDescriptor(Uri p0, String p1){ return null; } + public final AssetFileDescriptor openAssetFileDescriptor(Uri p0, String p1, CancellationSignal p2){ return null; } + public final AssetFileDescriptor openTypedAssetFile(Uri p0, String p1, Bundle p2, CancellationSignal p3){ return null; } + public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri p0, String p1, Bundle p2){ return null; } + public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri p0, String p1, Bundle p2, CancellationSignal p3){ return null; } + public final Bundle call(String p0, String p1, String p2, Bundle p3){ return null; } + public final Bundle call(Uri p0, String p1, String p2, Bundle p3){ return null; } + public final ContentProviderClient acquireContentProviderClient(String p0){ return null; } + public final ContentProviderClient acquireContentProviderClient(Uri p0){ return null; } + public final ContentProviderClient acquireUnstableContentProviderClient(String p0){ return null; } + public final ContentProviderClient acquireUnstableContentProviderClient(Uri p0){ return null; } + public final ContentResolver.MimeTypeInfo getTypeInfo(String p0){ return null; } + public final Cursor query(Uri p0, String[] p1, Bundle p2, CancellationSignal p3){ return null; } + public final Cursor query(Uri p0, String[] p1, String p2, String[] p3, String p4){ return null; } + public final Cursor query(Uri p0, String[] p1, String p2, String[] p3, String p4, CancellationSignal p5){ return null; } + public final InputStream openInputStream(Uri p0){ return null; } + public final OutputStream openOutputStream(Uri p0){ return null; } + public final OutputStream openOutputStream(Uri p0, String p1){ return null; } + public final ParcelFileDescriptor openFile(Uri p0, String p1, CancellationSignal p2){ return null; } + public final ParcelFileDescriptor openFileDescriptor(Uri p0, String p1){ return null; } + public final ParcelFileDescriptor openFileDescriptor(Uri p0, String p1, CancellationSignal p2){ return null; } + public final String getType(Uri p0){ return null; } + public final Uri canonicalize(Uri p0){ return null; } + public final Uri insert(Uri p0, ContentValues p1){ return null; } + public final Uri insert(Uri p0, ContentValues p1, Bundle p2){ return null; } + public final Uri uncanonicalize(Uri p0){ return null; } + public final boolean refresh(Uri p0, Bundle p1, CancellationSignal p2){ return false; } + public final int bulkInsert(Uri p0, ContentValues[] p1){ return 0; } + public final int delete(Uri p0, Bundle p1){ return 0; } + public final int delete(Uri p0, String p1, String[] p2){ return 0; } + public final int update(Uri p0, ContentValues p1, Bundle p2){ return 0; } + public final int update(Uri p0, ContentValues p1, String p2, String[] p3){ return 0; } + public final void registerContentObserver(Uri p0, boolean p1, ContentObserver p2){} + public final void unregisterContentObserver(ContentObserver p0){} + public static ContentResolver wrap(ContentProvider p0){ return null; } + public static ContentResolver wrap(ContentProviderClient p0){ return null; } + public static List getPeriodicSyncs(Account p0, String p1){ return null; } + public static List getCurrentSyncs(){ return null; } + public static Object addStatusChangeListener(int p0, SyncStatusObserver p1){ return null; } + public static String ANY_CURSOR_ITEM_TYPE = null; + public static String CURSOR_DIR_BASE_TYPE = null; + public static String CURSOR_ITEM_BASE_TYPE = null; + public static String EXTRA_HONORED_ARGS = null; + public static String EXTRA_REFRESH_SUPPORTED = null; + public static String EXTRA_SIZE = null; + public static String EXTRA_TOTAL_COUNT = null; + public static String QUERY_ARG_GROUP_COLUMNS = null; + public static String QUERY_ARG_LIMIT = null; + public static String QUERY_ARG_OFFSET = null; + public static String QUERY_ARG_SORT_COLLATION = null; + public static String QUERY_ARG_SORT_COLUMNS = null; + public static String QUERY_ARG_SORT_DIRECTION = null; + public static String QUERY_ARG_SORT_LOCALE = null; + public static String QUERY_ARG_SQL_GROUP_BY = null; + public static String QUERY_ARG_SQL_HAVING = null; + public static String QUERY_ARG_SQL_LIMIT = null; + public static String QUERY_ARG_SQL_SELECTION = null; + public static String QUERY_ARG_SQL_SELECTION_ARGS = null; + public static String QUERY_ARG_SQL_SORT_ORDER = null; + public static String SCHEME_ANDROID_RESOURCE = null; + public static String SCHEME_CONTENT = null; + public static String SCHEME_FILE = null; + public static String SYNC_EXTRAS_ACCOUNT = null; + public static String SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS = null; + public static String SYNC_EXTRAS_DO_NOT_RETRY = null; + public static String SYNC_EXTRAS_EXPEDITED = null; + public static String SYNC_EXTRAS_FORCE = null; + public static String SYNC_EXTRAS_IGNORE_BACKOFF = null; + public static String SYNC_EXTRAS_IGNORE_SETTINGS = null; + public static String SYNC_EXTRAS_INITIALIZE = null; + public static String SYNC_EXTRAS_MANUAL = null; + public static String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS = null; + public static String SYNC_EXTRAS_REQUIRE_CHARGING = null; + public static String SYNC_EXTRAS_UPLOAD = null; + public static SyncAdapterType[] getSyncAdapterTypes(){ return null; } + public static SyncInfo getCurrentSync(){ return null; } + public static boolean getMasterSyncAutomatically(){ return false; } + public static boolean getSyncAutomatically(Account p0, String p1){ return false; } + public static boolean isSyncActive(Account p0, String p1){ return false; } + public static boolean isSyncPending(Account p0, String p1){ return false; } + public static int NOTIFY_DELETE = 0; + public static int NOTIFY_INSERT = 0; + public static int NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS = 0; + public static int NOTIFY_SYNC_TO_NETWORK = 0; + public static int NOTIFY_UPDATE = 0; + public static int QUERY_SORT_DIRECTION_ASCENDING = 0; + public static int QUERY_SORT_DIRECTION_DESCENDING = 0; + public static int SYNC_OBSERVER_TYPE_ACTIVE = 0; + public static int SYNC_OBSERVER_TYPE_PENDING = 0; + public static int SYNC_OBSERVER_TYPE_SETTINGS = 0; + public static int getIsSyncable(Account p0, String p1){ return 0; } + public static void addPeriodicSync(Account p0, String p1, Bundle p2, long p3){} + public static void cancelSync(Account p0, String p1){} + public static void cancelSync(SyncRequest p0){} + public static void removePeriodicSync(Account p0, String p1, Bundle p2){} + public static void removeStatusChangeListener(Object p0){} + public static void requestSync(Account p0, String p1, Bundle p2){} + public static void requestSync(SyncRequest p0){} + public static void setIsSyncable(Account p0, String p1, int p2){} + public static void setMasterSyncAutomatically(boolean p0){} + public static void setSyncAutomatically(Account p0, String p1, boolean p2){} + public static void validateSyncExtrasBundle(Bundle p0){} + public void cancelSync(Uri p0){} + public void notifyChange(Collection p0, ContentObserver p1, int p2){} + public void notifyChange(Uri p0, ContentObserver p1){} + public void notifyChange(Uri p0, ContentObserver p1, boolean p2){} + public void notifyChange(Uri p0, ContentObserver p1, int p2){} + public void releasePersistableUriPermission(Uri p0, int p1){} + public void startSync(Uri p0, Bundle p1){} + public void takePersistableUriPermission(Uri p0, int p1){} + static public class MimeTypeInfo + { + public CharSequence getContentDescription(){ return null; } + public CharSequence getLabel(){ return null; } + public Icon getIcon(){ return null; } + } } diff --git a/java/ql/test/stubs/android/android/content/ContentValues.java b/java/ql/test/stubs/android/android/content/ContentValues.java index 105c3092d79..f85e1462717 100644 --- a/java/ql/test/stubs/android/android/content/ContentValues.java +++ b/java/ql/test/stubs/android/android/content/ContentValues.java @@ -1,5 +1,50 @@ +// Generated automatically from android.content.ContentValues for testing purposes + package android.content; -public class ContentValues { +import android.os.Parcel; +import android.os.Parcelable; +import java.util.Map; +import java.util.Set; +public class ContentValues implements Parcelable +{ + public Boolean getAsBoolean(String p0){ return null; } + public Byte getAsByte(String p0){ return null; } + public ContentValues(){} + public ContentValues(ContentValues p0){} + public ContentValues(int p0){} + public Double getAsDouble(String p0){ return null; } + public Float getAsFloat(String p0){ return null; } + public Integer getAsInteger(String p0){ return null; } + public Long getAsLong(String p0){ return null; } + public Object get(String p0){ return null; } + public Set> valueSet(){ return null; } + public Set keySet(){ return null; } + public Short getAsShort(String p0){ return null; } + public String getAsString(String p0){ return null; } + public String toString(){ return null; } + public boolean containsKey(String p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public byte[] getAsByteArray(String p0){ return null; } + public int describeContents(){ return 0; } + public int hashCode(){ return 0; } + public int size(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static String TAG = null; + public void clear(){} + public void put(String p0, Boolean p1){} + public void put(String p0, Byte p1){} + public void put(String p0, Double p1){} + public void put(String p0, Float p1){} + public void put(String p0, Integer p1){} + public void put(String p0, Long p1){} + public void put(String p0, Short p1){} + public void put(String p0, String p1){} + public void put(String p0, byte[] p1){} + public void putAll(ContentValues p0){} + public void putNull(String p0){} + public void remove(String p0){} + public void writeToParcel(Parcel p0, int p1){} } diff --git a/java/ql/test/stubs/android/android/content/Context.java b/java/ql/test/stubs/android/android/content/Context.java index 118e170d788..7e507e89095 100644 --- a/java/ql/test/stubs/android/android/content/Context.java +++ b/java/ql/test/stubs/android/android/content/Context.java @@ -1,5 +1,265 @@ +// Generated automatically from android.content.Context for testing purposes + package android.content; -public class Context { +import android.content.BroadcastReceiver; +import android.content.ComponentCallbacks; +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.IntentSender; +import android.content.ServiceConnection; +import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.res.AssetManager; +import android.content.res.ColorStateList; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.database.DatabaseErrorHandler; +import android.database.sqlite.SQLiteDatabase; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.UserHandle; +import android.util.AttributeSet; +import android.view.Display; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.util.concurrent.Executor; +abstract public class Context +{ + public Context createAttributionContext(String p0){ return null; } + public Context createWindowContext(int p0, Bundle p1){ return null; } + public Context(){} + public Display getDisplay(){ return null; } + public Executor getMainExecutor(){ return null; } + public String getAttributionTag(){ return null; } + public String getOpPackageName(){ return null; } + public abstract ApplicationInfo getApplicationInfo(); + public abstract AssetManager getAssets(); + public abstract ClassLoader getClassLoader(); + public abstract ComponentName startForegroundService(Intent p0); + public abstract ComponentName startService(Intent p0); + public abstract ContentResolver getContentResolver(); + public abstract Context createConfigurationContext(Configuration p0); + public abstract Context createContextForSplit(String p0); + public abstract Context createDeviceProtectedStorageContext(); + public abstract Context createDisplayContext(Display p0); + public abstract Context createPackageContext(String p0, int p1); + public abstract Context getApplicationContext(); + public abstract Drawable getWallpaper(); + public abstract Drawable peekWallpaper(); + public abstract File getCacheDir(); + public abstract File getCodeCacheDir(); + public abstract File getDataDir(); + public abstract File getDatabasePath(String p0); + public abstract File getDir(String p0, int p1); + public abstract File getExternalCacheDir(); + public abstract File getExternalFilesDir(String p0); + public abstract File getFileStreamPath(String p0); + public abstract File getFilesDir(); + public abstract File getNoBackupFilesDir(); + public abstract File getObbDir(); + public abstract FileInputStream openFileInput(String p0); + public abstract FileOutputStream openFileOutput(String p0, int p1); + public abstract File[] getExternalCacheDirs(); + public abstract File[] getExternalFilesDirs(String p0); + public abstract File[] getExternalMediaDirs(); + public abstract File[] getObbDirs(); + public abstract Intent registerReceiver(BroadcastReceiver p0, IntentFilter p1); + public abstract Intent registerReceiver(BroadcastReceiver p0, IntentFilter p1, String p2, Handler p3); + public abstract Intent registerReceiver(BroadcastReceiver p0, IntentFilter p1, String p2, Handler p3, int p4); + public abstract Intent registerReceiver(BroadcastReceiver p0, IntentFilter p1, int p2); + public abstract Looper getMainLooper(); + public abstract Object getSystemService(String p0); + public abstract PackageManager getPackageManager(); + public abstract Resources getResources(); + public abstract Resources.Theme getTheme(); + public abstract SQLiteDatabase openOrCreateDatabase(String p0, int p1, SQLiteDatabase.CursorFactory p2); + public abstract SQLiteDatabase openOrCreateDatabase(String p0, int p1, SQLiteDatabase.CursorFactory p2, DatabaseErrorHandler p3); + public abstract SharedPreferences getSharedPreferences(String p0, int p1); + public abstract String getPackageCodePath(); + public abstract String getPackageName(); + public abstract String getPackageResourcePath(); + public abstract String getSystemServiceName(Class p0); + public abstract String[] databaseList(); + public abstract String[] fileList(); + public abstract boolean bindService(Intent p0, ServiceConnection p1, int p2); + public abstract boolean deleteDatabase(String p0); + public abstract boolean deleteFile(String p0); + public abstract boolean deleteSharedPreferences(String p0); + public abstract boolean isDeviceProtectedStorage(); + public abstract boolean moveDatabaseFrom(Context p0, String p1); + public abstract boolean moveSharedPreferencesFrom(Context p0, String p1); + public abstract boolean startInstrumentation(ComponentName p0, String p1, Bundle p2); + public abstract boolean stopService(Intent p0); + public abstract int checkCallingOrSelfPermission(String p0); + public abstract int checkCallingOrSelfUriPermission(Uri p0, int p1); + public abstract int checkCallingPermission(String p0); + public abstract int checkCallingUriPermission(Uri p0, int p1); + public abstract int checkPermission(String p0, int p1, int p2); + public abstract int checkSelfPermission(String p0); + public abstract int checkUriPermission(Uri p0, String p1, String p2, int p3, int p4, int p5); + public abstract int checkUriPermission(Uri p0, int p1, int p2, int p3); + public abstract int getWallpaperDesiredMinimumHeight(); + public abstract int getWallpaperDesiredMinimumWidth(); + public abstract void clearWallpaper(); + public abstract void enforceCallingOrSelfPermission(String p0, String p1); + public abstract void enforceCallingOrSelfUriPermission(Uri p0, int p1, String p2); + public abstract void enforceCallingPermission(String p0, String p1); + public abstract void enforceCallingUriPermission(Uri p0, int p1, String p2); + public abstract void enforcePermission(String p0, int p1, int p2, String p3); + public abstract void enforceUriPermission(Uri p0, String p1, String p2, int p3, int p4, int p5, String p6); + public abstract void enforceUriPermission(Uri p0, int p1, int p2, int p3, String p4); + public abstract void grantUriPermission(String p0, Uri p1, int p2); + public abstract void removeStickyBroadcast(Intent p0); + public abstract void removeStickyBroadcastAsUser(Intent p0, UserHandle p1); + public abstract void revokeUriPermission(String p0, Uri p1, int p2); + public abstract void revokeUriPermission(Uri p0, int p1); + public abstract void sendBroadcast(Intent p0); + public abstract void sendBroadcast(Intent p0, String p1); + public abstract void sendBroadcastAsUser(Intent p0, UserHandle p1); + public abstract void sendBroadcastAsUser(Intent p0, UserHandle p1, String p2); + public abstract void sendOrderedBroadcast(Intent p0, String p1); + public abstract void sendOrderedBroadcast(Intent p0, String p1, BroadcastReceiver p2, Handler p3, int p4, String p5, Bundle p6); + public abstract void sendOrderedBroadcastAsUser(Intent p0, UserHandle p1, String p2, BroadcastReceiver p3, Handler p4, int p5, String p6, Bundle p7); + public abstract void sendStickyBroadcast(Intent p0); + public abstract void sendStickyBroadcastAsUser(Intent p0, UserHandle p1); + public abstract void sendStickyOrderedBroadcast(Intent p0, BroadcastReceiver p1, Handler p2, int p3, String p4, Bundle p5); + public abstract void sendStickyOrderedBroadcastAsUser(Intent p0, UserHandle p1, BroadcastReceiver p2, Handler p3, int p4, String p5, Bundle p6); + public abstract void setTheme(int p0); + public abstract void setWallpaper(Bitmap p0); + public abstract void setWallpaper(InputStream p0); + public abstract void startActivities(Intent[] p0); + public abstract void startActivities(Intent[] p0, Bundle p1); + public abstract void startActivity(Intent p0); + public abstract void startActivity(Intent p0, Bundle p1); + public abstract void startIntentSender(IntentSender p0, Intent p1, int p2, int p3, int p4); + public abstract void startIntentSender(IntentSender p0, Intent p1, int p2, int p3, int p4, Bundle p5); + public abstract void unbindService(ServiceConnection p0); + public abstract void unregisterReceiver(BroadcastReceiver p0); + public boolean bindIsolatedService(Intent p0, int p1, String p2, Executor p3, ServiceConnection p4){ return false; } + public boolean bindService(Intent p0, int p1, Executor p2, ServiceConnection p3){ return false; } + public boolean bindServiceAsUser(Intent p0, ServiceConnection p1, int p2, UserHandle p3){ return false; } + public boolean isRestricted(){ return false; } + public final T getSystemService(Class p0){ return null; } + public final CharSequence getText(int p0){ return null; } + public final ColorStateList getColorStateList(int p0){ return null; } + public final Drawable getDrawable(int p0){ return null; } + public final String getString(int p0){ return null; } + public final String getString(int p0, Object... p1){ return null; } + public final TypedArray obtainStyledAttributes(AttributeSet p0, int[] p1){ return null; } + public final TypedArray obtainStyledAttributes(AttributeSet p0, int[] p1, int p2, int p3){ return null; } + public final TypedArray obtainStyledAttributes(int p0, int[] p1){ return null; } + public final TypedArray obtainStyledAttributes(int[] p0){ return null; } + public final int getColor(int p0){ return 0; } + public static String ACCESSIBILITY_SERVICE = null; + public static String ACCOUNT_SERVICE = null; + public static String ACTIVITY_SERVICE = null; + public static String ALARM_SERVICE = null; + public static String APPWIDGET_SERVICE = null; + public static String APP_OPS_SERVICE = null; + public static String AUDIO_SERVICE = null; + public static String BATTERY_SERVICE = null; + public static String BIOMETRIC_SERVICE = null; + public static String BLOB_STORE_SERVICE = null; + public static String BLUETOOTH_SERVICE = null; + public static String CAMERA_SERVICE = null; + public static String CAPTIONING_SERVICE = null; + public static String CARRIER_CONFIG_SERVICE = null; + public static String CLIPBOARD_SERVICE = null; + public static String COMPANION_DEVICE_SERVICE = null; + public static String CONNECTIVITY_DIAGNOSTICS_SERVICE = null; + public static String CONNECTIVITY_SERVICE = null; + public static String CONSUMER_IR_SERVICE = null; + public static String CROSS_PROFILE_APPS_SERVICE = null; + public static String DEVICE_POLICY_SERVICE = null; + public static String DISPLAY_SERVICE = null; + public static String DOWNLOAD_SERVICE = null; + public static String DROPBOX_SERVICE = null; + public static String EUICC_SERVICE = null; + public static String FILE_INTEGRITY_SERVICE = null; + public static String FINGERPRINT_SERVICE = null; + public static String HARDWARE_PROPERTIES_SERVICE = null; + public static String INPUT_METHOD_SERVICE = null; + public static String INPUT_SERVICE = null; + public static String IPSEC_SERVICE = null; + public static String JOB_SCHEDULER_SERVICE = null; + public static String KEYGUARD_SERVICE = null; + public static String LAUNCHER_APPS_SERVICE = null; + public static String LAYOUT_INFLATER_SERVICE = null; + public static String LOCATION_SERVICE = null; + public static String MEDIA_PROJECTION_SERVICE = null; + public static String MEDIA_ROUTER_SERVICE = null; + public static String MEDIA_SESSION_SERVICE = null; + public static String MIDI_SERVICE = null; + public static String NETWORK_STATS_SERVICE = null; + public static String NFC_SERVICE = null; + public static String NOTIFICATION_SERVICE = null; + public static String NSD_SERVICE = null; + public static String POWER_SERVICE = null; + public static String PRINT_SERVICE = null; + public static String RESTRICTIONS_SERVICE = null; + public static String ROLE_SERVICE = null; + public static String SEARCH_SERVICE = null; + public static String SENSOR_SERVICE = null; + public static String SHORTCUT_SERVICE = null; + public static String STORAGE_SERVICE = null; + public static String STORAGE_STATS_SERVICE = null; + public static String SYSTEM_HEALTH_SERVICE = null; + public static String TELECOM_SERVICE = null; + public static String TELEPHONY_IMS_SERVICE = null; + public static String TELEPHONY_SERVICE = null; + public static String TELEPHONY_SUBSCRIPTION_SERVICE = null; + public static String TEXT_CLASSIFICATION_SERVICE = null; + public static String TEXT_SERVICES_MANAGER_SERVICE = null; + public static String TV_INPUT_SERVICE = null; + public static String UI_MODE_SERVICE = null; + public static String USAGE_STATS_SERVICE = null; + public static String USB_SERVICE = null; + public static String USER_SERVICE = null; + public static String VIBRATOR_SERVICE = null; + public static String VPN_MANAGEMENT_SERVICE = null; + public static String WALLPAPER_SERVICE = null; + public static String WIFI_AWARE_SERVICE = null; + public static String WIFI_P2P_SERVICE = null; + public static String WIFI_RTT_RANGING_SERVICE = null; + public static String WIFI_SERVICE = null; + public static String WINDOW_SERVICE = null; + public static int BIND_ABOVE_CLIENT = 0; + public static int BIND_ADJUST_WITH_ACTIVITY = 0; + public static int BIND_ALLOW_OOM_MANAGEMENT = 0; + public static int BIND_AUTO_CREATE = 0; + public static int BIND_DEBUG_UNBIND = 0; + public static int BIND_EXTERNAL_SERVICE = 0; + public static int BIND_IMPORTANT = 0; + public static int BIND_INCLUDE_CAPABILITIES = 0; + public static int BIND_NOT_FOREGROUND = 0; + public static int BIND_NOT_PERCEPTIBLE = 0; + public static int BIND_WAIVE_PRIORITY = 0; + public static int CONTEXT_IGNORE_SECURITY = 0; + public static int CONTEXT_INCLUDE_CODE = 0; + public static int CONTEXT_RESTRICTED = 0; + public static int MODE_APPEND = 0; + public static int MODE_ENABLE_WRITE_AHEAD_LOGGING = 0; + public static int MODE_MULTI_PROCESS = 0; + public static int MODE_NO_LOCALIZED_COLLATORS = 0; + public static int MODE_PRIVATE = 0; + public static int MODE_WORLD_READABLE = 0; + public static int MODE_WORLD_WRITEABLE = 0; + public static int RECEIVER_VISIBLE_TO_INSTANT_APPS = 0; + public void registerComponentCallbacks(ComponentCallbacks p0){} + public void sendBroadcastWithMultiplePermissions(Intent p0, String[] p1){} + public void sendOrderedBroadcast(Intent p0, String p1, String p2, BroadcastReceiver p3, Handler p4, int p5, String p6, Bundle p7){} + public void unregisterComponentCallbacks(ComponentCallbacks p0){} + public void updateServiceGroup(ServiceConnection p0, int p1, int p2){} } diff --git a/java/ql/test/stubs/android/android/content/Intent.java b/java/ql/test/stubs/android/android/content/Intent.java index 32b167509d3..d3dd30a8fc4 100644 --- a/java/ql/test/stubs/android/android/content/Intent.java +++ b/java/ql/test/stubs/android/android/content/Intent.java @@ -1,196 +1,461 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Generated automatically from android.content.Intent for testing purposes package android.content; +import android.content.ClipData; +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.Context; +import android.content.IntentSender; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.graphics.Rect; import android.net.Uri; import android.os.Bundle; - -import java.io.PrintWriter; -import java.net.URISyntaxException; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.AttributeSet; +import java.io.Serializable; +import java.util.ArrayList; import java.util.Set; +import org.xmlpull.v1.XmlPullParser; -public class Intent implements Cloneable { - - public static Intent createChooser(Intent target, CharSequence title) { - return null; - } - - public Intent() { - } - - public Intent(Intent o) { - } - - @Override - public Object clone() { - return null; - } - - public Intent(String action) { - } - - public Intent(String action, Uri uri) { - } - - public Intent(Context packageContext, Class cls) { - } - - public Intent(String action, Uri uri, Context packageContext, Class cls) { - } - - public static Intent makeMainSelectorActivity(String selectorAction, String selectorCategory) { - return null; - } - - public static Intent getIntent(String uri) throws URISyntaxException { - return null; - } - - public static Intent getIntentOld(String uri) throws URISyntaxException { - return null; - } - - public static void printIntentArgsHelp(PrintWriter pw, String prefix) { - } - - public boolean hasCategory(String category) { - return false; - } - - public Set getCategories() { - return null; - } - - public int getContentUserHint() { - return 0; - } - - public String getLaunchToken() { - return null; - } - - public void setLaunchToken(String launchToken) { - } - - public boolean hasExtra(String name) { - return false; - } - - public boolean hasFileDescriptors() { - return false; - } - - public void setAllowFds(boolean allowFds) { - } - - public void setDefusable(boolean defusable) { - } - - public Object getExtra(String name) { - return null; - } - - public boolean getBooleanExtra(String name, boolean defaultValue) { - return false; - } - - public byte getByteExtra(String name, byte defaultValue) { - return 0; - } - - public short getShortExtra(String name, short defaultValue) { - return 0; - } - - public char getCharExtra(String name, char defaultValue) { - return '0'; - } - - public int getIntExtra(String name, int defaultValue) { - return 0; - } - - public long getLongExtra(String name, long defaultValue) { - return 0; - } - - public float getFloatExtra(String name, float defaultValue) { - return 0; - } - - public double getDoubleExtra(String name, double defaultValue) { - return 0; - } - - public String getStringExtra(String string) { - return null; - } - - public void removeUnsafeExtras() { - } - - public boolean canStripForHistory() { - return false; - } - - public Intent maybeStripForHistory() { - return null; - } - - public boolean isExcludingStopped() { - return false; - } - - public void removeCategory(String category) { - } - - public void prepareToLeaveUser(int userId) { - } - - public boolean filterEquals(Intent other) { - return false; - } - - public int filterHashCode() { - return 0; - } - - @Override - public String toString() { - return null; - } - - public String toInsecureString() { - return null; - } - - public String toInsecureStringWithClip() { - return null; - } - - public String toShortString(boolean secure, boolean comp, boolean extras, boolean clip) { - return null; - } - - public void toShortString(StringBuilder b, boolean secure, boolean comp, boolean extras, boolean clip) { - } - - public Bundle getExtras() { - return null; - } - +public class Intent implements Cloneable, Parcelable +{ + public ArrayList getParcelableArrayListExtra(String p0){ return null; } + public T getParcelableExtra(String p0){ return null; } + public ActivityInfo resolveActivityInfo(PackageManager p0, int p1){ return null; } + public ArrayList getCharSequenceArrayListExtra(String p0){ return null; } + public ArrayList getIntegerArrayListExtra(String p0){ return null; } + public ArrayList getStringArrayListExtra(String p0){ return null; } + public Bundle getBundleExtra(String p0){ return null; } + public Bundle getExtras(){ return null; } + public CharSequence getCharSequenceExtra(String p0){ return null; } + public CharSequence[] getCharSequenceArrayExtra(String p0){ return null; } + public ClipData getClipData(){ return null; } + public ComponentName getComponent(){ return null; } + public ComponentName resolveActivity(PackageManager p0){ return null; } + public Intent addCategory(String p0){ return null; } + public Intent addFlags(int p0){ return null; } + public Intent cloneFilter(){ return null; } + public Intent getSelector(){ return null; } + public Intent putCharSequenceArrayListExtra(String p0, ArrayList p1){ return null; } + public Intent putExtra(String p0, Bundle p1){ return null; } + public Intent putExtra(String p0, CharSequence p1){ return null; } + public Intent putExtra(String p0, CharSequence[] p1){ return null; } + public Intent putExtra(String p0, Parcelable p1){ return null; } + public Intent putExtra(String p0, Parcelable[] p1){ return null; } + public Intent putExtra(String p0, Serializable p1){ return null; } + public Intent putExtra(String p0, String p1){ return null; } + public Intent putExtra(String p0, String[] p1){ return null; } + public Intent putExtra(String p0, boolean p1){ return null; } + public Intent putExtra(String p0, boolean[] p1){ return null; } + public Intent putExtra(String p0, byte p1){ return null; } + public Intent putExtra(String p0, byte[] p1){ return null; } + public Intent putExtra(String p0, char p1){ return null; } + public Intent putExtra(String p0, char[] p1){ return null; } + public Intent putExtra(String p0, double p1){ return null; } + public Intent putExtra(String p0, double[] p1){ return null; } + public Intent putExtra(String p0, float p1){ return null; } + public Intent putExtra(String p0, float[] p1){ return null; } + public Intent putExtra(String p0, int p1){ return null; } + public Intent putExtra(String p0, int[] p1){ return null; } + public Intent putExtra(String p0, long p1){ return null; } + public Intent putExtra(String p0, long[] p1){ return null; } + public Intent putExtra(String p0, short p1){ return null; } + public Intent putExtra(String p0, short[] p1){ return null; } + public Intent putExtras(Bundle p0){ return null; } + public Intent putExtras(Intent p0){ return null; } + public Intent putIntegerArrayListExtra(String p0, ArrayList p1){ return null; } + public Intent putParcelableArrayListExtra(String p0, ArrayList p1){ return null; } + public Intent putStringArrayListExtra(String p0, ArrayList p1){ return null; } + public Intent replaceExtras(Bundle p0){ return null; } + public Intent replaceExtras(Intent p0){ return null; } + public Intent setAction(String p0){ return null; } + public Intent setClass(Context p0, Class p1){ return null; } + public Intent setClassName(Context p0, String p1){ return null; } + public Intent setClassName(String p0, String p1){ return null; } + public Intent setComponent(ComponentName p0){ return null; } + public Intent setData(Uri p0){ return null; } + public Intent setDataAndNormalize(Uri p0){ return null; } + public Intent setDataAndType(Uri p0, String p1){ return null; } + public Intent setDataAndTypeAndNormalize(Uri p0, String p1){ return null; } + public Intent setFlags(int p0){ return null; } + public Intent setIdentifier(String p0){ return null; } + public Intent setPackage(String p0){ return null; } + public Intent setType(String p0){ return null; } + public Intent setTypeAndNormalize(String p0){ return null; } + public Intent(){} + public Intent(Context p0, Class p1){} + public Intent(Intent p0){} + public Intent(String p0){} + public Intent(String p0, Uri p1){} + public Intent(String p0, Uri p1, Context p2, Class p3){} + public Object clone(){ return null; } + public Parcelable[] getParcelableArrayExtra(String p0){ return null; } + public Rect getSourceBounds(){ return null; } + public Serializable getSerializableExtra(String p0){ return null; } + public Set getCategories(){ return null; } + public String getAction(){ return null; } + public String getDataString(){ return null; } + public String getIdentifier(){ return null; } + public String getPackage(){ return null; } + public String getScheme(){ return null; } + public String getStringExtra(String p0){ return null; } + public String getType(){ return null; } + public String resolveType(ContentResolver p0){ return null; } + public String resolveType(Context p0){ return null; } + public String resolveTypeIfNeeded(ContentResolver p0){ return null; } + public String toString(){ return null; } + public String toURI(){ return null; } + public String toUri(int p0){ return null; } + public String[] getStringArrayExtra(String p0){ return null; } + public Uri getData(){ return null; } + public boolean filterEquals(Intent p0){ return false; } + public boolean getBooleanExtra(String p0, boolean p1){ return false; } + public boolean hasCategory(String p0){ return false; } + public boolean hasExtra(String p0){ return false; } + public boolean hasFileDescriptors(){ return false; } + public boolean[] getBooleanArrayExtra(String p0){ return null; } + public byte getByteExtra(String p0, byte p1){ return 0; } + public byte[] getByteArrayExtra(String p0){ return null; } + public char getCharExtra(String p0, char p1){ return '0'; } + public char[] getCharArrayExtra(String p0){ return null; } + public double getDoubleExtra(String p0, double p1){ return 0; } + public double[] getDoubleArrayExtra(String p0){ return null; } + public float getFloatExtra(String p0, float p1){ return 0; } + public float[] getFloatArrayExtra(String p0){ return null; } + public int describeContents(){ return 0; } + public int fillIn(Intent p0, int p1){ return 0; } + public int filterHashCode(){ return 0; } + public int getFlags(){ return 0; } + public int getIntExtra(String p0, int p1){ return 0; } + public int[] getIntArrayExtra(String p0){ return null; } + public long getLongExtra(String p0, long p1){ return 0; } + public long[] getLongArrayExtra(String p0){ return null; } + public short getShortExtra(String p0, short p1){ return 0; } + public short[] getShortArrayExtra(String p0){ return null; } + public static Intent createChooser(Intent p0, CharSequence p1){ return null; } + public static Intent createChooser(Intent p0, CharSequence p1, IntentSender p2){ return null; } + public static Intent getIntent(String p0){ return null; } + public static Intent getIntentOld(String p0){ return null; } + public static Intent makeMainActivity(ComponentName p0){ return null; } + public static Intent makeMainSelectorActivity(String p0, String p1){ return null; } + public static Intent makeRestartActivityTask(ComponentName p0){ return null; } + public static Intent parseIntent(Resources p0, XmlPullParser p1, AttributeSet p2){ return null; } + public static Intent parseUri(String p0, int p1){ return null; } + public static Parcelable.Creator CREATOR = null; + public static String ACTION_AIRPLANE_MODE_CHANGED = null; + public static String ACTION_ALL_APPS = null; + public static String ACTION_ANSWER = null; + public static String ACTION_APPLICATION_PREFERENCES = null; + public static String ACTION_APPLICATION_RESTRICTIONS_CHANGED = null; + public static String ACTION_APP_ERROR = null; + public static String ACTION_ASSIST = null; + public static String ACTION_ATTACH_DATA = null; + public static String ACTION_AUTO_REVOKE_PERMISSIONS = null; + public static String ACTION_BATTERY_CHANGED = null; + public static String ACTION_BATTERY_LOW = null; + public static String ACTION_BATTERY_OKAY = null; + public static String ACTION_BOOT_COMPLETED = null; + public static String ACTION_BUG_REPORT = null; + public static String ACTION_CALL = null; + public static String ACTION_CALL_BUTTON = null; + public static String ACTION_CAMERA_BUTTON = null; + public static String ACTION_CARRIER_SETUP = null; + public static String ACTION_CHOOSER = null; + public static String ACTION_CLOSE_SYSTEM_DIALOGS = null; + public static String ACTION_CONFIGURATION_CHANGED = null; + public static String ACTION_CREATE_DOCUMENT = null; + public static String ACTION_CREATE_REMINDER = null; + public static String ACTION_CREATE_SHORTCUT = null; + public static String ACTION_DATE_CHANGED = null; + public static String ACTION_DEFAULT = null; + public static String ACTION_DEFINE = null; + public static String ACTION_DELETE = null; + public static String ACTION_DEVICE_STORAGE_LOW = null; + public static String ACTION_DEVICE_STORAGE_OK = null; + public static String ACTION_DIAL = null; + public static String ACTION_DOCK_EVENT = null; + public static String ACTION_DREAMING_STARTED = null; + public static String ACTION_DREAMING_STOPPED = null; + public static String ACTION_EDIT = null; + public static String ACTION_EXTERNAL_APPLICATIONS_AVAILABLE = null; + public static String ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE = null; + public static String ACTION_FACTORY_TEST = null; + public static String ACTION_GET_CONTENT = null; + public static String ACTION_GET_RESTRICTION_ENTRIES = null; + public static String ACTION_GTALK_SERVICE_CONNECTED = null; + public static String ACTION_GTALK_SERVICE_DISCONNECTED = null; + public static String ACTION_HEADSET_PLUG = null; + public static String ACTION_INPUT_METHOD_CHANGED = null; + public static String ACTION_INSERT = null; + public static String ACTION_INSERT_OR_EDIT = null; + public static String ACTION_INSTALL_FAILURE = null; + public static String ACTION_INSTALL_PACKAGE = null; + public static String ACTION_LOCALE_CHANGED = null; + public static String ACTION_LOCKED_BOOT_COMPLETED = null; + public static String ACTION_MAIN = null; + public static String ACTION_MANAGED_PROFILE_ADDED = null; + public static String ACTION_MANAGED_PROFILE_AVAILABLE = null; + public static String ACTION_MANAGED_PROFILE_REMOVED = null; + public static String ACTION_MANAGED_PROFILE_UNAVAILABLE = null; + public static String ACTION_MANAGED_PROFILE_UNLOCKED = null; + public static String ACTION_MANAGE_NETWORK_USAGE = null; + public static String ACTION_MANAGE_PACKAGE_STORAGE = null; + public static String ACTION_MEDIA_BAD_REMOVAL = null; + public static String ACTION_MEDIA_BUTTON = null; + public static String ACTION_MEDIA_CHECKING = null; + public static String ACTION_MEDIA_EJECT = null; + public static String ACTION_MEDIA_MOUNTED = null; + public static String ACTION_MEDIA_NOFS = null; + public static String ACTION_MEDIA_REMOVED = null; + public static String ACTION_MEDIA_SCANNER_FINISHED = null; + public static String ACTION_MEDIA_SCANNER_SCAN_FILE = null; + public static String ACTION_MEDIA_SCANNER_STARTED = null; + public static String ACTION_MEDIA_SHARED = null; + public static String ACTION_MEDIA_UNMOUNTABLE = null; + public static String ACTION_MEDIA_UNMOUNTED = null; + public static String ACTION_MY_PACKAGE_REPLACED = null; + public static String ACTION_MY_PACKAGE_SUSPENDED = null; + public static String ACTION_MY_PACKAGE_UNSUSPENDED = null; + public static String ACTION_NEW_OUTGOING_CALL = null; + public static String ACTION_OPEN_DOCUMENT = null; + public static String ACTION_OPEN_DOCUMENT_TREE = null; + public static String ACTION_PACKAGES_SUSPENDED = null; + public static String ACTION_PACKAGES_UNSUSPENDED = null; + public static String ACTION_PACKAGE_ADDED = null; + public static String ACTION_PACKAGE_CHANGED = null; + public static String ACTION_PACKAGE_DATA_CLEARED = null; + public static String ACTION_PACKAGE_FIRST_LAUNCH = null; + public static String ACTION_PACKAGE_FULLY_REMOVED = null; + public static String ACTION_PACKAGE_INSTALL = null; + public static String ACTION_PACKAGE_NEEDS_VERIFICATION = null; + public static String ACTION_PACKAGE_REMOVED = null; + public static String ACTION_PACKAGE_REPLACED = null; + public static String ACTION_PACKAGE_RESTARTED = null; + public static String ACTION_PACKAGE_VERIFIED = null; + public static String ACTION_PASTE = null; + public static String ACTION_PICK = null; + public static String ACTION_PICK_ACTIVITY = null; + public static String ACTION_POWER_CONNECTED = null; + public static String ACTION_POWER_DISCONNECTED = null; + public static String ACTION_POWER_USAGE_SUMMARY = null; + public static String ACTION_PROCESS_TEXT = null; + public static String ACTION_PROVIDER_CHANGED = null; + public static String ACTION_QUICK_CLOCK = null; + public static String ACTION_QUICK_VIEW = null; + public static String ACTION_REBOOT = null; + public static String ACTION_RUN = null; + public static String ACTION_SCREEN_OFF = null; + public static String ACTION_SCREEN_ON = null; + public static String ACTION_SEARCH = null; + public static String ACTION_SEARCH_LONG_PRESS = null; + public static String ACTION_SEND = null; + public static String ACTION_SENDTO = null; + public static String ACTION_SEND_MULTIPLE = null; + public static String ACTION_SET_WALLPAPER = null; + public static String ACTION_SHOW_APP_INFO = null; + public static String ACTION_SHUTDOWN = null; + public static String ACTION_SYNC = null; + public static String ACTION_SYSTEM_TUTORIAL = null; + public static String ACTION_TIMEZONE_CHANGED = null; + public static String ACTION_TIME_CHANGED = null; + public static String ACTION_TIME_TICK = null; + public static String ACTION_TRANSLATE = null; + public static String ACTION_UID_REMOVED = null; + public static String ACTION_UMS_CONNECTED = null; + public static String ACTION_UMS_DISCONNECTED = null; + public static String ACTION_UNINSTALL_PACKAGE = null; + public static String ACTION_USER_BACKGROUND = null; + public static String ACTION_USER_FOREGROUND = null; + public static String ACTION_USER_INITIALIZE = null; + public static String ACTION_USER_PRESENT = null; + public static String ACTION_USER_UNLOCKED = null; + public static String ACTION_VIEW = null; + public static String ACTION_VIEW_LOCUS = null; + public static String ACTION_VIEW_PERMISSION_USAGE = null; + public static String ACTION_VOICE_COMMAND = null; + public static String ACTION_WALLPAPER_CHANGED = null; + public static String ACTION_WEB_SEARCH = null; + public static String CATEGORY_ACCESSIBILITY_SHORTCUT_TARGET = null; + public static String CATEGORY_ALTERNATIVE = null; + public static String CATEGORY_APP_BROWSER = null; + public static String CATEGORY_APP_CALCULATOR = null; + public static String CATEGORY_APP_CALENDAR = null; + public static String CATEGORY_APP_CONTACTS = null; + public static String CATEGORY_APP_EMAIL = null; + public static String CATEGORY_APP_FILES = null; + public static String CATEGORY_APP_GALLERY = null; + public static String CATEGORY_APP_MAPS = null; + public static String CATEGORY_APP_MARKET = null; + public static String CATEGORY_APP_MESSAGING = null; + public static String CATEGORY_APP_MUSIC = null; + public static String CATEGORY_BROWSABLE = null; + public static String CATEGORY_CAR_DOCK = null; + public static String CATEGORY_CAR_MODE = null; + public static String CATEGORY_DEFAULT = null; + public static String CATEGORY_DESK_DOCK = null; + public static String CATEGORY_DEVELOPMENT_PREFERENCE = null; + public static String CATEGORY_EMBED = null; + public static String CATEGORY_FRAMEWORK_INSTRUMENTATION_TEST = null; + public static String CATEGORY_HE_DESK_DOCK = null; + public static String CATEGORY_HOME = null; + public static String CATEGORY_INFO = null; + public static String CATEGORY_LAUNCHER = null; + public static String CATEGORY_LEANBACK_LAUNCHER = null; + public static String CATEGORY_LE_DESK_DOCK = null; + public static String CATEGORY_MONKEY = null; + public static String CATEGORY_OPENABLE = null; + public static String CATEGORY_PREFERENCE = null; + public static String CATEGORY_SAMPLE_CODE = null; + public static String CATEGORY_SECONDARY_HOME = null; + public static String CATEGORY_SELECTED_ALTERNATIVE = null; + public static String CATEGORY_TAB = null; + public static String CATEGORY_TEST = null; + public static String CATEGORY_TYPED_OPENABLE = null; + public static String CATEGORY_UNIT_TEST = null; + public static String CATEGORY_VOICE = null; + public static String CATEGORY_VR_HOME = null; + public static String EXTRA_ALARM_COUNT = null; + public static String EXTRA_ALLOW_MULTIPLE = null; + public static String EXTRA_ALLOW_REPLACE = null; + public static String EXTRA_ALTERNATE_INTENTS = null; + public static String EXTRA_ASSIST_CONTEXT = null; + public static String EXTRA_ASSIST_INPUT_DEVICE_ID = null; + public static String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = null; + public static String EXTRA_ASSIST_PACKAGE = null; + public static String EXTRA_ASSIST_UID = null; + public static String EXTRA_AUTO_LAUNCH_SINGLE_CHOICE = null; + public static String EXTRA_BCC = null; + public static String EXTRA_BUG_REPORT = null; + public static String EXTRA_CC = null; + public static String EXTRA_CHANGED_COMPONENT_NAME = null; + public static String EXTRA_CHANGED_COMPONENT_NAME_LIST = null; + public static String EXTRA_CHANGED_PACKAGE_LIST = null; + public static String EXTRA_CHANGED_UID_LIST = null; + public static String EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER = null; + public static String EXTRA_CHOOSER_TARGETS = null; + public static String EXTRA_CHOSEN_COMPONENT = null; + public static String EXTRA_CHOSEN_COMPONENT_INTENT_SENDER = null; + public static String EXTRA_COMPONENT_NAME = null; + public static String EXTRA_CONTENT_ANNOTATIONS = null; + public static String EXTRA_CONTENT_QUERY = null; + public static String EXTRA_DATA_REMOVED = null; + public static String EXTRA_DOCK_STATE = null; + public static String EXTRA_DONT_KILL_APP = null; + public static String EXTRA_DURATION_MILLIS = null; + public static String EXTRA_EMAIL = null; + public static String EXTRA_EXCLUDE_COMPONENTS = null; + public static String EXTRA_FROM_STORAGE = null; + public static String EXTRA_HTML_TEXT = null; + public static String EXTRA_INDEX = null; + public static String EXTRA_INITIAL_INTENTS = null; + public static String EXTRA_INSTALLER_PACKAGE_NAME = null; + public static String EXTRA_INTENT = null; + public static String EXTRA_KEY_EVENT = null; + public static String EXTRA_LOCAL_ONLY = null; + public static String EXTRA_LOCUS_ID = null; + public static String EXTRA_MIME_TYPES = null; + public static String EXTRA_NOT_UNKNOWN_SOURCE = null; + public static String EXTRA_ORIGINATING_URI = null; + public static String EXTRA_PACKAGE_NAME = null; + public static String EXTRA_PHONE_NUMBER = null; + public static String EXTRA_PROCESS_TEXT = null; + public static String EXTRA_PROCESS_TEXT_READONLY = null; + public static String EXTRA_QUICK_VIEW_FEATURES = null; + public static String EXTRA_QUIET_MODE = null; + public static String EXTRA_REFERRER = null; + public static String EXTRA_REFERRER_NAME = null; + public static String EXTRA_REMOTE_INTENT_TOKEN = null; + public static String EXTRA_REPLACEMENT_EXTRAS = null; + public static String EXTRA_REPLACING = null; + public static String EXTRA_RESTRICTIONS_BUNDLE = null; + public static String EXTRA_RESTRICTIONS_INTENT = null; + public static String EXTRA_RESTRICTIONS_LIST = null; + public static String EXTRA_RESULT_RECEIVER = null; + public static String EXTRA_RETURN_RESULT = null; + public static String EXTRA_SHORTCUT_ICON = null; + public static String EXTRA_SHORTCUT_ICON_RESOURCE = null; + public static String EXTRA_SHORTCUT_ID = null; + public static String EXTRA_SHORTCUT_INTENT = null; + public static String EXTRA_SHORTCUT_NAME = null; + public static String EXTRA_SHUTDOWN_USERSPACE_ONLY = null; + public static String EXTRA_SPLIT_NAME = null; + public static String EXTRA_STREAM = null; + public static String EXTRA_SUBJECT = null; + public static String EXTRA_SUSPENDED_PACKAGE_EXTRAS = null; + public static String EXTRA_TEMPLATE = null; + public static String EXTRA_TEXT = null; + public static String EXTRA_TIME = null; + public static String EXTRA_TIMEZONE = null; + public static String EXTRA_TITLE = null; + public static String EXTRA_UID = null; + public static String EXTRA_USER = null; + public static String METADATA_DOCK_HOME = null; + public static String normalizeMimeType(String p0){ return null; } + public static int EXTRA_DOCK_STATE_CAR = 0; + public static int EXTRA_DOCK_STATE_DESK = 0; + public static int EXTRA_DOCK_STATE_HE_DESK = 0; + public static int EXTRA_DOCK_STATE_LE_DESK = 0; + public static int EXTRA_DOCK_STATE_UNDOCKED = 0; + public static int FILL_IN_ACTION = 0; + public static int FILL_IN_CATEGORIES = 0; + public static int FILL_IN_CLIP_DATA = 0; + public static int FILL_IN_COMPONENT = 0; + public static int FILL_IN_DATA = 0; + public static int FILL_IN_IDENTIFIER = 0; + public static int FILL_IN_PACKAGE = 0; + public static int FILL_IN_SELECTOR = 0; + public static int FILL_IN_SOURCE_BOUNDS = 0; + public static int FLAG_ACTIVITY_BROUGHT_TO_FRONT = 0; + public static int FLAG_ACTIVITY_CLEAR_TASK = 0; + public static int FLAG_ACTIVITY_CLEAR_TOP = 0; + public static int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 0; + public static int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 0; + public static int FLAG_ACTIVITY_FORWARD_RESULT = 0; + public static int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 0; + public static int FLAG_ACTIVITY_LAUNCH_ADJACENT = 0; + public static int FLAG_ACTIVITY_MATCH_EXTERNAL = 0; + public static int FLAG_ACTIVITY_MULTIPLE_TASK = 0; + public static int FLAG_ACTIVITY_NEW_DOCUMENT = 0; + public static int FLAG_ACTIVITY_NEW_TASK = 0; + public static int FLAG_ACTIVITY_NO_ANIMATION = 0; + public static int FLAG_ACTIVITY_NO_HISTORY = 0; + public static int FLAG_ACTIVITY_NO_USER_ACTION = 0; + public static int FLAG_ACTIVITY_PREVIOUS_IS_TOP = 0; + public static int FLAG_ACTIVITY_REORDER_TO_FRONT = 0; + public static int FLAG_ACTIVITY_REQUIRE_DEFAULT = 0; + public static int FLAG_ACTIVITY_REQUIRE_NON_BROWSER = 0; + public static int FLAG_ACTIVITY_RESET_TASK_IF_NEEDED = 0; + public static int FLAG_ACTIVITY_RETAIN_IN_RECENTS = 0; + public static int FLAG_ACTIVITY_SINGLE_TOP = 0; + public static int FLAG_ACTIVITY_TASK_ON_HOME = 0; + public static int FLAG_DEBUG_LOG_RESOLUTION = 0; + public static int FLAG_DIRECT_BOOT_AUTO = 0; + public static int FLAG_EXCLUDE_STOPPED_PACKAGES = 0; + public static int FLAG_FROM_BACKGROUND = 0; + public static int FLAG_GRANT_PERSISTABLE_URI_PERMISSION = 0; + public static int FLAG_GRANT_PREFIX_URI_PERMISSION = 0; + public static int FLAG_GRANT_READ_URI_PERMISSION = 0; + public static int FLAG_GRANT_WRITE_URI_PERMISSION = 0; + public static int FLAG_INCLUDE_STOPPED_PACKAGES = 0; + public static int FLAG_RECEIVER_FOREGROUND = 0; + public static int FLAG_RECEIVER_NO_ABORT = 0; + public static int FLAG_RECEIVER_REGISTERED_ONLY = 0; + public static int FLAG_RECEIVER_REPLACE_PENDING = 0; + public static int FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS = 0; + public static int URI_ALLOW_UNSAFE = 0; + public static int URI_ANDROID_APP_SCHEME = 0; + public static int URI_INTENT_SCHEME = 0; + public void readFromParcel(Parcel p0){} + public void removeCategory(String p0){} + public void removeExtra(String p0){} + public void removeFlags(int p0){} + public void setClipData(ClipData p0){} + public void setExtrasClassLoader(ClassLoader p0){} + public void setSelector(Intent p0){} + public void setSourceBounds(Rect p0){} + public void writeToParcel(Parcel p0, int p1){} } diff --git a/java/ql/test/stubs/android/android/content/IntentFilter.java b/java/ql/test/stubs/android/android/content/IntentFilter.java new file mode 100644 index 00000000000..99de8481e14 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/IntentFilter.java @@ -0,0 +1,104 @@ +// Generated automatically from android.content.IntentFilter for testing purposes + +package android.content; + +import android.content.ContentResolver; +import android.content.Intent; +import android.net.Uri; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.PatternMatcher; +import android.util.AndroidException; +import android.util.Printer; +import java.util.Iterator; +import java.util.Set; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlSerializer; + +public class IntentFilter implements Parcelable +{ + public IntentFilter(){} + public IntentFilter(IntentFilter p0){} + public IntentFilter(String p0){} + public IntentFilter(String p0, String p1){} + public final IntentFilter.AuthorityEntry getDataAuthority(int p0){ return null; } + public final Iterator authoritiesIterator(){ return null; } + public final Iterator pathsIterator(){ return null; } + public final Iterator schemeSpecificPartsIterator(){ return null; } + public final Iterator actionsIterator(){ return null; } + public final Iterator categoriesIterator(){ return null; } + public final Iterator schemesIterator(){ return null; } + public final Iterator typesIterator(){ return null; } + public final PatternMatcher getDataPath(int p0){ return null; } + public final PatternMatcher getDataSchemeSpecificPart(int p0){ return null; } + public final String getAction(int p0){ return null; } + public final String getCategory(int p0){ return null; } + public final String getDataScheme(int p0){ return null; } + public final String getDataType(int p0){ return null; } + public final String matchCategories(Set p0){ return null; } + public final boolean hasAction(String p0){ return false; } + public final boolean hasCategory(String p0){ return false; } + public final boolean hasDataAuthority(Uri p0){ return false; } + public final boolean hasDataPath(String p0){ return false; } + public final boolean hasDataScheme(String p0){ return false; } + public final boolean hasDataSchemeSpecificPart(String p0){ return false; } + public final boolean hasDataType(String p0){ return false; } + public final boolean matchAction(String p0){ return false; } + public final int countActions(){ return 0; } + public final int countCategories(){ return 0; } + public final int countDataAuthorities(){ return 0; } + public final int countDataPaths(){ return 0; } + public final int countDataSchemeSpecificParts(){ return 0; } + public final int countDataSchemes(){ return 0; } + public final int countDataTypes(){ return 0; } + public final int describeContents(){ return 0; } + public final int getPriority(){ return 0; } + public final int match(ContentResolver p0, Intent p1, boolean p2, String p3){ return 0; } + public final int match(String p0, String p1, String p2, Uri p3, Set p4, String p5){ return 0; } + public final int matchData(String p0, String p1, Uri p2){ return 0; } + public final int matchDataAuthority(Uri p0){ return 0; } + public final void addAction(String p0){} + public final void addCategory(String p0){} + public final void addDataAuthority(String p0, String p1){} + public final void addDataPath(String p0, int p1){} + public final void addDataScheme(String p0){} + public final void addDataSchemeSpecificPart(String p0, int p1){} + public final void addDataType(String p0){} + public final void setPriority(int p0){} + public final void writeToParcel(Parcel p0, int p1){} + public static IntentFilter create(String p0, String p1){ return null; } + public static Parcelable.Creator CREATOR = null; + public static int MATCH_ADJUSTMENT_MASK = 0; + public static int MATCH_ADJUSTMENT_NORMAL = 0; + public static int MATCH_CATEGORY_EMPTY = 0; + public static int MATCH_CATEGORY_HOST = 0; + public static int MATCH_CATEGORY_MASK = 0; + public static int MATCH_CATEGORY_PATH = 0; + public static int MATCH_CATEGORY_PORT = 0; + public static int MATCH_CATEGORY_SCHEME = 0; + public static int MATCH_CATEGORY_SCHEME_SPECIFIC_PART = 0; + public static int MATCH_CATEGORY_TYPE = 0; + public static int NO_MATCH_ACTION = 0; + public static int NO_MATCH_CATEGORY = 0; + public static int NO_MATCH_DATA = 0; + public static int NO_MATCH_TYPE = 0; + public static int SYSTEM_HIGH_PRIORITY = 0; + public static int SYSTEM_LOW_PRIORITY = 0; + public void dump(Printer p0, String p1){} + public void readFromXml(XmlPullParser p0){} + public void writeToXml(XmlSerializer p0){} + static public class AuthorityEntry + { + protected AuthorityEntry() {} + public AuthorityEntry(String p0, String p1){} + public String getHost(){ return null; } + public boolean equals(Object p0){ return false; } + public int getPort(){ return 0; } + public int match(Uri p0){ return 0; } + } + static public class MalformedMimeTypeException extends AndroidException + { + public MalformedMimeTypeException(){} + public MalformedMimeTypeException(String p0){} + } +} diff --git a/java/ql/test/stubs/android/android/content/IntentSender.java b/java/ql/test/stubs/android/android/content/IntentSender.java new file mode 100644 index 00000000000..6008341e802 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/IntentSender.java @@ -0,0 +1,40 @@ +// Generated automatically from android.content.IntentSender for testing purposes + +package android.content; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.UserHandle; +import android.util.AndroidException; + +public class IntentSender implements Parcelable +{ + public String getCreatorPackage(){ return null; } + public String getTargetPackage(){ return null; } + public String toString(){ return null; } + public UserHandle getCreatorUserHandle(){ return null; } + public boolean equals(Object p0){ return false; } + public int describeContents(){ return 0; } + public int getCreatorUid(){ return 0; } + public int hashCode(){ return 0; } + public static IntentSender readIntentSenderOrNullFromParcel(Parcel p0){ return null; } + public static Parcelable.Creator CREATOR = null; + public static void writeIntentSenderOrNullToParcel(IntentSender p0, Parcel p1){} + public void sendIntent(Context p0, int p1, Intent p2, IntentSender.OnFinished p3, Handler p4){} + public void sendIntent(Context p0, int p1, Intent p2, IntentSender.OnFinished p3, Handler p4, String p5){} + public void writeToParcel(Parcel p0, int p1){} + static public class SendIntentException extends AndroidException + { + public SendIntentException(){} + public SendIntentException(Exception p0){} + public SendIntentException(String p0){} + } + static public interface OnFinished + { + void onSendFinished(IntentSender p0, Intent p1, int p2, String p3, Bundle p4); + } +} diff --git a/java/ql/test/stubs/android/android/content/PeriodicSync.java b/java/ql/test/stubs/android/android/content/PeriodicSync.java new file mode 100644 index 00000000000..6842c06d22f --- /dev/null +++ b/java/ql/test/stubs/android/android/content/PeriodicSync.java @@ -0,0 +1,23 @@ +// Generated automatically from android.content.PeriodicSync for testing purposes + +package android.content; + +import android.accounts.Account; +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; + +public class PeriodicSync implements Parcelable +{ + protected PeriodicSync() {} + public PeriodicSync(Account p0, String p1, Bundle p2, long p3){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public final Account account = null; + public final Bundle extras = null; + public final String authority = null; + public final long period = 0; + public int describeContents(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/ServiceConnection.java b/java/ql/test/stubs/android/android/content/ServiceConnection.java new file mode 100644 index 00000000000..1b8534539c4 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/ServiceConnection.java @@ -0,0 +1,14 @@ +// Generated automatically from android.content.ServiceConnection for testing purposes + +package android.content; + +import android.content.ComponentName; +import android.os.IBinder; + +public interface ServiceConnection +{ + default void onBindingDied(ComponentName p0){} + default void onNullBinding(ComponentName p0){} + void onServiceConnected(ComponentName p0, IBinder p1); + void onServiceDisconnected(ComponentName p0); +} diff --git a/java/ql/test/stubs/android/android/content/SharedPreferences.java b/java/ql/test/stubs/android/android/content/SharedPreferences.java new file mode 100644 index 00000000000..90cdc242501 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/SharedPreferences.java @@ -0,0 +1,38 @@ +// Generated automatically from android.content.SharedPreferences for testing purposes + +package android.content; + +import java.util.Map; +import java.util.Set; + +public interface SharedPreferences +{ + Map getAll(); + Set getStringSet(String p0, Set p1); + SharedPreferences.Editor edit(); + String getString(String p0, String p1); + boolean contains(String p0); + boolean getBoolean(String p0, boolean p1); + float getFloat(String p0, float p1); + int getInt(String p0, int p1); + long getLong(String p0, long p1); + static public interface Editor + { + SharedPreferences.Editor clear(); + SharedPreferences.Editor putBoolean(String p0, boolean p1); + SharedPreferences.Editor putFloat(String p0, float p1); + SharedPreferences.Editor putInt(String p0, int p1); + SharedPreferences.Editor putLong(String p0, long p1); + SharedPreferences.Editor putString(String p0, String p1); + SharedPreferences.Editor putStringSet(String p0, Set p1); + SharedPreferences.Editor remove(String p0); + boolean commit(); + void apply(); + } + static public interface OnSharedPreferenceChangeListener + { + void onSharedPreferenceChanged(SharedPreferences p0, String p1); + } + void registerOnSharedPreferenceChangeListener(SharedPreferences.OnSharedPreferenceChangeListener p0); + void unregisterOnSharedPreferenceChangeListener(SharedPreferences.OnSharedPreferenceChangeListener p0); +} diff --git a/java/ql/test/stubs/android/android/content/SyncAdapterType.java b/java/ql/test/stubs/android/android/content/SyncAdapterType.java new file mode 100644 index 00000000000..b05e030a6c3 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/SyncAdapterType.java @@ -0,0 +1,28 @@ +// Generated automatically from android.content.SyncAdapterType for testing purposes + +package android.content; + +import android.os.Parcel; +import android.os.Parcelable; + +public class SyncAdapterType implements Parcelable +{ + protected SyncAdapterType() {} + public String getSettingsActivity(){ return null; } + public String toString(){ return null; } + public SyncAdapterType(Parcel p0){} + public SyncAdapterType(String p0, String p1, boolean p2, boolean p3){} + public boolean allowParallelSyncs(){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isAlwaysSyncable(){ return false; } + public boolean isUserVisible(){ return false; } + public boolean supportsUploading(){ return false; } + public final String accountType = null; + public final String authority = null; + public final boolean isKey = false; + public int describeContents(){ return 0; } + public int hashCode(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static SyncAdapterType newKey(String p0, String p1){ return null; } + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/SyncInfo.java b/java/ql/test/stubs/android/android/content/SyncInfo.java new file mode 100644 index 00000000000..500c5bd97bc --- /dev/null +++ b/java/ql/test/stubs/android/android/content/SyncInfo.java @@ -0,0 +1,16 @@ +// Generated automatically from android.content.SyncInfo for testing purposes + +package android.content; + +import android.accounts.Account; +import android.os.Parcel; +import android.os.Parcelable; + +public class SyncInfo implements Parcelable +{ + public final Account account = null; + public final String authority = null; + public final long startTime = 0; + public int describeContents(){ return 0; } + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/SyncRequest.java b/java/ql/test/stubs/android/android/content/SyncRequest.java new file mode 100644 index 00000000000..29a07c4b5a7 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/SyncRequest.java @@ -0,0 +1,13 @@ +// Generated automatically from android.content.SyncRequest for testing purposes + +package android.content; + +import android.os.Parcel; +import android.os.Parcelable; + +public class SyncRequest implements Parcelable +{ + public int describeContents(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/SyncStatusObserver.java b/java/ql/test/stubs/android/android/content/SyncStatusObserver.java new file mode 100644 index 00000000000..534cd549be0 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/SyncStatusObserver.java @@ -0,0 +1,9 @@ +// Generated automatically from android.content.SyncStatusObserver for testing purposes + +package android.content; + + +public interface SyncStatusObserver +{ + void onStatusChanged(int p0); +} diff --git a/java/ql/test/stubs/android/android/content/UriPermission.java b/java/ql/test/stubs/android/android/content/UriPermission.java new file mode 100644 index 00000000000..efa9f6e7b95 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/UriPermission.java @@ -0,0 +1,20 @@ +// Generated automatically from android.content.UriPermission for testing purposes + +package android.content; + +import android.net.Uri; +import android.os.Parcel; +import android.os.Parcelable; + +public class UriPermission implements Parcelable +{ + public String toString(){ return null; } + public Uri getUri(){ return null; } + public boolean isReadPermission(){ return false; } + public boolean isWritePermission(){ return false; } + public int describeContents(){ return 0; } + public long getPersistedTime(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static long INVALID_TIME = 0; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/ActivityInfo.java b/java/ql/test/stubs/android/android/content/pm/ActivityInfo.java new file mode 100644 index 00000000000..ed0debb0412 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/ActivityInfo.java @@ -0,0 +1,112 @@ +// Generated automatically from android.content.pm.ActivityInfo for testing purposes + +package android.content.pm; + +import android.content.pm.ComponentInfo; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Printer; + +public class ActivityInfo extends ComponentInfo implements Parcelable +{ + public ActivityInfo(){} + public ActivityInfo(ActivityInfo p0){} + public ActivityInfo.WindowLayout windowLayout = null; + public String parentActivityName = null; + public String permission = null; + public String targetActivity = null; + public String taskAffinity = null; + public String toString(){ return null; } + public final int getThemeResource(){ return 0; } + public int colorMode = 0; + public int configChanges = 0; + public int describeContents(){ return 0; } + public int documentLaunchMode = 0; + public int flags = 0; + public int launchMode = 0; + public int maxRecents = 0; + public int persistableMode = 0; + public int screenOrientation = 0; + public int softInputMode = 0; + public int theme = 0; + public int uiOptions = 0; + public static Parcelable.Creator CREATOR = null; + public static int COLOR_MODE_DEFAULT = 0; + public static int COLOR_MODE_HDR = 0; + public static int COLOR_MODE_WIDE_COLOR_GAMUT = 0; + public static int CONFIG_COLOR_MODE = 0; + public static int CONFIG_DENSITY = 0; + public static int CONFIG_FONT_SCALE = 0; + public static int CONFIG_KEYBOARD = 0; + public static int CONFIG_KEYBOARD_HIDDEN = 0; + public static int CONFIG_LAYOUT_DIRECTION = 0; + public static int CONFIG_LOCALE = 0; + public static int CONFIG_MCC = 0; + public static int CONFIG_MNC = 0; + public static int CONFIG_NAVIGATION = 0; + public static int CONFIG_ORIENTATION = 0; + public static int CONFIG_SCREEN_LAYOUT = 0; + public static int CONFIG_SCREEN_SIZE = 0; + public static int CONFIG_SMALLEST_SCREEN_SIZE = 0; + public static int CONFIG_TOUCHSCREEN = 0; + public static int CONFIG_UI_MODE = 0; + public static int DOCUMENT_LAUNCH_ALWAYS = 0; + public static int DOCUMENT_LAUNCH_INTO_EXISTING = 0; + public static int DOCUMENT_LAUNCH_NEVER = 0; + public static int DOCUMENT_LAUNCH_NONE = 0; + public static int FLAG_ALLOW_TASK_REPARENTING = 0; + public static int FLAG_ALWAYS_RETAIN_TASK_STATE = 0; + public static int FLAG_AUTO_REMOVE_FROM_RECENTS = 0; + public static int FLAG_CLEAR_TASK_ON_LAUNCH = 0; + public static int FLAG_ENABLE_VR_MODE = 0; + public static int FLAG_EXCLUDE_FROM_RECENTS = 0; + public static int FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS = 0; + public static int FLAG_FINISH_ON_TASK_LAUNCH = 0; + public static int FLAG_HARDWARE_ACCELERATED = 0; + public static int FLAG_IMMERSIVE = 0; + public static int FLAG_MULTIPROCESS = 0; + public static int FLAG_NO_HISTORY = 0; + public static int FLAG_PREFER_MINIMAL_POST_PROCESSING = 0; + public static int FLAG_RELINQUISH_TASK_IDENTITY = 0; + public static int FLAG_RESUME_WHILE_PAUSING = 0; + public static int FLAG_SINGLE_USER = 0; + public static int FLAG_STATE_NOT_NEEDED = 0; + public static int LAUNCH_MULTIPLE = 0; + public static int LAUNCH_SINGLE_INSTANCE = 0; + public static int LAUNCH_SINGLE_TASK = 0; + public static int LAUNCH_SINGLE_TOP = 0; + public static int PERSIST_ACROSS_REBOOTS = 0; + public static int PERSIST_NEVER = 0; + public static int PERSIST_ROOT_ONLY = 0; + public static int SCREEN_ORIENTATION_BEHIND = 0; + public static int SCREEN_ORIENTATION_FULL_SENSOR = 0; + public static int SCREEN_ORIENTATION_FULL_USER = 0; + public static int SCREEN_ORIENTATION_LANDSCAPE = 0; + public static int SCREEN_ORIENTATION_LOCKED = 0; + public static int SCREEN_ORIENTATION_NOSENSOR = 0; + public static int SCREEN_ORIENTATION_PORTRAIT = 0; + public static int SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 0; + public static int SCREEN_ORIENTATION_REVERSE_PORTRAIT = 0; + public static int SCREEN_ORIENTATION_SENSOR = 0; + public static int SCREEN_ORIENTATION_SENSOR_LANDSCAPE = 0; + public static int SCREEN_ORIENTATION_SENSOR_PORTRAIT = 0; + public static int SCREEN_ORIENTATION_UNSPECIFIED = 0; + public static int SCREEN_ORIENTATION_USER = 0; + public static int SCREEN_ORIENTATION_USER_LANDSCAPE = 0; + public static int SCREEN_ORIENTATION_USER_PORTRAIT = 0; + public static int UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW = 0; + public void dump(Printer p0, String p1){} + public void writeToParcel(Parcel p0, int p1){} + static public class WindowLayout + { + protected WindowLayout() {} + public WindowLayout(int p0, float p1, int p2, float p3, int p4, int p5, int p6){} + public final float heightFraction = 0; + public final float widthFraction = 0; + public final int gravity = 0; + public final int height = 0; + public final int minHeight = 0; + public final int minWidth = 0; + public final int width = 0; + } +} diff --git a/java/ql/test/stubs/android/android/content/pm/ApplicationInfo.java b/java/ql/test/stubs/android/android/content/pm/ApplicationInfo.java new file mode 100644 index 00000000000..51fc3974933 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/ApplicationInfo.java @@ -0,0 +1,101 @@ +// Generated automatically from android.content.pm.ApplicationInfo for testing purposes + +package android.content.pm; + +import android.content.Context; +import android.content.pm.PackageItemInfo; +import android.content.pm.PackageManager; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Printer; +import java.util.UUID; + +public class ApplicationInfo extends PackageItemInfo implements Parcelable +{ + public ApplicationInfo(){} + public ApplicationInfo(ApplicationInfo p0){} + public CharSequence loadDescription(PackageManager p0){ return null; } + public String appComponentFactory = null; + public String backupAgentName = null; + public String className = null; + public String dataDir = null; + public String deviceProtectedDataDir = null; + public String manageSpaceActivityName = null; + public String nativeLibraryDir = null; + public String permission = null; + public String processName = null; + public String publicSourceDir = null; + public String sourceDir = null; + public String taskAffinity = null; + public String toString(){ return null; } + public String[] sharedLibraryFiles = null; + public String[] splitNames = null; + public String[] splitPublicSourceDirs = null; + public String[] splitSourceDirs = null; + public UUID storageUuid = null; + public boolean enabled = false; + public boolean isProfileableByShell(){ return false; } + public boolean isResourceOverlay(){ return false; } + public boolean isVirtualPreload(){ return false; } + public int category = 0; + public int compatibleWidthLimitDp = 0; + public int describeContents(){ return 0; } + public int descriptionRes = 0; + public int flags = 0; + public int getGwpAsanMode(){ return 0; } + public int largestWidthLimitDp = 0; + public int minSdkVersion = 0; + public int requiresSmallestWidthDp = 0; + public int targetSdkVersion = 0; + public int theme = 0; + public int uiOptions = 0; + public int uid = 0; + public static CharSequence getCategoryTitle(Context p0, int p1){ return null; } + public static Parcelable.Creator CREATOR = null; + public static int CATEGORY_AUDIO = 0; + public static int CATEGORY_GAME = 0; + public static int CATEGORY_IMAGE = 0; + public static int CATEGORY_MAPS = 0; + public static int CATEGORY_NEWS = 0; + public static int CATEGORY_PRODUCTIVITY = 0; + public static int CATEGORY_SOCIAL = 0; + public static int CATEGORY_UNDEFINED = 0; + public static int CATEGORY_VIDEO = 0; + public static int FLAG_ALLOW_BACKUP = 0; + public static int FLAG_ALLOW_CLEAR_USER_DATA = 0; + public static int FLAG_ALLOW_TASK_REPARENTING = 0; + public static int FLAG_DEBUGGABLE = 0; + public static int FLAG_EXTERNAL_STORAGE = 0; + public static int FLAG_EXTRACT_NATIVE_LIBS = 0; + public static int FLAG_FACTORY_TEST = 0; + public static int FLAG_FULL_BACKUP_ONLY = 0; + public static int FLAG_HARDWARE_ACCELERATED = 0; + public static int FLAG_HAS_CODE = 0; + public static int FLAG_INSTALLED = 0; + public static int FLAG_IS_DATA_ONLY = 0; + public static int FLAG_IS_GAME = 0; + public static int FLAG_KILL_AFTER_RESTORE = 0; + public static int FLAG_LARGE_HEAP = 0; + public static int FLAG_MULTIARCH = 0; + public static int FLAG_PERSISTENT = 0; + public static int FLAG_RESIZEABLE_FOR_SCREENS = 0; + public static int FLAG_RESTORE_ANY_VERSION = 0; + public static int FLAG_STOPPED = 0; + public static int FLAG_SUPPORTS_LARGE_SCREENS = 0; + public static int FLAG_SUPPORTS_NORMAL_SCREENS = 0; + public static int FLAG_SUPPORTS_RTL = 0; + public static int FLAG_SUPPORTS_SCREEN_DENSITIES = 0; + public static int FLAG_SUPPORTS_SMALL_SCREENS = 0; + public static int FLAG_SUPPORTS_XLARGE_SCREENS = 0; + public static int FLAG_SUSPENDED = 0; + public static int FLAG_SYSTEM = 0; + public static int FLAG_TEST_ONLY = 0; + public static int FLAG_UPDATED_SYSTEM_APP = 0; + public static int FLAG_USES_CLEARTEXT_TRAFFIC = 0; + public static int FLAG_VM_SAFE_MODE = 0; + public static int GWP_ASAN_ALWAYS = 0; + public static int GWP_ASAN_DEFAULT = 0; + public static int GWP_ASAN_NEVER = 0; + public void dump(Printer p0, String p1){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/ChangedPackages.java b/java/ql/test/stubs/android/android/content/pm/ChangedPackages.java new file mode 100644 index 00000000000..08c10b13f3c --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/ChangedPackages.java @@ -0,0 +1,18 @@ +// Generated automatically from android.content.pm.ChangedPackages for testing purposes + +package android.content.pm; + +import android.os.Parcel; +import android.os.Parcelable; +import java.util.List; + +public class ChangedPackages implements Parcelable +{ + protected ChangedPackages() {} + public ChangedPackages(int p0, List p1){} + public List getPackageNames(){ return null; } + public int describeContents(){ return 0; } + public int getSequenceNumber(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/ComponentInfo.java b/java/ql/test/stubs/android/android/content/pm/ComponentInfo.java new file mode 100644 index 00000000000..fb92a43adbe --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/ComponentInfo.java @@ -0,0 +1,29 @@ +// Generated automatically from android.content.pm.ComponentInfo for testing purposes + +package android.content.pm; + +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageItemInfo; +import android.os.Parcel; +import android.util.Printer; + +public class ComponentInfo extends PackageItemInfo +{ + protected ComponentInfo(Parcel p0){} + protected void dumpBack(Printer p0, String p1){} + protected void dumpFront(Printer p0, String p1){} + public ApplicationInfo applicationInfo = null; + public ComponentInfo(){} + public ComponentInfo(ComponentInfo p0){} + public String processName = null; + public String splitName = null; + public boolean directBootAware = false; + public boolean enabled = false; + public boolean exported = false; + public boolean isEnabled(){ return false; } + public final int getBannerResource(){ return 0; } + public final int getIconResource(){ return 0; } + public final int getLogoResource(){ return 0; } + public int descriptionRes = 0; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/ConfigurationInfo.java b/java/ql/test/stubs/android/android/content/pm/ConfigurationInfo.java new file mode 100644 index 00000000000..ad178b8c6a3 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/ConfigurationInfo.java @@ -0,0 +1,25 @@ +// Generated automatically from android.content.pm.ConfigurationInfo for testing purposes + +package android.content.pm; + +import android.os.Parcel; +import android.os.Parcelable; + +public class ConfigurationInfo implements Parcelable +{ + public ConfigurationInfo(){} + public ConfigurationInfo(ConfigurationInfo p0){} + public String getGlEsVersion(){ return null; } + public String toString(){ return null; } + public int describeContents(){ return 0; } + public int reqGlEsVersion = 0; + public int reqInputFeatures = 0; + public int reqKeyboardType = 0; + public int reqNavigation = 0; + public int reqTouchScreen = 0; + public static Parcelable.Creator CREATOR = null; + public static int GL_ES_VERSION_UNDEFINED = 0; + public static int INPUT_FEATURE_FIVE_WAY_NAV = 0; + public static int INPUT_FEATURE_HARD_KEYBOARD = 0; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/FeatureGroupInfo.java b/java/ql/test/stubs/android/android/content/pm/FeatureGroupInfo.java new file mode 100644 index 00000000000..9cf6eaa172a --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/FeatureGroupInfo.java @@ -0,0 +1,17 @@ +// Generated automatically from android.content.pm.FeatureGroupInfo for testing purposes + +package android.content.pm; + +import android.content.pm.FeatureInfo; +import android.os.Parcel; +import android.os.Parcelable; + +public class FeatureGroupInfo implements Parcelable +{ + public FeatureGroupInfo(){} + public FeatureGroupInfo(FeatureGroupInfo p0){} + public FeatureInfo[] features = null; + public int describeContents(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/FeatureInfo.java b/java/ql/test/stubs/android/android/content/pm/FeatureInfo.java new file mode 100644 index 00000000000..5512590828f --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/FeatureInfo.java @@ -0,0 +1,23 @@ +// Generated automatically from android.content.pm.FeatureInfo for testing purposes + +package android.content.pm; + +import android.os.Parcel; +import android.os.Parcelable; + +public class FeatureInfo implements Parcelable +{ + public FeatureInfo(){} + public FeatureInfo(FeatureInfo p0){} + public String getGlEsVersion(){ return null; } + public String name = null; + public String toString(){ return null; } + public int describeContents(){ return 0; } + public int flags = 0; + public int reqGlEsVersion = 0; + public int version = 0; + public static Parcelable.Creator CREATOR = null; + public static int FLAG_REQUIRED = 0; + public static int GL_ES_VERSION_UNDEFINED = 0; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/InstallSourceInfo.java b/java/ql/test/stubs/android/android/content/pm/InstallSourceInfo.java new file mode 100644 index 00000000000..85c503025d0 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/InstallSourceInfo.java @@ -0,0 +1,18 @@ +// Generated automatically from android.content.pm.InstallSourceInfo for testing purposes + +package android.content.pm; + +import android.content.pm.SigningInfo; +import android.os.Parcel; +import android.os.Parcelable; + +public class InstallSourceInfo implements Parcelable +{ + public SigningInfo getInitiatingPackageSigningInfo(){ return null; } + public String getInitiatingPackageName(){ return null; } + public String getInstallingPackageName(){ return null; } + public String getOriginatingPackageName(){ return null; } + public int describeContents(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/InstrumentationInfo.java b/java/ql/test/stubs/android/android/content/pm/InstrumentationInfo.java new file mode 100644 index 00000000000..70063a09744 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/InstrumentationInfo.java @@ -0,0 +1,27 @@ +// Generated automatically from android.content.pm.InstrumentationInfo for testing purposes + +package android.content.pm; + +import android.content.pm.PackageItemInfo; +import android.os.Parcel; +import android.os.Parcelable; + +public class InstrumentationInfo extends PackageItemInfo implements Parcelable +{ + public InstrumentationInfo(){} + public InstrumentationInfo(InstrumentationInfo p0){} + public String dataDir = null; + public String publicSourceDir = null; + public String sourceDir = null; + public String targetPackage = null; + public String targetProcesses = null; + public String toString(){ return null; } + public String[] splitNames = null; + public String[] splitPublicSourceDirs = null; + public String[] splitSourceDirs = null; + public boolean functionalTest = false; + public boolean handleProfiling = false; + public int describeContents(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/ModuleInfo.java b/java/ql/test/stubs/android/android/content/pm/ModuleInfo.java new file mode 100644 index 00000000000..c7aef5f7ac7 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/ModuleInfo.java @@ -0,0 +1,19 @@ +// Generated automatically from android.content.pm.ModuleInfo for testing purposes + +package android.content.pm; + +import android.os.Parcel; +import android.os.Parcelable; + +public class ModuleInfo implements Parcelable +{ + public CharSequence getName(){ return null; } + public String getPackageName(){ return null; } + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public boolean isHidden(){ return false; } + public int describeContents(){ return 0; } + public int hashCode(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/PackageInfo.java b/java/ql/test/stubs/android/android/content/pm/PackageInfo.java new file mode 100644 index 00000000000..566e8e73fbf --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/PackageInfo.java @@ -0,0 +1,59 @@ +// Generated automatically from android.content.pm.PackageInfo for testing purposes + +package android.content.pm; + +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.ConfigurationInfo; +import android.content.pm.FeatureGroupInfo; +import android.content.pm.FeatureInfo; +import android.content.pm.InstrumentationInfo; +import android.content.pm.PermissionInfo; +import android.content.pm.ProviderInfo; +import android.content.pm.ServiceInfo; +import android.content.pm.Signature; +import android.content.pm.SigningInfo; +import android.os.Parcel; +import android.os.Parcelable; + +public class PackageInfo implements Parcelable +{ + public ActivityInfo[] activities = null; + public ActivityInfo[] receivers = null; + public ApplicationInfo applicationInfo = null; + public ConfigurationInfo[] configPreferences = null; + public FeatureGroupInfo[] featureGroups = null; + public FeatureInfo[] reqFeatures = null; + public InstrumentationInfo[] instrumentation = null; + public PackageInfo(){} + public PermissionInfo[] permissions = null; + public ProviderInfo[] providers = null; + public ServiceInfo[] services = null; + public Signature[] signatures = null; + public SigningInfo signingInfo = null; + public String packageName = null; + public String sharedUserId = null; + public String toString(){ return null; } + public String versionName = null; + public String[] requestedPermissions = null; + public String[] splitNames = null; + public boolean isApex = false; + public int baseRevisionCode = 0; + public int describeContents(){ return 0; } + public int installLocation = 0; + public int sharedUserLabel = 0; + public int versionCode = 0; + public int[] gids = null; + public int[] requestedPermissionsFlags = null; + public int[] splitRevisionCodes = null; + public long firstInstallTime = 0; + public long getLongVersionCode(){ return 0; } + public long lastUpdateTime = 0; + public static Parcelable.Creator CREATOR = null; + public static int INSTALL_LOCATION_AUTO = 0; + public static int INSTALL_LOCATION_INTERNAL_ONLY = 0; + public static int INSTALL_LOCATION_PREFER_EXTERNAL = 0; + public static int REQUESTED_PERMISSION_GRANTED = 0; + public void setLongVersionCode(long p0){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/PackageInstaller.java b/java/ql/test/stubs/android/android/content/pm/PackageInstaller.java new file mode 100644 index 00000000000..46337e28f60 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/PackageInstaller.java @@ -0,0 +1,151 @@ +// Generated automatically from android.content.pm.PackageInstaller for testing purposes + +package android.content.pm; + +import android.content.Intent; +import android.content.IntentSender; +import android.content.pm.VersionedPackage; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Handler; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.UserHandle; +import java.io.Closeable; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; +import java.util.Set; + +public class PackageInstaller +{ + abstract static public class SessionCallback + { + public SessionCallback(){} + public abstract void onActiveChanged(int p0, boolean p1); + public abstract void onBadgingChanged(int p0); + public abstract void onCreated(int p0); + public abstract void onFinished(int p0, boolean p1); + public abstract void onProgressChanged(int p0, float p1); + } + public List getActiveStagedSessions(){ return null; } + public List getAllSessions(){ return null; } + public List getMySessions(){ return null; } + public List getStagedSessions(){ return null; } + public PackageInstaller.Session openSession(int p0){ return null; } + public PackageInstaller.SessionInfo getActiveStagedSession(){ return null; } + public PackageInstaller.SessionInfo getSessionInfo(int p0){ return null; } + public int createSession(PackageInstaller.SessionParams p0){ return 0; } + public static String ACTION_SESSION_COMMITTED = null; + public static String ACTION_SESSION_DETAILS = null; + public static String ACTION_SESSION_UPDATED = null; + public static String EXTRA_OTHER_PACKAGE_NAME = null; + public static String EXTRA_PACKAGE_NAME = null; + public static String EXTRA_SESSION = null; + public static String EXTRA_SESSION_ID = null; + public static String EXTRA_STATUS = null; + public static String EXTRA_STATUS_MESSAGE = null; + public static String EXTRA_STORAGE_PATH = null; + public static int STATUS_FAILURE = 0; + public static int STATUS_FAILURE_ABORTED = 0; + public static int STATUS_FAILURE_BLOCKED = 0; + public static int STATUS_FAILURE_CONFLICT = 0; + public static int STATUS_FAILURE_INCOMPATIBLE = 0; + public static int STATUS_FAILURE_INVALID = 0; + public static int STATUS_FAILURE_STORAGE = 0; + public static int STATUS_PENDING_USER_ACTION = 0; + public static int STATUS_SUCCESS = 0; + public void abandonSession(int p0){} + public void installExistingPackage(String p0, int p1, IntentSender p2){} + public void registerSessionCallback(PackageInstaller.SessionCallback p0){} + public void registerSessionCallback(PackageInstaller.SessionCallback p0, Handler p1){} + public void uninstall(String p0, IntentSender p1){} + public void uninstall(VersionedPackage p0, IntentSender p1){} + public void unregisterSessionCallback(PackageInstaller.SessionCallback p0){} + public void updateSessionAppIcon(int p0, Bitmap p1){} + public void updateSessionAppLabel(int p0, CharSequence p1){} + static public class Session implements Closeable + { + public InputStream openRead(String p0){ return null; } + public OutputStream openWrite(String p0, long p1, long p2){ return null; } + public String[] getNames(){ return null; } + public boolean isMultiPackage(){ return false; } + public boolean isStaged(){ return false; } + public int getParentSessionId(){ return 0; } + public int[] getChildSessionIds(){ return null; } + public void abandon(){} + public void addChildSessionId(int p0){} + public void close(){} + public void commit(IntentSender p0){} + public void fsync(OutputStream p0){} + public void removeChildSessionId(int p0){} + public void removeSplit(String p0){} + public void setStagingProgress(float p0){} + public void transfer(String p0){} + } + static public class SessionInfo implements Parcelable + { + public Bitmap getAppIcon(){ return null; } + public CharSequence getAppLabel(){ return null; } + public Intent createDetailsIntent(){ return null; } + public String getAppPackageName(){ return null; } + public String getInstallerPackageName(){ return null; } + public String getStagedSessionErrorMessage(){ return null; } + public Uri getOriginatingUri(){ return null; } + public Uri getReferrerUri(){ return null; } + public UserHandle getUser(){ return null; } + public boolean hasParentSessionId(){ return false; } + public boolean isActive(){ return false; } + public boolean isCommitted(){ return false; } + public boolean isMultiPackage(){ return false; } + public boolean isSealed(){ return false; } + public boolean isStaged(){ return false; } + public boolean isStagedSessionActive(){ return false; } + public boolean isStagedSessionApplied(){ return false; } + public boolean isStagedSessionFailed(){ return false; } + public boolean isStagedSessionReady(){ return false; } + public float getProgress(){ return 0; } + public int describeContents(){ return 0; } + public int getInstallLocation(){ return 0; } + public int getInstallReason(){ return 0; } + public int getMode(){ return 0; } + public int getOriginatingUid(){ return 0; } + public int getParentSessionId(){ return 0; } + public int getSessionId(){ return 0; } + public int getStagedSessionErrorCode(){ return 0; } + public int[] getChildSessionIds(){ return null; } + public long getCreatedMillis(){ return 0; } + public long getSize(){ return 0; } + public long getUpdatedMillis(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static int INVALID_ID = 0; + public static int STAGED_SESSION_ACTIVATION_FAILED = 0; + public static int STAGED_SESSION_NO_ERROR = 0; + public static int STAGED_SESSION_UNKNOWN = 0; + public static int STAGED_SESSION_VERIFICATION_FAILED = 0; + public void writeToParcel(Parcel p0, int p1){} + } + static public class SessionParams implements Parcelable + { + protected SessionParams() {} + public SessionParams(int p0){} + public int describeContents(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static Set RESTRICTED_PERMISSIONS_ALL = null; + public static int MODE_FULL_INSTALL = 0; + public static int MODE_INHERIT_EXISTING = 0; + public void setAppIcon(Bitmap p0){} + public void setAppLabel(CharSequence p0){} + public void setAppPackageName(String p0){} + public void setAutoRevokePermissionsMode(boolean p0){} + public void setInstallLocation(int p0){} + public void setInstallReason(int p0){} + public void setMultiPackage(){} + public void setOriginatingUid(int p0){} + public void setOriginatingUri(Uri p0){} + public void setReferrerUri(Uri p0){} + public void setSize(long p0){} + public void setWhitelistedRestrictedPermissions(Set p0){} + public void writeToParcel(Parcel p0, int p1){} + } +} diff --git a/java/ql/test/stubs/android/android/content/pm/PackageItemInfo.java b/java/ql/test/stubs/android/android/content/pm/PackageItemInfo.java new file mode 100644 index 00000000000..1d35a31f52b --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/PackageItemInfo.java @@ -0,0 +1,34 @@ +// Generated automatically from android.content.pm.PackageItemInfo for testing purposes + +package android.content.pm; + +import android.content.pm.PackageManager; +import android.content.res.XmlResourceParser; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.Parcel; +import android.util.Printer; + +public class PackageItemInfo +{ + protected PackageItemInfo(Parcel p0){} + protected void dumpBack(Printer p0, String p1){} + protected void dumpFront(Printer p0, String p1){} + public Bundle metaData = null; + public CharSequence loadLabel(PackageManager p0){ return null; } + public CharSequence nonLocalizedLabel = null; + public Drawable loadBanner(PackageManager p0){ return null; } + public Drawable loadIcon(PackageManager p0){ return null; } + public Drawable loadLogo(PackageManager p0){ return null; } + public Drawable loadUnbadgedIcon(PackageManager p0){ return null; } + public PackageItemInfo(){} + public PackageItemInfo(PackageItemInfo p0){} + public String name = null; + public String packageName = null; + public XmlResourceParser loadXmlMetaData(PackageManager p0, String p1){ return null; } + public int banner = 0; + public int icon = 0; + public int labelRes = 0; + public int logo = 0; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/PackageManager.java b/java/ql/test/stubs/android/android/content/pm/PackageManager.java new file mode 100644 index 00000000000..73e82024984 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/PackageManager.java @@ -0,0 +1,331 @@ +// Generated automatically from android.content.pm.PackageManager for testing purposes + +package android.content.pm; + +import android.content.ComponentName; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.ChangedPackages; +import android.content.pm.FeatureInfo; +import android.content.pm.InstallSourceInfo; +import android.content.pm.InstrumentationInfo; +import android.content.pm.ModuleInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageInstaller; +import android.content.pm.PermissionGroupInfo; +import android.content.pm.PermissionInfo; +import android.content.pm.ProviderInfo; +import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; +import android.content.pm.SharedLibraryInfo; +import android.content.pm.VersionedPackage; +import android.content.res.Resources; +import android.content.res.XmlResourceParser; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.UserHandle; +import android.util.AndroidException; +import java.util.List; +import java.util.Set; + +abstract public class PackageManager +{ + public Bundle getSuspendedPackageAppExtras(){ return null; } + public CharSequence getBackgroundPermissionOptionLabel(){ return null; } + public InstallSourceInfo getInstallSourceInfo(String p0){ return null; } + public List getInstalledModules(int p0){ return null; } + public ModuleInfo getModuleInfo(String p0, int p1){ return null; } + public PackageInfo getPackageArchiveInfo(String p0, int p1){ return null; } + public PackageManager(){} + public Set getMimeGroup(String p0){ return null; } + public Set getWhitelistedRestrictedPermissions(String p0, int p1){ return null; } + public abstract ActivityInfo getActivityInfo(ComponentName p0, int p1); + public abstract ActivityInfo getReceiverInfo(ComponentName p0, int p1); + public abstract ApplicationInfo getApplicationInfo(String p0, int p1); + public abstract ChangedPackages getChangedPackages(int p0); + public abstract CharSequence getApplicationLabel(ApplicationInfo p0); + public abstract CharSequence getText(String p0, int p1, ApplicationInfo p2); + public abstract CharSequence getUserBadgedLabel(CharSequence p0, UserHandle p1); + public abstract Drawable getActivityBanner(ComponentName p0); + public abstract Drawable getActivityBanner(Intent p0); + public abstract Drawable getActivityIcon(ComponentName p0); + public abstract Drawable getActivityIcon(Intent p0); + public abstract Drawable getActivityLogo(ComponentName p0); + public abstract Drawable getActivityLogo(Intent p0); + public abstract Drawable getApplicationBanner(ApplicationInfo p0); + public abstract Drawable getApplicationBanner(String p0); + public abstract Drawable getApplicationIcon(ApplicationInfo p0); + public abstract Drawable getApplicationIcon(String p0); + public abstract Drawable getApplicationLogo(ApplicationInfo p0); + public abstract Drawable getApplicationLogo(String p0); + public abstract Drawable getDefaultActivityIcon(); + public abstract Drawable getDrawable(String p0, int p1, ApplicationInfo p2); + public abstract Drawable getUserBadgedDrawableForDensity(Drawable p0, UserHandle p1, Rect p2, int p3); + public abstract Drawable getUserBadgedIcon(Drawable p0, UserHandle p1); + public abstract FeatureInfo[] getSystemAvailableFeatures(); + public abstract InstrumentationInfo getInstrumentationInfo(ComponentName p0, int p1); + public abstract Intent getLaunchIntentForPackage(String p0); + public abstract Intent getLeanbackLaunchIntentForPackage(String p0); + public abstract List getInstalledApplications(int p0); + public abstract List queryInstrumentation(String p0, int p1); + public abstract List getInstalledPackages(int p0); + public abstract List getPackagesHoldingPermissions(String[] p0, int p1); + public abstract List getPreferredPackages(int p0); + public abstract List getAllPermissionGroups(int p0); + public abstract List queryPermissionsByGroup(String p0, int p1); + public abstract List queryContentProviders(String p0, int p1, int p2); + public abstract List queryBroadcastReceivers(Intent p0, int p1); + public abstract List queryIntentActivities(Intent p0, int p1); + public abstract List queryIntentActivityOptions(ComponentName p0, Intent[] p1, Intent p2, int p3); + public abstract List queryIntentContentProviders(Intent p0, int p1); + public abstract List queryIntentServices(Intent p0, int p1); + public abstract List getSharedLibraries(int p0); + public abstract PackageInfo getPackageInfo(String p0, int p1); + public abstract PackageInfo getPackageInfo(VersionedPackage p0, int p1); + public abstract PackageInstaller getPackageInstaller(); + public abstract PermissionGroupInfo getPermissionGroupInfo(String p0, int p1); + public abstract PermissionInfo getPermissionInfo(String p0, int p1); + public abstract ProviderInfo getProviderInfo(ComponentName p0, int p1); + public abstract ProviderInfo resolveContentProvider(String p0, int p1); + public abstract ResolveInfo resolveActivity(Intent p0, int p1); + public abstract ResolveInfo resolveService(Intent p0, int p1); + public abstract Resources getResourcesForActivity(ComponentName p0); + public abstract Resources getResourcesForApplication(ApplicationInfo p0); + public abstract Resources getResourcesForApplication(String p0); + public abstract ServiceInfo getServiceInfo(ComponentName p0, int p1); + public abstract String getInstallerPackageName(String p0); + public abstract String getNameForUid(int p0); + public abstract String[] canonicalToCurrentPackageNames(String[] p0); + public abstract String[] currentToCanonicalPackageNames(String[] p0); + public abstract String[] getPackagesForUid(int p0); + public abstract String[] getSystemSharedLibraryNames(); + public abstract XmlResourceParser getXml(String p0, int p1, ApplicationInfo p2); + public abstract boolean addPermission(PermissionInfo p0); + public abstract boolean addPermissionAsync(PermissionInfo p0); + public abstract boolean canRequestPackageInstalls(); + public abstract boolean hasSystemFeature(String p0); + public abstract boolean hasSystemFeature(String p0, int p1); + public abstract boolean isInstantApp(); + public abstract boolean isInstantApp(String p0); + public abstract boolean isPermissionRevokedByPolicy(String p0, String p1); + public abstract boolean isSafeMode(); + public abstract byte[] getInstantAppCookie(); + public abstract int checkPermission(String p0, String p1); + public abstract int checkSignatures(String p0, String p1); + public abstract int checkSignatures(int p0, int p1); + public abstract int getApplicationEnabledSetting(String p0); + public abstract int getComponentEnabledSetting(ComponentName p0); + public abstract int getInstantAppCookieMaxBytes(); + public abstract int getPackageUid(String p0, int p1); + public abstract int getPreferredActivities(List p0, List p1, String p2); + public abstract int[] getPackageGids(String p0); + public abstract int[] getPackageGids(String p0, int p1); + public abstract void addPackageToPreferred(String p0); + public abstract void addPreferredActivity(IntentFilter p0, int p1, ComponentName[] p2, ComponentName p3); + public abstract void clearInstantAppCookie(); + public abstract void clearPackagePreferredActivities(String p0); + public abstract void extendVerificationTimeout(int p0, int p1, long p2); + public abstract void removePackageFromPreferred(String p0); + public abstract void removePermission(String p0); + public abstract void setApplicationCategoryHint(String p0, int p1); + public abstract void setApplicationEnabledSetting(String p0, int p1, int p2); + public abstract void setComponentEnabledSetting(ComponentName p0, int p1, int p2); + public abstract void setInstallerPackageName(String p0, String p1); + public abstract void updateInstantAppCookie(byte[] p0); + public abstract void verifyPendingInstall(int p0, int p1); + public boolean addWhitelistedRestrictedPermission(String p0, String p1, int p2){ return false; } + public boolean getSyntheticAppDetailsActivityEnabled(String p0){ return false; } + public boolean hasSigningCertificate(String p0, byte[] p1, int p2){ return false; } + public boolean hasSigningCertificate(int p0, byte[] p1, int p2){ return false; } + public boolean isAutoRevokeWhitelisted(){ return false; } + public boolean isAutoRevokeWhitelisted(String p0){ return false; } + public boolean isDefaultApplicationIcon(Drawable p0){ return false; } + public boolean isDeviceUpgrading(){ return false; } + public boolean isPackageSuspended(){ return false; } + public boolean isPackageSuspended(String p0){ return false; } + public boolean removeWhitelistedRestrictedPermission(String p0, String p1, int p2){ return false; } + public boolean setAutoRevokeWhitelisted(String p0, boolean p1){ return false; } + public static String EXTRA_VERIFICATION_ID = null; + public static String EXTRA_VERIFICATION_RESULT = null; + public static String FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS = null; + public static String FEATURE_APP_WIDGETS = null; + public static String FEATURE_AUDIO_LOW_LATENCY = null; + public static String FEATURE_AUDIO_OUTPUT = null; + public static String FEATURE_AUDIO_PRO = null; + public static String FEATURE_AUTOFILL = null; + public static String FEATURE_AUTOMOTIVE = null; + public static String FEATURE_BACKUP = null; + public static String FEATURE_BLUETOOTH = null; + public static String FEATURE_BLUETOOTH_LE = null; + public static String FEATURE_CAMERA = null; + public static String FEATURE_CAMERA_ANY = null; + public static String FEATURE_CAMERA_AR = null; + public static String FEATURE_CAMERA_AUTOFOCUS = null; + public static String FEATURE_CAMERA_CAPABILITY_MANUAL_POST_PROCESSING = null; + public static String FEATURE_CAMERA_CAPABILITY_MANUAL_SENSOR = null; + public static String FEATURE_CAMERA_CAPABILITY_RAW = null; + public static String FEATURE_CAMERA_CONCURRENT = null; + public static String FEATURE_CAMERA_EXTERNAL = null; + public static String FEATURE_CAMERA_FLASH = null; + public static String FEATURE_CAMERA_FRONT = null; + public static String FEATURE_CAMERA_LEVEL_FULL = null; + public static String FEATURE_CANT_SAVE_STATE = null; + public static String FEATURE_COMPANION_DEVICE_SETUP = null; + public static String FEATURE_CONNECTION_SERVICE = null; + public static String FEATURE_CONSUMER_IR = null; + public static String FEATURE_CONTROLS = null; + public static String FEATURE_DEVICE_ADMIN = null; + public static String FEATURE_EMBEDDED = null; + public static String FEATURE_ETHERNET = null; + public static String FEATURE_FACE = null; + public static String FEATURE_FAKETOUCH = null; + public static String FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT = null; + public static String FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND = null; + public static String FEATURE_FINGERPRINT = null; + public static String FEATURE_FREEFORM_WINDOW_MANAGEMENT = null; + public static String FEATURE_GAMEPAD = null; + public static String FEATURE_HIFI_SENSORS = null; + public static String FEATURE_HOME_SCREEN = null; + public static String FEATURE_INPUT_METHODS = null; + public static String FEATURE_IPSEC_TUNNELS = null; + public static String FEATURE_IRIS = null; + public static String FEATURE_LEANBACK = null; + public static String FEATURE_LEANBACK_ONLY = null; + public static String FEATURE_LIVE_TV = null; + public static String FEATURE_LIVE_WALLPAPER = null; + public static String FEATURE_LOCATION = null; + public static String FEATURE_LOCATION_GPS = null; + public static String FEATURE_LOCATION_NETWORK = null; + public static String FEATURE_MANAGED_USERS = null; + public static String FEATURE_MICROPHONE = null; + public static String FEATURE_MIDI = null; + public static String FEATURE_NFC = null; + public static String FEATURE_NFC_BEAM = null; + public static String FEATURE_NFC_HOST_CARD_EMULATION = null; + public static String FEATURE_NFC_HOST_CARD_EMULATION_NFCF = null; + public static String FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE = null; + public static String FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC = null; + public static String FEATURE_OPENGLES_EXTENSION_PACK = null; + public static String FEATURE_PC = null; + public static String FEATURE_PICTURE_IN_PICTURE = null; + public static String FEATURE_PRINTING = null; + public static String FEATURE_RAM_LOW = null; + public static String FEATURE_RAM_NORMAL = null; + public static String FEATURE_SCREEN_LANDSCAPE = null; + public static String FEATURE_SCREEN_PORTRAIT = null; + public static String FEATURE_SECURELY_REMOVES_USERS = null; + public static String FEATURE_SECURE_LOCK_SCREEN = null; + public static String FEATURE_SENSOR_ACCELEROMETER = null; + public static String FEATURE_SENSOR_AMBIENT_TEMPERATURE = null; + public static String FEATURE_SENSOR_BAROMETER = null; + public static String FEATURE_SENSOR_COMPASS = null; + public static String FEATURE_SENSOR_GYROSCOPE = null; + public static String FEATURE_SENSOR_HEART_RATE = null; + public static String FEATURE_SENSOR_HEART_RATE_ECG = null; + public static String FEATURE_SENSOR_HINGE_ANGLE = null; + public static String FEATURE_SENSOR_LIGHT = null; + public static String FEATURE_SENSOR_PROXIMITY = null; + public static String FEATURE_SENSOR_RELATIVE_HUMIDITY = null; + public static String FEATURE_SENSOR_STEP_COUNTER = null; + public static String FEATURE_SENSOR_STEP_DETECTOR = null; + public static String FEATURE_SE_OMAPI_ESE = null; + public static String FEATURE_SE_OMAPI_SD = null; + public static String FEATURE_SE_OMAPI_UICC = null; + public static String FEATURE_SIP = null; + public static String FEATURE_SIP_VOIP = null; + public static String FEATURE_STRONGBOX_KEYSTORE = null; + public static String FEATURE_TELEPHONY = null; + public static String FEATURE_TELEPHONY_CDMA = null; + public static String FEATURE_TELEPHONY_EUICC = null; + public static String FEATURE_TELEPHONY_GSM = null; + public static String FEATURE_TELEPHONY_IMS = null; + public static String FEATURE_TELEPHONY_MBMS = null; + public static String FEATURE_TELEVISION = null; + public static String FEATURE_TOUCHSCREEN = null; + public static String FEATURE_TOUCHSCREEN_MULTITOUCH = null; + public static String FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT = null; + public static String FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND = null; + public static String FEATURE_USB_ACCESSORY = null; + public static String FEATURE_USB_HOST = null; + public static String FEATURE_VERIFIED_BOOT = null; + public static String FEATURE_VR_HEADTRACKING = null; + public static String FEATURE_VR_MODE = null; + public static String FEATURE_VR_MODE_HIGH_PERFORMANCE = null; + public static String FEATURE_VULKAN_DEQP_LEVEL = null; + public static String FEATURE_VULKAN_HARDWARE_COMPUTE = null; + public static String FEATURE_VULKAN_HARDWARE_LEVEL = null; + public static String FEATURE_VULKAN_HARDWARE_VERSION = null; + public static String FEATURE_WATCH = null; + public static String FEATURE_WEBVIEW = null; + public static String FEATURE_WIFI = null; + public static String FEATURE_WIFI_AWARE = null; + public static String FEATURE_WIFI_DIRECT = null; + public static String FEATURE_WIFI_PASSPOINT = null; + public static String FEATURE_WIFI_RTT = null; + public static int CERT_INPUT_RAW_X509 = 0; + public static int CERT_INPUT_SHA256 = 0; + public static int COMPONENT_ENABLED_STATE_DEFAULT = 0; + public static int COMPONENT_ENABLED_STATE_DISABLED = 0; + public static int COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED = 0; + public static int COMPONENT_ENABLED_STATE_DISABLED_USER = 0; + public static int COMPONENT_ENABLED_STATE_ENABLED = 0; + public static int DONT_KILL_APP = 0; + public static int FLAG_PERMISSION_WHITELIST_INSTALLER = 0; + public static int FLAG_PERMISSION_WHITELIST_SYSTEM = 0; + public static int FLAG_PERMISSION_WHITELIST_UPGRADE = 0; + public static int GET_ACTIVITIES = 0; + public static int GET_CONFIGURATIONS = 0; + public static int GET_DISABLED_COMPONENTS = 0; + public static int GET_DISABLED_UNTIL_USED_COMPONENTS = 0; + public static int GET_GIDS = 0; + public static int GET_INSTRUMENTATION = 0; + public static int GET_INTENT_FILTERS = 0; + public static int GET_META_DATA = 0; + public static int GET_PERMISSIONS = 0; + public static int GET_PROVIDERS = 0; + public static int GET_RECEIVERS = 0; + public static int GET_RESOLVED_FILTER = 0; + public static int GET_SERVICES = 0; + public static int GET_SHARED_LIBRARY_FILES = 0; + public static int GET_SIGNATURES = 0; + public static int GET_SIGNING_CERTIFICATES = 0; + public static int GET_UNINSTALLED_PACKAGES = 0; + public static int GET_URI_PERMISSION_PATTERNS = 0; + public static int INSTALL_REASON_DEVICE_RESTORE = 0; + public static int INSTALL_REASON_DEVICE_SETUP = 0; + public static int INSTALL_REASON_POLICY = 0; + public static int INSTALL_REASON_UNKNOWN = 0; + public static int INSTALL_REASON_USER = 0; + public static int MATCH_ALL = 0; + public static int MATCH_APEX = 0; + public static int MATCH_DEFAULT_ONLY = 0; + public static int MATCH_DIRECT_BOOT_AUTO = 0; + public static int MATCH_DIRECT_BOOT_AWARE = 0; + public static int MATCH_DIRECT_BOOT_UNAWARE = 0; + public static int MATCH_DISABLED_COMPONENTS = 0; + public static int MATCH_DISABLED_UNTIL_USED_COMPONENTS = 0; + public static int MATCH_SYSTEM_ONLY = 0; + public static int MATCH_UNINSTALLED_PACKAGES = 0; + public static int PERMISSION_DENIED = 0; + public static int PERMISSION_GRANTED = 0; + public static int SIGNATURE_FIRST_NOT_SIGNED = 0; + public static int SIGNATURE_MATCH = 0; + public static int SIGNATURE_NEITHER_SIGNED = 0; + public static int SIGNATURE_NO_MATCH = 0; + public static int SIGNATURE_SECOND_NOT_SIGNED = 0; + public static int SIGNATURE_UNKNOWN_PACKAGE = 0; + public static int SYNCHRONOUS = 0; + public static int VERIFICATION_ALLOW = 0; + public static int VERIFICATION_REJECT = 0; + public static int VERSION_CODE_HIGHEST = 0; + public static long MAXIMUM_VERIFICATION_TIMEOUT = 0; + public void setMimeGroup(String p0, Set p1){} + static public class NameNotFoundException extends AndroidException + { + public NameNotFoundException(){} + public NameNotFoundException(String p0){} + } +} diff --git a/java/ql/test/stubs/android/android/content/pm/PathPermission.java b/java/ql/test/stubs/android/android/content/pm/PathPermission.java new file mode 100644 index 00000000000..455adfe5be7 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/PathPermission.java @@ -0,0 +1,18 @@ +// Generated automatically from android.content.pm.PathPermission for testing purposes + +package android.content.pm; + +import android.os.Parcel; +import android.os.Parcelable; +import android.os.PatternMatcher; + +public class PathPermission extends PatternMatcher +{ + protected PathPermission() {} + public PathPermission(Parcel p0){} + public PathPermission(String p0, int p1, String p2, String p3){} + public String getReadPermission(){ return null; } + public String getWritePermission(){ return null; } + public static Parcelable.Creator CREATOR = null; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/PermissionGroupInfo.java b/java/ql/test/stubs/android/android/content/pm/PermissionGroupInfo.java new file mode 100644 index 00000000000..a74934de52f --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/PermissionGroupInfo.java @@ -0,0 +1,24 @@ +// Generated automatically from android.content.pm.PermissionGroupInfo for testing purposes + +package android.content.pm; + +import android.content.pm.PackageItemInfo; +import android.content.pm.PackageManager; +import android.os.Parcel; +import android.os.Parcelable; + +public class PermissionGroupInfo extends PackageItemInfo implements Parcelable +{ + public CharSequence loadDescription(PackageManager p0){ return null; } + public CharSequence nonLocalizedDescription = null; + public PermissionGroupInfo(){} + public PermissionGroupInfo(PermissionGroupInfo p0){} + public String toString(){ return null; } + public int describeContents(){ return 0; } + public int descriptionRes = 0; + public int flags = 0; + public int priority = 0; + public static Parcelable.Creator CREATOR = null; + public static int FLAG_PERSONAL_INFO = 0; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/PermissionInfo.java b/java/ql/test/stubs/android/android/content/pm/PermissionInfo.java new file mode 100644 index 00000000000..2c95bb9af7a --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/PermissionInfo.java @@ -0,0 +1,48 @@ +// Generated automatically from android.content.pm.PermissionInfo for testing purposes + +package android.content.pm; + +import android.content.pm.PackageItemInfo; +import android.content.pm.PackageManager; +import android.os.Parcel; +import android.os.Parcelable; + +public class PermissionInfo extends PackageItemInfo implements Parcelable +{ + public CharSequence loadDescription(PackageManager p0){ return null; } + public CharSequence nonLocalizedDescription = null; + public PermissionInfo(){} + public PermissionInfo(PermissionInfo p0){} + public String group = null; + public String toString(){ return null; } + public int describeContents(){ return 0; } + public int descriptionRes = 0; + public int flags = 0; + public int getProtection(){ return 0; } + public int getProtectionFlags(){ return 0; } + public int protectionLevel = 0; + public static Parcelable.Creator CREATOR = null; + public static int FLAG_COSTS_MONEY = 0; + public static int FLAG_HARD_RESTRICTED = 0; + public static int FLAG_IMMUTABLY_RESTRICTED = 0; + public static int FLAG_INSTALLED = 0; + public static int FLAG_SOFT_RESTRICTED = 0; + public static int PROTECTION_DANGEROUS = 0; + public static int PROTECTION_FLAG_APPOP = 0; + public static int PROTECTION_FLAG_DEVELOPMENT = 0; + public static int PROTECTION_FLAG_INSTALLER = 0; + public static int PROTECTION_FLAG_INSTANT = 0; + public static int PROTECTION_FLAG_PRE23 = 0; + public static int PROTECTION_FLAG_PREINSTALLED = 0; + public static int PROTECTION_FLAG_PRIVILEGED = 0; + public static int PROTECTION_FLAG_RUNTIME_ONLY = 0; + public static int PROTECTION_FLAG_SETUP = 0; + public static int PROTECTION_FLAG_SYSTEM = 0; + public static int PROTECTION_FLAG_VERIFIER = 0; + public static int PROTECTION_MASK_BASE = 0; + public static int PROTECTION_MASK_FLAGS = 0; + public static int PROTECTION_NORMAL = 0; + public static int PROTECTION_SIGNATURE = 0; + public static int PROTECTION_SIGNATURE_OR_SYSTEM = 0; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/ProviderInfo.java b/java/ql/test/stubs/android/android/content/pm/ProviderInfo.java new file mode 100644 index 00000000000..93b694cae59 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/ProviderInfo.java @@ -0,0 +1,33 @@ +// Generated automatically from android.content.pm.ProviderInfo for testing purposes + +package android.content.pm; + +import android.content.pm.ComponentInfo; +import android.content.pm.PathPermission; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.PatternMatcher; +import android.util.Printer; + +public class ProviderInfo extends ComponentInfo implements Parcelable +{ + public PathPermission[] pathPermissions = null; + public PatternMatcher[] uriPermissionPatterns = null; + public ProviderInfo(){} + public ProviderInfo(ProviderInfo p0){} + public String authority = null; + public String readPermission = null; + public String toString(){ return null; } + public String writePermission = null; + public boolean forceUriPermissions = false; + public boolean grantUriPermissions = false; + public boolean isSyncable = false; + public boolean multiprocess = false; + public int describeContents(){ return 0; } + public int flags = 0; + public int initOrder = 0; + public static Parcelable.Creator CREATOR = null; + public static int FLAG_SINGLE_USER = 0; + public void dump(Printer p0, String p1){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/ResolveInfo.java b/java/ql/test/stubs/android/android/content/pm/ResolveInfo.java new file mode 100644 index 00000000000..3ed20df0d38 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/ResolveInfo.java @@ -0,0 +1,42 @@ +// Generated automatically from android.content.pm.ResolveInfo for testing purposes + +package android.content.pm; + +import android.content.IntentFilter; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.ProviderInfo; +import android.content.pm.ServiceInfo; +import android.graphics.drawable.Drawable; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Printer; + +public class ResolveInfo implements Parcelable +{ + public ActivityInfo activityInfo = null; + public CharSequence loadLabel(PackageManager p0){ return null; } + public CharSequence nonLocalizedLabel = null; + public Drawable loadIcon(PackageManager p0){ return null; } + public IntentFilter filter = null; + public ProviderInfo providerInfo = null; + public ResolveInfo(){} + public ResolveInfo(ResolveInfo p0){} + public ServiceInfo serviceInfo = null; + public String resolvePackageName = null; + public String toString(){ return null; } + public boolean isCrossProfileIntentForwarderActivity(){ return false; } + public boolean isDefault = false; + public boolean isInstantAppAvailable = false; + public final int getIconResource(){ return 0; } + public int describeContents(){ return 0; } + public int icon = 0; + public int labelRes = 0; + public int match = 0; + public int preferredOrder = 0; + public int priority = 0; + public int specificIndex = 0; + public static Parcelable.Creator CREATOR = null; + public void dump(Printer p0, String p1){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/ServiceInfo.java b/java/ql/test/stubs/android/android/content/pm/ServiceInfo.java new file mode 100644 index 00000000000..6044d4af7bb --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/ServiceInfo.java @@ -0,0 +1,37 @@ +// Generated automatically from android.content.pm.ServiceInfo for testing purposes + +package android.content.pm; + +import android.content.pm.ComponentInfo; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Printer; + +public class ServiceInfo extends ComponentInfo implements Parcelable +{ + public ServiceInfo(){} + public ServiceInfo(ServiceInfo p0){} + public String permission = null; + public String toString(){ return null; } + public int describeContents(){ return 0; } + public int flags = 0; + public int getForegroundServiceType(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static int FLAG_EXTERNAL_SERVICE = 0; + public static int FLAG_ISOLATED_PROCESS = 0; + public static int FLAG_SINGLE_USER = 0; + public static int FLAG_STOP_WITH_TASK = 0; + public static int FLAG_USE_APP_ZYGOTE = 0; + public static int FOREGROUND_SERVICE_TYPE_CAMERA = 0; + public static int FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE = 0; + public static int FOREGROUND_SERVICE_TYPE_DATA_SYNC = 0; + public static int FOREGROUND_SERVICE_TYPE_LOCATION = 0; + public static int FOREGROUND_SERVICE_TYPE_MANIFEST = 0; + public static int FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK = 0; + public static int FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION = 0; + public static int FOREGROUND_SERVICE_TYPE_MICROPHONE = 0; + public static int FOREGROUND_SERVICE_TYPE_NONE = 0; + public static int FOREGROUND_SERVICE_TYPE_PHONE_CALL = 0; + public void dump(Printer p0, String p1){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/SharedLibraryInfo.java b/java/ql/test/stubs/android/android/content/pm/SharedLibraryInfo.java new file mode 100644 index 00000000000..10928af2a23 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/SharedLibraryInfo.java @@ -0,0 +1,26 @@ +// Generated automatically from android.content.pm.SharedLibraryInfo for testing purposes + +package android.content.pm; + +import android.content.pm.VersionedPackage; +import android.os.Parcel; +import android.os.Parcelable; +import java.util.List; + +public class SharedLibraryInfo implements Parcelable +{ + public List getDependentPackages(){ return null; } + public String getName(){ return null; } + public String toString(){ return null; } + public VersionedPackage getDeclaringPackage(){ return null; } + public int describeContents(){ return 0; } + public int getType(){ return 0; } + public int getVersion(){ return 0; } + public long getLongVersion(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static int TYPE_BUILTIN = 0; + public static int TYPE_DYNAMIC = 0; + public static int TYPE_STATIC = 0; + public static int VERSION_UNDEFINED = 0; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/Signature.java b/java/ql/test/stubs/android/android/content/pm/Signature.java new file mode 100644 index 00000000000..2f26fb9636e --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/Signature.java @@ -0,0 +1,22 @@ +// Generated automatically from android.content.pm.Signature for testing purposes + +package android.content.pm; + +import android.os.Parcel; +import android.os.Parcelable; + +public class Signature implements Parcelable +{ + protected Signature() {} + public Signature(String p0){} + public Signature(byte[] p0){} + public String toCharsString(){ return null; } + public boolean equals(Object p0){ return false; } + public byte[] toByteArray(){ return null; } + public char[] toChars(){ return null; } + public char[] toChars(char[] p0, int[] p1){ return null; } + public int describeContents(){ return 0; } + public int hashCode(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/SigningInfo.java b/java/ql/test/stubs/android/android/content/pm/SigningInfo.java new file mode 100644 index 00000000000..56aadea159a --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/SigningInfo.java @@ -0,0 +1,20 @@ +// Generated automatically from android.content.pm.SigningInfo for testing purposes + +package android.content.pm; + +import android.content.pm.Signature; +import android.os.Parcel; +import android.os.Parcelable; + +public class SigningInfo implements Parcelable +{ + public Signature[] getApkContentsSigners(){ return null; } + public Signature[] getSigningCertificateHistory(){ return null; } + public SigningInfo(){} + public SigningInfo(SigningInfo p0){} + public boolean hasMultipleSigners(){ return false; } + public boolean hasPastSigningCertificates(){ return false; } + public int describeContents(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/pm/VersionedPackage.java b/java/ql/test/stubs/android/android/content/pm/VersionedPackage.java new file mode 100644 index 00000000000..4d4e37f54bc --- /dev/null +++ b/java/ql/test/stubs/android/android/content/pm/VersionedPackage.java @@ -0,0 +1,22 @@ +// Generated automatically from android.content.pm.VersionedPackage for testing purposes + +package android.content.pm; + +import android.os.Parcel; +import android.os.Parcelable; + +public class VersionedPackage implements Parcelable +{ + protected VersionedPackage() {} + public String getPackageName(){ return null; } + public String toString(){ return null; } + public VersionedPackage(String p0, int p1){} + public VersionedPackage(String p0, long p1){} + public boolean equals(Object p0){ return false; } + public int describeContents(){ return 0; } + public int getVersionCode(){ return 0; } + public int hashCode(){ return 0; } + public long getLongVersionCode(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/res/AssetFileDescriptor.java b/java/ql/test/stubs/android/android/content/res/AssetFileDescriptor.java new file mode 100644 index 00000000000..46e0266dd62 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/res/AssetFileDescriptor.java @@ -0,0 +1,33 @@ +// Generated automatically from android.content.res.AssetFileDescriptor for testing purposes + +package android.content.res; + +import android.os.Bundle; +import android.os.Parcel; +import android.os.ParcelFileDescriptor; +import android.os.Parcelable; +import java.io.Closeable; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileOutputStream; + +public class AssetFileDescriptor implements Closeable, Parcelable +{ + protected AssetFileDescriptor() {} + public AssetFileDescriptor(ParcelFileDescriptor p0, long p1, long p2){} + public AssetFileDescriptor(ParcelFileDescriptor p0, long p1, long p2, Bundle p3){} + public Bundle getExtras(){ return null; } + public FileDescriptor getFileDescriptor(){ return null; } + public FileInputStream createInputStream(){ return null; } + public FileOutputStream createOutputStream(){ return null; } + public ParcelFileDescriptor getParcelFileDescriptor(){ return null; } + public String toString(){ return null; } + public int describeContents(){ return 0; } + public long getDeclaredLength(){ return 0; } + public long getLength(){ return 0; } + public long getStartOffset(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static long UNKNOWN_LENGTH = 0; + public void close(){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/res/AssetManager.java b/java/ql/test/stubs/android/android/content/res/AssetManager.java new file mode 100644 index 00000000000..37926aa5c61 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/res/AssetManager.java @@ -0,0 +1,26 @@ +// Generated automatically from android.content.res.AssetManager for testing purposes + +package android.content.res; + +import android.content.res.AssetFileDescriptor; +import android.content.res.XmlResourceParser; +import java.io.InputStream; + +public class AssetManager implements AutoCloseable +{ + protected void finalize(){} + public AssetFileDescriptor openFd(String p0){ return null; } + public AssetFileDescriptor openNonAssetFd(String p0){ return null; } + public AssetFileDescriptor openNonAssetFd(int p0, String p1){ return null; } + public InputStream open(String p0){ return null; } + public InputStream open(String p0, int p1){ return null; } + public String[] getLocales(){ return null; } + public String[] list(String p0){ return null; } + public XmlResourceParser openXmlResourceParser(String p0){ return null; } + public XmlResourceParser openXmlResourceParser(int p0, String p1){ return null; } + public static int ACCESS_BUFFER = 0; + public static int ACCESS_RANDOM = 0; + public static int ACCESS_STREAMING = 0; + public static int ACCESS_UNKNOWN = 0; + public void close(){} +} diff --git a/java/ql/test/stubs/android/android/content/res/ColorStateList.java b/java/ql/test/stubs/android/android/content/res/ColorStateList.java new file mode 100644 index 00000000000..cc6a1851767 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/res/ColorStateList.java @@ -0,0 +1,27 @@ +// Generated automatically from android.content.res.ColorStateList for testing purposes + +package android.content.res; + +import android.content.res.Resources; +import android.os.Parcel; +import android.os.Parcelable; +import org.xmlpull.v1.XmlPullParser; + +public class ColorStateList implements Parcelable +{ + protected ColorStateList() {} + public ColorStateList withAlpha(int p0){ return null; } + public ColorStateList(int[][] p0, int[] p1){} + public String toString(){ return null; } + public boolean isOpaque(){ return false; } + public boolean isStateful(){ return false; } + public int describeContents(){ return 0; } + public int getChangingConfigurations(){ return 0; } + public int getColorForState(int[] p0, int p1){ return 0; } + public int getDefaultColor(){ return 0; } + public static ColorStateList createFromXml(Resources p0, XmlPullParser p1){ return null; } + public static ColorStateList createFromXml(Resources p0, XmlPullParser p1, Resources.Theme p2){ return null; } + public static ColorStateList valueOf(int p0){ return null; } + public static Parcelable.Creator CREATOR = null; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/res/Configuration.java b/java/ql/test/stubs/android/android/content/res/Configuration.java new file mode 100644 index 00000000000..01c3f2a7d15 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/res/Configuration.java @@ -0,0 +1,130 @@ +// Generated automatically from android.content.res.Configuration for testing purposes + +package android.content.res; + +import android.os.LocaleList; +import android.os.Parcel; +import android.os.Parcelable; +import java.util.Locale; + +public class Configuration implements Comparable, Parcelable +{ + public Configuration(){} + public Configuration(Configuration p0){} + public Locale locale = null; + public LocaleList getLocales(){ return null; } + public String toString(){ return null; } + public boolean equals(Configuration p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isLayoutSizeAtLeast(int p0){ return false; } + public boolean isNightModeActive(){ return false; } + public boolean isScreenHdr(){ return false; } + public boolean isScreenRound(){ return false; } + public boolean isScreenWideColorGamut(){ return false; } + public float fontScale = 0; + public int colorMode = 0; + public int compareTo(Configuration p0){ return 0; } + public int densityDpi = 0; + public int describeContents(){ return 0; } + public int diff(Configuration p0){ return 0; } + public int getLayoutDirection(){ return 0; } + public int hardKeyboardHidden = 0; + public int hashCode(){ return 0; } + public int keyboard = 0; + public int keyboardHidden = 0; + public int mcc = 0; + public int mnc = 0; + public int navigation = 0; + public int navigationHidden = 0; + public int orientation = 0; + public int screenHeightDp = 0; + public int screenLayout = 0; + public int screenWidthDp = 0; + public int smallestScreenWidthDp = 0; + public int touchscreen = 0; + public int uiMode = 0; + public int updateFrom(Configuration p0){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static boolean needNewResources(int p0, int p1){ return false; } + public static int COLOR_MODE_HDR_MASK = 0; + public static int COLOR_MODE_HDR_NO = 0; + public static int COLOR_MODE_HDR_SHIFT = 0; + public static int COLOR_MODE_HDR_UNDEFINED = 0; + public static int COLOR_MODE_HDR_YES = 0; + public static int COLOR_MODE_UNDEFINED = 0; + public static int COLOR_MODE_WIDE_COLOR_GAMUT_MASK = 0; + public static int COLOR_MODE_WIDE_COLOR_GAMUT_NO = 0; + public static int COLOR_MODE_WIDE_COLOR_GAMUT_UNDEFINED = 0; + public static int COLOR_MODE_WIDE_COLOR_GAMUT_YES = 0; + public static int DENSITY_DPI_UNDEFINED = 0; + public static int HARDKEYBOARDHIDDEN_NO = 0; + public static int HARDKEYBOARDHIDDEN_UNDEFINED = 0; + public static int HARDKEYBOARDHIDDEN_YES = 0; + public static int KEYBOARDHIDDEN_NO = 0; + public static int KEYBOARDHIDDEN_UNDEFINED = 0; + public static int KEYBOARDHIDDEN_YES = 0; + public static int KEYBOARD_12KEY = 0; + public static int KEYBOARD_NOKEYS = 0; + public static int KEYBOARD_QWERTY = 0; + public static int KEYBOARD_UNDEFINED = 0; + public static int MNC_ZERO = 0; + public static int NAVIGATIONHIDDEN_NO = 0; + public static int NAVIGATIONHIDDEN_UNDEFINED = 0; + public static int NAVIGATIONHIDDEN_YES = 0; + public static int NAVIGATION_DPAD = 0; + public static int NAVIGATION_NONAV = 0; + public static int NAVIGATION_TRACKBALL = 0; + public static int NAVIGATION_UNDEFINED = 0; + public static int NAVIGATION_WHEEL = 0; + public static int ORIENTATION_LANDSCAPE = 0; + public static int ORIENTATION_PORTRAIT = 0; + public static int ORIENTATION_SQUARE = 0; + public static int ORIENTATION_UNDEFINED = 0; + public static int SCREENLAYOUT_LAYOUTDIR_LTR = 0; + public static int SCREENLAYOUT_LAYOUTDIR_MASK = 0; + public static int SCREENLAYOUT_LAYOUTDIR_RTL = 0; + public static int SCREENLAYOUT_LAYOUTDIR_SHIFT = 0; + public static int SCREENLAYOUT_LAYOUTDIR_UNDEFINED = 0; + public static int SCREENLAYOUT_LONG_MASK = 0; + public static int SCREENLAYOUT_LONG_NO = 0; + public static int SCREENLAYOUT_LONG_UNDEFINED = 0; + public static int SCREENLAYOUT_LONG_YES = 0; + public static int SCREENLAYOUT_ROUND_MASK = 0; + public static int SCREENLAYOUT_ROUND_NO = 0; + public static int SCREENLAYOUT_ROUND_UNDEFINED = 0; + public static int SCREENLAYOUT_ROUND_YES = 0; + public static int SCREENLAYOUT_SIZE_LARGE = 0; + public static int SCREENLAYOUT_SIZE_MASK = 0; + public static int SCREENLAYOUT_SIZE_NORMAL = 0; + public static int SCREENLAYOUT_SIZE_SMALL = 0; + public static int SCREENLAYOUT_SIZE_UNDEFINED = 0; + public static int SCREENLAYOUT_SIZE_XLARGE = 0; + public static int SCREENLAYOUT_UNDEFINED = 0; + public static int SCREEN_HEIGHT_DP_UNDEFINED = 0; + public static int SCREEN_WIDTH_DP_UNDEFINED = 0; + public static int SMALLEST_SCREEN_WIDTH_DP_UNDEFINED = 0; + public static int TOUCHSCREEN_FINGER = 0; + public static int TOUCHSCREEN_NOTOUCH = 0; + public static int TOUCHSCREEN_STYLUS = 0; + public static int TOUCHSCREEN_UNDEFINED = 0; + public static int UI_MODE_NIGHT_MASK = 0; + public static int UI_MODE_NIGHT_NO = 0; + public static int UI_MODE_NIGHT_UNDEFINED = 0; + public static int UI_MODE_NIGHT_YES = 0; + public static int UI_MODE_TYPE_APPLIANCE = 0; + public static int UI_MODE_TYPE_CAR = 0; + public static int UI_MODE_TYPE_DESK = 0; + public static int UI_MODE_TYPE_MASK = 0; + public static int UI_MODE_TYPE_NORMAL = 0; + public static int UI_MODE_TYPE_TELEVISION = 0; + public static int UI_MODE_TYPE_UNDEFINED = 0; + public static int UI_MODE_TYPE_VR_HEADSET = 0; + public static int UI_MODE_TYPE_WATCH = 0; + public void readFromParcel(Parcel p0){} + public void setLayoutDirection(Locale p0){} + public void setLocale(Locale p0){} + public void setLocales(LocaleList p0){} + public void setTo(Configuration p0){} + public void setToDefaults(){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/content/res/Resources.java b/java/ql/test/stubs/android/android/content/res/Resources.java new file mode 100644 index 00000000000..9277c4ee765 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/res/Resources.java @@ -0,0 +1,105 @@ +// Generated automatically from android.content.res.Resources for testing purposes + +package android.content.res; + +import android.content.res.AssetFileDescriptor; +import android.content.res.AssetManager; +import android.content.res.ColorStateList; +import android.content.res.Configuration; +import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; +import android.content.res.loader.ResourcesLoader; +import android.graphics.Movie; +import android.graphics.Typeface; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.util.TypedValue; +import java.io.InputStream; + +public class Resources +{ + protected Resources() {} + public AssetFileDescriptor openRawResourceFd(int p0){ return null; } + public CharSequence getQuantityText(int p0, int p1){ return null; } + public CharSequence getText(int p0){ return null; } + public CharSequence getText(int p0, CharSequence p1){ return null; } + public CharSequence[] getTextArray(int p0){ return null; } + public ColorStateList getColorStateList(int p0){ return null; } + public ColorStateList getColorStateList(int p0, Resources.Theme p1){ return null; } + public Configuration getConfiguration(){ return null; } + public DisplayMetrics getDisplayMetrics(){ return null; } + public Drawable getDrawable(int p0){ return null; } + public Drawable getDrawable(int p0, Resources.Theme p1){ return null; } + public Drawable getDrawableForDensity(int p0, int p1){ return null; } + public Drawable getDrawableForDensity(int p0, int p1, Resources.Theme p2){ return null; } + public InputStream openRawResource(int p0){ return null; } + public InputStream openRawResource(int p0, TypedValue p1){ return null; } + public Movie getMovie(int p0){ return null; } + public Resources(AssetManager p0, DisplayMetrics p1, Configuration p2){} + public String getQuantityString(int p0, int p1){ return null; } + public String getQuantityString(int p0, int p1, Object... p2){ return null; } + public String getResourceEntryName(int p0){ return null; } + public String getResourceName(int p0){ return null; } + public String getResourcePackageName(int p0){ return null; } + public String getResourceTypeName(int p0){ return null; } + public String getString(int p0){ return null; } + public String getString(int p0, Object... p1){ return null; } + public String[] getStringArray(int p0){ return null; } + public TypedArray obtainAttributes(AttributeSet p0, int[] p1){ return null; } + public TypedArray obtainTypedArray(int p0){ return null; } + public Typeface getFont(int p0){ return null; } + public XmlResourceParser getAnimation(int p0){ return null; } + public XmlResourceParser getLayout(int p0){ return null; } + public XmlResourceParser getXml(int p0){ return null; } + public boolean getBoolean(int p0){ return false; } + public class Theme + { + protected Theme() {} + public Drawable getDrawable(int p0){ return null; } + public Resources getResources(){ return null; } + public TypedArray obtainStyledAttributes(AttributeSet p0, int[] p1, int p2, int p3){ return null; } + public TypedArray obtainStyledAttributes(int p0, int[] p1){ return null; } + public TypedArray obtainStyledAttributes(int[] p0){ return null; } + public boolean resolveAttribute(int p0, TypedValue p1, boolean p2){ return false; } + public int getChangingConfigurations(){ return 0; } + public int getExplicitStyle(AttributeSet p0){ return 0; } + public int[] getAttributeResolutionStack(int p0, int p1, int p2){ return null; } + public void applyStyle(int p0, boolean p1){} + public void dump(int p0, String p1, String p2){} + public void rebase(){} + public void setTo(Resources.Theme p0){} + } + public final AssetManager getAssets(){ return null; } + public final Resources.Theme newTheme(){ return null; } + public final void finishPreloading(){} + public final void flushLayoutCache(){} + public float getDimension(int p0){ return 0; } + public float getFloat(int p0){ return 0; } + public float getFraction(int p0, int p1, int p2){ return 0; } + public int getColor(int p0){ return 0; } + public int getColor(int p0, Resources.Theme p1){ return 0; } + public int getDimensionPixelOffset(int p0){ return 0; } + public int getDimensionPixelSize(int p0){ return 0; } + public int getIdentifier(String p0, String p1, String p2){ return 0; } + public int getInteger(int p0){ return 0; } + public int[] getIntArray(int p0){ return null; } + public static Resources getSystem(){ return null; } + public static int ID_NULL = 0; + public static int getAttributeSetSourceResId(AttributeSet p0){ return 0; } + public void addLoaders(ResourcesLoader... p0){} + public void getValue(String p0, TypedValue p1, boolean p2){} + public void getValue(int p0, TypedValue p1, boolean p2){} + public void getValueForDensity(int p0, int p1, TypedValue p2, boolean p3){} + public void parseBundleExtra(String p0, AttributeSet p1, Bundle p2){} + public void parseBundleExtras(XmlResourceParser p0, Bundle p1){} + public void removeLoaders(ResourcesLoader... p0){} + public void updateConfiguration(Configuration p0, DisplayMetrics p1){} + static public class NotFoundException extends RuntimeException + { + public NotFoundException(){} + public NotFoundException(String p0){} + public NotFoundException(String p0, Exception p1){} + } +} diff --git a/java/ql/test/stubs/android/android/content/res/TypedArray.java b/java/ql/test/stubs/android/android/content/res/TypedArray.java new file mode 100644 index 00000000000..2b857671f88 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/res/TypedArray.java @@ -0,0 +1,46 @@ +// Generated automatically from android.content.res.TypedArray for testing purposes + +package android.content.res; + +import android.content.res.ColorStateList; +import android.content.res.Resources; +import android.graphics.Typeface; +import android.graphics.drawable.Drawable; +import android.util.TypedValue; + +public class TypedArray +{ + public CharSequence getText(int p0){ return null; } + public CharSequence[] getTextArray(int p0){ return null; } + public ColorStateList getColorStateList(int p0){ return null; } + public Drawable getDrawable(int p0){ return null; } + public Resources getResources(){ return null; } + public String getNonResourceString(int p0){ return null; } + public String getPositionDescription(){ return null; } + public String getString(int p0){ return null; } + public String toString(){ return null; } + public TypedValue peekValue(int p0){ return null; } + public Typeface getFont(int p0){ return null; } + public boolean getBoolean(int p0, boolean p1){ return false; } + public boolean getValue(int p0, TypedValue p1){ return false; } + public boolean hasValue(int p0){ return false; } + public boolean hasValueOrEmpty(int p0){ return false; } + public float getDimension(int p0, float p1){ return 0; } + public float getFloat(int p0, float p1){ return 0; } + public float getFraction(int p0, int p1, int p2, float p3){ return 0; } + public int getChangingConfigurations(){ return 0; } + public int getColor(int p0, int p1){ return 0; } + public int getDimensionPixelOffset(int p0, int p1){ return 0; } + public int getDimensionPixelSize(int p0, int p1){ return 0; } + public int getIndex(int p0){ return 0; } + public int getIndexCount(){ return 0; } + public int getInt(int p0, int p1){ return 0; } + public int getInteger(int p0, int p1){ return 0; } + public int getLayoutDimension(int p0, String p1){ return 0; } + public int getLayoutDimension(int p0, int p1){ return 0; } + public int getResourceId(int p0, int p1){ return 0; } + public int getSourceResourceId(int p0, int p1){ return 0; } + public int getType(int p0){ return 0; } + public int length(){ return 0; } + public void recycle(){} +} diff --git a/java/ql/test/stubs/android/android/content/res/XmlResourceParser.java b/java/ql/test/stubs/android/android/content/res/XmlResourceParser.java new file mode 100644 index 00000000000..61a50fe8bec --- /dev/null +++ b/java/ql/test/stubs/android/android/content/res/XmlResourceParser.java @@ -0,0 +1,12 @@ +// Generated automatically from android.content.res.XmlResourceParser for testing purposes + +package android.content.res; + +import android.util.AttributeSet; +import org.xmlpull.v1.XmlPullParser; + +public interface XmlResourceParser extends AttributeSet, AutoCloseable, XmlPullParser +{ + String getAttributeNamespace(int p0); + void close(); +} diff --git a/java/ql/test/stubs/android/android/content/res/loader/AssetsProvider.java b/java/ql/test/stubs/android/android/content/res/loader/AssetsProvider.java new file mode 100644 index 00000000000..bf99474dcb1 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/res/loader/AssetsProvider.java @@ -0,0 +1,10 @@ +// Generated automatically from android.content.res.loader.AssetsProvider for testing purposes + +package android.content.res.loader; + +import android.content.res.AssetFileDescriptor; + +public interface AssetsProvider +{ + default AssetFileDescriptor loadAssetFd(String p0, int p1){ return null; } +} diff --git a/java/ql/test/stubs/android/android/content/res/loader/ResourcesLoader.java b/java/ql/test/stubs/android/android/content/res/loader/ResourcesLoader.java new file mode 100644 index 00000000000..1ad577ab478 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/res/loader/ResourcesLoader.java @@ -0,0 +1,16 @@ +// Generated automatically from android.content.res.loader.ResourcesLoader for testing purposes + +package android.content.res.loader; + +import android.content.res.loader.ResourcesProvider; +import java.util.List; + +public class ResourcesLoader +{ + public List getProviders(){ return null; } + public ResourcesLoader(){} + public void addProvider(ResourcesProvider p0){} + public void clearProviders(){} + public void removeProvider(ResourcesProvider p0){} + public void setProviders(List p0){} +} diff --git a/java/ql/test/stubs/android/android/content/res/loader/ResourcesProvider.java b/java/ql/test/stubs/android/android/content/res/loader/ResourcesProvider.java new file mode 100644 index 00000000000..059b0961b59 --- /dev/null +++ b/java/ql/test/stubs/android/android/content/res/loader/ResourcesProvider.java @@ -0,0 +1,21 @@ +// Generated automatically from android.content.res.loader.ResourcesProvider for testing purposes + +package android.content.res.loader; + +import android.content.Context; +import android.content.res.loader.AssetsProvider; +import android.os.ParcelFileDescriptor; +import java.io.Closeable; + +public class ResourcesProvider implements AutoCloseable, Closeable +{ + protected ResourcesProvider() {} + protected void finalize(){} + public static ResourcesProvider empty(AssetsProvider p0){ return null; } + public static ResourcesProvider loadFromApk(ParcelFileDescriptor p0){ return null; } + public static ResourcesProvider loadFromApk(ParcelFileDescriptor p0, AssetsProvider p1){ return null; } + public static ResourcesProvider loadFromDirectory(String p0, AssetsProvider p1){ return null; } + public static ResourcesProvider loadFromSplit(Context p0, String p1){ return null; } + public static ResourcesProvider loadFromTable(ParcelFileDescriptor p0, AssetsProvider p1){ return null; } + public void close(){} +} diff --git a/java/ql/test/stubs/android/android/database/CharArrayBuffer.java b/java/ql/test/stubs/android/android/database/CharArrayBuffer.java new file mode 100644 index 00000000000..b75eff88239 --- /dev/null +++ b/java/ql/test/stubs/android/android/database/CharArrayBuffer.java @@ -0,0 +1,13 @@ +// Generated automatically from android.database.CharArrayBuffer for testing purposes + +package android.database; + + +public class CharArrayBuffer +{ + protected CharArrayBuffer() {} + public CharArrayBuffer(char[] p0){} + public CharArrayBuffer(int p0){} + public char[] data = null; + public int sizeCopied = 0; +} diff --git a/java/ql/test/stubs/android/android/database/ContentObserver.java b/java/ql/test/stubs/android/android/database/ContentObserver.java new file mode 100644 index 00000000000..f70e12dc20c --- /dev/null +++ b/java/ql/test/stubs/android/android/database/ContentObserver.java @@ -0,0 +1,22 @@ +// Generated automatically from android.database.ContentObserver for testing purposes + +package android.database; + +import android.net.Uri; +import android.os.Handler; +import java.util.Collection; + +abstract public class ContentObserver +{ + protected ContentObserver() {} + public ContentObserver(Handler p0){} + public boolean deliverSelfNotifications(){ return false; } + public final void dispatchChange(boolean p0){} + public final void dispatchChange(boolean p0, Collection p1, int p2){} + public final void dispatchChange(boolean p0, Uri p1){} + public final void dispatchChange(boolean p0, Uri p1, int p2){} + public void onChange(boolean p0){} + public void onChange(boolean p0, Collection p1, int p2){} + public void onChange(boolean p0, Uri p1){} + public void onChange(boolean p0, Uri p1, int p2){} +} diff --git a/java/ql/test/stubs/android/android/database/Cursor.java b/java/ql/test/stubs/android/android/database/Cursor.java index cc432b1ad06..e692f9be738 100644 --- a/java/ql/test/stubs/android/android/database/Cursor.java +++ b/java/ql/test/stubs/android/android/database/Cursor.java @@ -1,5 +1,64 @@ +// Generated automatically from android.database.Cursor for testing purposes + package android.database; -public interface Cursor { +import android.content.ContentResolver; +import android.database.CharArrayBuffer; +import android.database.ContentObserver; +import android.database.DataSetObserver; +import android.net.Uri; +import android.os.Bundle; +import java.io.Closeable; +import java.util.List; +public interface Cursor extends Closeable +{ + Bundle getExtras(); + Bundle respond(Bundle p0); + String getColumnName(int p0); + String getString(int p0); + String[] getColumnNames(); + Uri getNotificationUri(); + boolean getWantsAllOnMoveCalls(); + boolean isAfterLast(); + boolean isBeforeFirst(); + boolean isClosed(); + boolean isFirst(); + boolean isLast(); + boolean isNull(int p0); + boolean move(int p0); + boolean moveToFirst(); + boolean moveToLast(); + boolean moveToNext(); + boolean moveToPosition(int p0); + boolean moveToPrevious(); + boolean requery(); + byte[] getBlob(int p0); + default List getNotificationUris(){ return null; } + default void setNotificationUris(ContentResolver p0, List p1){} + double getDouble(int p0); + float getFloat(int p0); + int getColumnCount(); + int getColumnIndex(String p0); + int getColumnIndexOrThrow(String p0); + int getCount(); + int getInt(int p0); + int getPosition(); + int getType(int p0); + long getLong(int p0); + short getShort(int p0); + static int FIELD_TYPE_BLOB = 0; + static int FIELD_TYPE_FLOAT = 0; + static int FIELD_TYPE_INTEGER = 0; + static int FIELD_TYPE_NULL = 0; + static int FIELD_TYPE_STRING = 0; + void close(); + void copyStringToBuffer(int p0, CharArrayBuffer p1); + void deactivate(); + void registerContentObserver(ContentObserver p0); + void registerDataSetObserver(DataSetObserver p0); + void setExtras(Bundle p0); + void setNotificationUri(ContentResolver p0, Uri p1); + void unregisterContentObserver(ContentObserver p0); + void unregisterDataSetObserver(DataSetObserver p0); } diff --git a/java/ql/test/stubs/android/android/database/DataSetObserver.java b/java/ql/test/stubs/android/android/database/DataSetObserver.java new file mode 100644 index 00000000000..6ca449b2e95 --- /dev/null +++ b/java/ql/test/stubs/android/android/database/DataSetObserver.java @@ -0,0 +1,11 @@ +// Generated automatically from android.database.DataSetObserver for testing purposes + +package android.database; + + +abstract public class DataSetObserver +{ + public DataSetObserver(){} + public void onChanged(){} + public void onInvalidated(){} +} diff --git a/java/ql/test/stubs/android/android/database/DatabaseErrorHandler.java b/java/ql/test/stubs/android/android/database/DatabaseErrorHandler.java new file mode 100644 index 00000000000..c52eb9698a7 --- /dev/null +++ b/java/ql/test/stubs/android/android/database/DatabaseErrorHandler.java @@ -0,0 +1,10 @@ +// Generated automatically from android.database.DatabaseErrorHandler for testing purposes + +package android.database; + +import android.database.sqlite.SQLiteDatabase; + +public interface DatabaseErrorHandler +{ + void onCorruption(SQLiteDatabase p0); +} diff --git a/java/ql/test/stubs/android/android/database/sqlite/SQLiteClosable.java b/java/ql/test/stubs/android/android/database/sqlite/SQLiteClosable.java new file mode 100644 index 00000000000..8295e8d0d61 --- /dev/null +++ b/java/ql/test/stubs/android/android/database/sqlite/SQLiteClosable.java @@ -0,0 +1,16 @@ +// Generated automatically from android.database.sqlite.SQLiteClosable for testing purposes + +package android.database.sqlite; + +import java.io.Closeable; + +abstract public class SQLiteClosable implements Closeable +{ + protected abstract void onAllReferencesReleased(); + protected void onAllReferencesReleasedFromContainer(){} + public SQLiteClosable(){} + public void acquireReference(){} + public void close(){} + public void releaseReference(){} + public void releaseReferenceFromContainer(){} +} diff --git a/java/ql/test/stubs/android/android/database/sqlite/SQLiteCursorDriver.java b/java/ql/test/stubs/android/android/database/sqlite/SQLiteCursorDriver.java new file mode 100644 index 00000000000..3d5cb99a2d0 --- /dev/null +++ b/java/ql/test/stubs/android/android/database/sqlite/SQLiteCursorDriver.java @@ -0,0 +1,15 @@ +// Generated automatically from android.database.sqlite.SQLiteCursorDriver for testing purposes + +package android.database.sqlite; + +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; + +public interface SQLiteCursorDriver +{ + Cursor query(SQLiteDatabase.CursorFactory p0, String[] p1); + void cursorClosed(); + void cursorDeactivated(); + void cursorRequeried(Cursor p0); + void setBindArguments(String[] p0); +} diff --git a/java/ql/test/stubs/android/android/database/sqlite/SQLiteDatabase.java b/java/ql/test/stubs/android/android/database/sqlite/SQLiteDatabase.java index 6f5b6bd2eea..64b62e68d44 100644 --- a/java/ql/test/stubs/android/android/database/sqlite/SQLiteDatabase.java +++ b/java/ql/test/stubs/android/android/database/sqlite/SQLiteDatabase.java @@ -1,56 +1,127 @@ +// Generated automatically from android.database.sqlite.SQLiteDatabase for testing purposes + package android.database.sqlite; import android.content.ContentValues; +import android.database.Cursor; +import android.database.DatabaseErrorHandler; +import android.database.sqlite.SQLiteClosable; +import android.database.sqlite.SQLiteCursorDriver; +import android.database.sqlite.SQLiteQuery; +import android.database.sqlite.SQLiteStatement; +import android.database.sqlite.SQLiteTransactionListener; import android.os.CancellationSignal; +import android.util.Pair; +import java.io.File; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.function.BinaryOperator; +import java.util.function.UnaryOperator; -public abstract class SQLiteDatabase { - public class CursorFactory { - - } - - public abstract void execPerConnectionSQL(String sql, Object[] bindArgs); - - public abstract void execSQL(String sql); - - public abstract void execSQL(String sql, Object[] bindArgs); - - public abstract void query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, - String groupBy, String having, String orderBy, String limit); - - public abstract void query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, - String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal); - - public abstract void query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, - String having, String orderBy, String limit); - - public abstract void query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, - String having, String orderBy); - - public abstract void queryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, - String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, - String limit, CancellationSignal cancellationSignal); - - public abstract void queryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, - String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, - String limit); - - public abstract void rawQuery(String sql, String[] selectionArgs, CancellationSignal cancellationSignal); - - public abstract void rawQuery(String sql, String[] selectionArgs); - - public abstract void rawQueryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, String sql, String[] selectionArgs, - String editTable, CancellationSignal cancellationSignal); - - public abstract void rawQueryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, String sql, String[] selectionArgs, - String editTable); - - public abstract void compileStatement(String sql); - - public abstract void delete(String table, String whereClause, String[] whereArgs); - - public abstract void update(String table, ContentValues values, String whereClause, String[] whereArgs); - - public abstract void updateWithOnConflict(String table, ContentValues values, String whereClause, String[] whereArgs, - int conflictAlgorithm); - +public class SQLiteDatabase extends SQLiteClosable +{ + protected SQLiteDatabase() {} + protected void finalize(){} + protected void onAllReferencesReleased(){} + public Cursor query(String p0, String[] p1, String p2, String[] p3, String p4, String p5, String p6){ return null; } + public Cursor query(String p0, String[] p1, String p2, String[] p3, String p4, String p5, String p6, String p7){ return null; } + public Cursor query(boolean p0, String p1, String[] p2, String p3, String[] p4, String p5, String p6, String p7, String p8){ return null; } + public Cursor query(boolean p0, String p1, String[] p2, String p3, String[] p4, String p5, String p6, String p7, String p8, CancellationSignal p9){ return null; } + public Cursor queryWithFactory(SQLiteDatabase.CursorFactory p0, boolean p1, String p2, String[] p3, String p4, String[] p5, String p6, String p7, String p8, String p9){ return null; } + public Cursor queryWithFactory(SQLiteDatabase.CursorFactory p0, boolean p1, String p2, String[] p3, String p4, String[] p5, String p6, String p7, String p8, String p9, CancellationSignal p10){ return null; } + public Cursor rawQuery(String p0, String[] p1){ return null; } + public Cursor rawQuery(String p0, String[] p1, CancellationSignal p2){ return null; } + public Cursor rawQueryWithFactory(SQLiteDatabase.CursorFactory p0, String p1, String[] p2, String p3){ return null; } + public Cursor rawQueryWithFactory(SQLiteDatabase.CursorFactory p0, String p1, String[] p2, String p3, CancellationSignal p4){ return null; } + public List> getAttachedDbs(){ return null; } + public Map getSyncedTables(){ return null; } + public SQLiteStatement compileStatement(String p0){ return null; } + public String getPath(){ return null; } + public String toString(){ return null; } + public boolean enableWriteAheadLogging(){ return false; } + public boolean inTransaction(){ return false; } + public boolean isDatabaseIntegrityOk(){ return false; } + public boolean isDbLockedByCurrentThread(){ return false; } + public boolean isDbLockedByOtherThreads(){ return false; } + public boolean isOpen(){ return false; } + public boolean isReadOnly(){ return false; } + public boolean isWriteAheadLoggingEnabled(){ return false; } + public boolean needUpgrade(int p0){ return false; } + public boolean yieldIfContended(){ return false; } + public boolean yieldIfContendedSafely(){ return false; } + public boolean yieldIfContendedSafely(long p0){ return false; } + public int delete(String p0, String p1, String[] p2){ return 0; } + public int getVersion(){ return 0; } + public int update(String p0, ContentValues p1, String p2, String[] p3){ return 0; } + public int updateWithOnConflict(String p0, ContentValues p1, String p2, String[] p3, int p4){ return 0; } + public long getMaximumSize(){ return 0; } + public long getPageSize(){ return 0; } + public long insert(String p0, String p1, ContentValues p2){ return 0; } + public long insertOrThrow(String p0, String p1, ContentValues p2){ return 0; } + public long insertWithOnConflict(String p0, String p1, ContentValues p2, int p3){ return 0; } + public long replace(String p0, String p1, ContentValues p2){ return 0; } + public long replaceOrThrow(String p0, String p1, ContentValues p2){ return 0; } + public long setMaximumSize(long p0){ return 0; } + public static SQLiteDatabase create(SQLiteDatabase.CursorFactory p0){ return null; } + public static SQLiteDatabase createInMemory(SQLiteDatabase.OpenParams p0){ return null; } + public static SQLiteDatabase openDatabase(File p0, SQLiteDatabase.OpenParams p1){ return null; } + public static SQLiteDatabase openDatabase(String p0, SQLiteDatabase.CursorFactory p1, int p2){ return null; } + public static SQLiteDatabase openDatabase(String p0, SQLiteDatabase.CursorFactory p1, int p2, DatabaseErrorHandler p3){ return null; } + public static SQLiteDatabase openOrCreateDatabase(File p0, SQLiteDatabase.CursorFactory p1){ return null; } + public static SQLiteDatabase openOrCreateDatabase(String p0, SQLiteDatabase.CursorFactory p1){ return null; } + public static SQLiteDatabase openOrCreateDatabase(String p0, SQLiteDatabase.CursorFactory p1, DatabaseErrorHandler p2){ return null; } + public static String findEditTable(String p0){ return null; } + public static boolean deleteDatabase(File p0){ return false; } + public static int CONFLICT_ABORT = 0; + public static int CONFLICT_FAIL = 0; + public static int CONFLICT_IGNORE = 0; + public static int CONFLICT_NONE = 0; + public static int CONFLICT_REPLACE = 0; + public static int CONFLICT_ROLLBACK = 0; + public static int CREATE_IF_NECESSARY = 0; + public static int ENABLE_WRITE_AHEAD_LOGGING = 0; + public static int MAX_SQL_CACHE_SIZE = 0; + public static int NO_LOCALIZED_COLLATORS = 0; + public static int OPEN_READONLY = 0; + public static int OPEN_READWRITE = 0; + public static int SQLITE_MAX_LIKE_PATTERN_LENGTH = 0; + public static int releaseMemory(){ return 0; } + public void beginTransaction(){} + public void beginTransactionNonExclusive(){} + public void beginTransactionWithListener(SQLiteTransactionListener p0){} + public void beginTransactionWithListenerNonExclusive(SQLiteTransactionListener p0){} + public void disableWriteAheadLogging(){} + public void endTransaction(){} + public void execPerConnectionSQL(String p0, Object[] p1){} + public void execSQL(String p0){} + public void execSQL(String p0, Object[] p1){} + public void markTableSyncable(String p0, String p1){} + public void markTableSyncable(String p0, String p1, String p2){} + public void setCustomAggregateFunction(String p0, BinaryOperator p1){} + public void setCustomScalarFunction(String p0, UnaryOperator p1){} + public void setForeignKeyConstraintsEnabled(boolean p0){} + public void setLocale(Locale p0){} + public void setLockingEnabled(boolean p0){} + public void setMaxSqlCacheSize(int p0){} + public void setPageSize(long p0){} + public void setTransactionSuccessful(){} + public void setVersion(int p0){} + public void validateSql(String p0, CancellationSignal p1){} + static public class OpenParams + { + protected OpenParams() {} + public DatabaseErrorHandler getErrorHandler(){ return null; } + public SQLiteDatabase.CursorFactory getCursorFactory(){ return null; } + public String getJournalMode(){ return null; } + public String getSynchronousMode(){ return null; } + public int getLookasideSlotCount(){ return 0; } + public int getLookasideSlotSize(){ return 0; } + public int getOpenFlags(){ return 0; } + public long getIdleConnectionTimeout(){ return 0; } + } + static public interface CursorFactory + { + Cursor newCursor(SQLiteDatabase p0, SQLiteCursorDriver p1, String p2, SQLiteQuery p3); + } } diff --git a/java/ql/test/stubs/android/android/database/sqlite/SQLiteProgram.java b/java/ql/test/stubs/android/android/database/sqlite/SQLiteProgram.java new file mode 100644 index 00000000000..15f078a4c16 --- /dev/null +++ b/java/ql/test/stubs/android/android/database/sqlite/SQLiteProgram.java @@ -0,0 +1,18 @@ +// Generated automatically from android.database.sqlite.SQLiteProgram for testing purposes + +package android.database.sqlite; + +import android.database.sqlite.SQLiteClosable; + +abstract public class SQLiteProgram extends SQLiteClosable +{ + protected void onAllReferencesReleased(){} + public final int getUniqueId(){ return 0; } + public void bindAllArgsAsStrings(String[] p0){} + public void bindBlob(int p0, byte[] p1){} + public void bindDouble(int p0, double p1){} + public void bindLong(int p0, long p1){} + public void bindNull(int p0){} + public void bindString(int p0, String p1){} + public void clearBindings(){} +} diff --git a/java/ql/test/stubs/android/android/database/sqlite/SQLiteQuery.java b/java/ql/test/stubs/android/android/database/sqlite/SQLiteQuery.java new file mode 100644 index 00000000000..a2169bcf238 --- /dev/null +++ b/java/ql/test/stubs/android/android/database/sqlite/SQLiteQuery.java @@ -0,0 +1,10 @@ +// Generated automatically from android.database.sqlite.SQLiteQuery for testing purposes + +package android.database.sqlite; + +import android.database.sqlite.SQLiteProgram; + +public class SQLiteQuery extends SQLiteProgram +{ + public String toString(){ return null; } +} diff --git a/java/ql/test/stubs/android/android/database/sqlite/SQLiteStatement.java b/java/ql/test/stubs/android/android/database/sqlite/SQLiteStatement.java new file mode 100644 index 00000000000..e96a0d28725 --- /dev/null +++ b/java/ql/test/stubs/android/android/database/sqlite/SQLiteStatement.java @@ -0,0 +1,17 @@ +// Generated automatically from android.database.sqlite.SQLiteStatement for testing purposes + +package android.database.sqlite; + +import android.database.sqlite.SQLiteProgram; +import android.os.ParcelFileDescriptor; + +public class SQLiteStatement extends SQLiteProgram +{ + public ParcelFileDescriptor simpleQueryForBlobFileDescriptor(){ return null; } + public String simpleQueryForString(){ return null; } + public String toString(){ return null; } + public int executeUpdateDelete(){ return 0; } + public long executeInsert(){ return 0; } + public long simpleQueryForLong(){ return 0; } + public void execute(){} +} diff --git a/java/ql/test/stubs/android/android/database/sqlite/SQLiteTransactionListener.java b/java/ql/test/stubs/android/android/database/sqlite/SQLiteTransactionListener.java new file mode 100644 index 00000000000..31895691b11 --- /dev/null +++ b/java/ql/test/stubs/android/android/database/sqlite/SQLiteTransactionListener.java @@ -0,0 +1,11 @@ +// Generated automatically from android.database.sqlite.SQLiteTransactionListener for testing purposes + +package android.database.sqlite; + + +public interface SQLiteTransactionListener +{ + void onBegin(); + void onCommit(); + void onRollback(); +} diff --git a/java/ql/test/stubs/android/android/graphics/Bitmap.java b/java/ql/test/stubs/android/android/graphics/Bitmap.java new file mode 100644 index 00000000000..cf7a3b69176 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/Bitmap.java @@ -0,0 +1,97 @@ +// Generated automatically from android.graphics.Bitmap for testing purposes + +package android.graphics; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorSpace; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.Picture; +import android.hardware.HardwareBuffer; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.DisplayMetrics; +import java.io.OutputStream; +import java.nio.Buffer; + +public class Bitmap implements Parcelable +{ + public Bitmap copy(Bitmap.Config p0, boolean p1){ return null; } + public Bitmap extractAlpha(){ return null; } + public Bitmap extractAlpha(Paint p0, int[] p1){ return null; } + public Bitmap.Config getConfig(){ return null; } + public Color getColor(int p0, int p1){ return null; } + public ColorSpace getColorSpace(){ return null; } + public boolean compress(Bitmap.CompressFormat p0, int p1, OutputStream p2){ return false; } + public boolean hasAlpha(){ return false; } + public boolean hasMipMap(){ return false; } + public boolean isMutable(){ return false; } + public boolean isPremultiplied(){ return false; } + public boolean isRecycled(){ return false; } + public boolean sameAs(Bitmap p0){ return false; } + public byte[] getNinePatchChunk(){ return null; } + public int describeContents(){ return 0; } + public int getAllocationByteCount(){ return 0; } + public int getByteCount(){ return 0; } + public int getDensity(){ return 0; } + public int getGenerationId(){ return 0; } + public int getHeight(){ return 0; } + public int getPixel(int p0, int p1){ return 0; } + public int getRowBytes(){ return 0; } + public int getScaledHeight(Canvas p0){ return 0; } + public int getScaledHeight(DisplayMetrics p0){ return 0; } + public int getScaledHeight(int p0){ return 0; } + public int getScaledWidth(Canvas p0){ return 0; } + public int getScaledWidth(DisplayMetrics p0){ return 0; } + public int getScaledWidth(int p0){ return 0; } + public int getWidth(){ return 0; } + public static Bitmap createBitmap(Bitmap p0){ return null; } + public static Bitmap createBitmap(Bitmap p0, int p1, int p2, int p3, int p4){ return null; } + public static Bitmap createBitmap(Bitmap p0, int p1, int p2, int p3, int p4, Matrix p5, boolean p6){ return null; } + public static Bitmap createBitmap(DisplayMetrics p0, int p1, int p2, Bitmap.Config p3){ return null; } + public static Bitmap createBitmap(DisplayMetrics p0, int p1, int p2, Bitmap.Config p3, boolean p4){ return null; } + public static Bitmap createBitmap(DisplayMetrics p0, int p1, int p2, Bitmap.Config p3, boolean p4, ColorSpace p5){ return null; } + public static Bitmap createBitmap(DisplayMetrics p0, int[] p1, int p2, int p3, Bitmap.Config p4){ return null; } + public static Bitmap createBitmap(DisplayMetrics p0, int[] p1, int p2, int p3, int p4, int p5, Bitmap.Config p6){ return null; } + public static Bitmap createBitmap(Picture p0){ return null; } + public static Bitmap createBitmap(Picture p0, int p1, int p2, Bitmap.Config p3){ return null; } + public static Bitmap createBitmap(int p0, int p1, Bitmap.Config p2){ return null; } + public static Bitmap createBitmap(int p0, int p1, Bitmap.Config p2, boolean p3){ return null; } + public static Bitmap createBitmap(int p0, int p1, Bitmap.Config p2, boolean p3, ColorSpace p4){ return null; } + public static Bitmap createBitmap(int[] p0, int p1, int p2, Bitmap.Config p3){ return null; } + public static Bitmap createBitmap(int[] p0, int p1, int p2, int p3, int p4, Bitmap.Config p5){ return null; } + public static Bitmap createScaledBitmap(Bitmap p0, int p1, int p2, boolean p3){ return null; } + public static Bitmap wrapHardwareBuffer(HardwareBuffer p0, ColorSpace p1){ return null; } + public static Parcelable.Creator CREATOR = null; + public static int DENSITY_NONE = 0; + public void copyPixelsFromBuffer(Buffer p0){} + public void copyPixelsToBuffer(Buffer p0){} + public void eraseColor(int p0){} + public void eraseColor(long p0){} + public void getPixels(int[] p0, int p1, int p2, int p3, int p4, int p5, int p6){} + public void prepareToDraw(){} + public void reconfigure(int p0, int p1, Bitmap.Config p2){} + public void recycle(){} + public void setColorSpace(ColorSpace p0){} + public void setConfig(Bitmap.Config p0){} + public void setDensity(int p0){} + public void setHasAlpha(boolean p0){} + public void setHasMipMap(boolean p0){} + public void setHeight(int p0){} + public void setPixel(int p0, int p1, int p2){} + public void setPixels(int[] p0, int p1, int p2, int p3, int p4, int p5, int p6){} + public void setPremultiplied(boolean p0){} + public void setWidth(int p0){} + public void writeToParcel(Parcel p0, int p1){} + static public enum CompressFormat + { + JPEG, PNG, WEBP, WEBP_LOSSLESS, WEBP_LOSSY; + private CompressFormat() {} + } + static public enum Config + { + ALPHA_8, ARGB_4444, ARGB_8888, HARDWARE, RGBA_F16, RGB_565; + private Config() {} + } +} diff --git a/java/ql/test/stubs/android/android/graphics/BitmapFactory.java b/java/ql/test/stubs/android/android/graphics/BitmapFactory.java new file mode 100644 index 00000000000..f6e05c10de9 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/BitmapFactory.java @@ -0,0 +1,54 @@ +// Generated automatically from android.graphics.BitmapFactory for testing purposes + +package android.graphics; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.ColorSpace; +import android.graphics.Rect; +import android.util.TypedValue; +import java.io.FileDescriptor; +import java.io.InputStream; + +public class BitmapFactory +{ + public BitmapFactory(){} + public static Bitmap decodeByteArray(byte[] p0, int p1, int p2){ return null; } + public static Bitmap decodeByteArray(byte[] p0, int p1, int p2, BitmapFactory.Options p3){ return null; } + public static Bitmap decodeFile(String p0){ return null; } + public static Bitmap decodeFile(String p0, BitmapFactory.Options p1){ return null; } + public static Bitmap decodeFileDescriptor(FileDescriptor p0){ return null; } + public static Bitmap decodeFileDescriptor(FileDescriptor p0, Rect p1, BitmapFactory.Options p2){ return null; } + public static Bitmap decodeResource(Resources p0, int p1){ return null; } + public static Bitmap decodeResource(Resources p0, int p1, BitmapFactory.Options p2){ return null; } + public static Bitmap decodeResourceStream(Resources p0, TypedValue p1, InputStream p2, Rect p3, BitmapFactory.Options p4){ return null; } + public static Bitmap decodeStream(InputStream p0){ return null; } + public static Bitmap decodeStream(InputStream p0, Rect p1, BitmapFactory.Options p2){ return null; } + static public class Options + { + public Bitmap inBitmap = null; + public Bitmap.Config inPreferredConfig = null; + public Bitmap.Config outConfig = null; + public ColorSpace inPreferredColorSpace = null; + public ColorSpace outColorSpace = null; + public Options(){} + public String outMimeType = null; + public boolean inDither = false; + public boolean inInputShareable = false; + public boolean inJustDecodeBounds = false; + public boolean inMutable = false; + public boolean inPreferQualityOverSpeed = false; + public boolean inPremultiplied = false; + public boolean inPurgeable = false; + public boolean inScaled = false; + public boolean mCancel = false; + public byte[] inTempStorage = null; + public int inDensity = 0; + public int inSampleSize = 0; + public int inScreenDensity = 0; + public int inTargetDensity = 0; + public int outHeight = 0; + public int outWidth = 0; + public void requestCancelDecode(){} + } +} diff --git a/java/ql/test/stubs/android/android/graphics/BlendMode.java b/java/ql/test/stubs/android/android/graphics/BlendMode.java new file mode 100644 index 00000000000..32510e36bdd --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/BlendMode.java @@ -0,0 +1,10 @@ +// Generated automatically from android.graphics.BlendMode for testing purposes + +package android.graphics; + + +public enum BlendMode +{ + CLEAR, COLOR, COLOR_BURN, COLOR_DODGE, DARKEN, DIFFERENCE, DST, DST_ATOP, DST_IN, DST_OUT, DST_OVER, EXCLUSION, HARD_LIGHT, HUE, LIGHTEN, LUMINOSITY, MODULATE, MULTIPLY, OVERLAY, PLUS, SATURATION, SCREEN, SOFT_LIGHT, SRC, SRC_ATOP, SRC_IN, SRC_OUT, SRC_OVER, XOR; + private BlendMode() {} +} diff --git a/java/ql/test/stubs/android/android/graphics/Canvas.java b/java/ql/test/stubs/android/android/graphics/Canvas.java new file mode 100644 index 00000000000..26c4536a2aa --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/Canvas.java @@ -0,0 +1,141 @@ +// Generated automatically from android.graphics.Canvas for testing purposes + +package android.graphics; + +import android.graphics.Bitmap; +import android.graphics.BlendMode; +import android.graphics.DrawFilter; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.Picture; +import android.graphics.PorterDuff; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.Region; +import android.graphics.RenderNode; +import android.graphics.text.MeasuredText; + +public class Canvas +{ + public Canvas(){} + public Canvas(Bitmap p0){} + public DrawFilter getDrawFilter(){ return null; } + public boolean clipOutPath(Path p0){ return false; } + public boolean clipOutRect(Rect p0){ return false; } + public boolean clipOutRect(RectF p0){ return false; } + public boolean clipOutRect(float p0, float p1, float p2, float p3){ return false; } + public boolean clipOutRect(int p0, int p1, int p2, int p3){ return false; } + public boolean clipPath(Path p0){ return false; } + public boolean clipPath(Path p0, Region.Op p1){ return false; } + public boolean clipRect(Rect p0){ return false; } + public boolean clipRect(Rect p0, Region.Op p1){ return false; } + public boolean clipRect(RectF p0){ return false; } + public boolean clipRect(RectF p0, Region.Op p1){ return false; } + public boolean clipRect(float p0, float p1, float p2, float p3){ return false; } + public boolean clipRect(float p0, float p1, float p2, float p3, Region.Op p4){ return false; } + public boolean clipRect(int p0, int p1, int p2, int p3){ return false; } + public boolean getClipBounds(Rect p0){ return false; } + public boolean isHardwareAccelerated(){ return false; } + public boolean isOpaque(){ return false; } + public boolean quickReject(Path p0){ return false; } + public boolean quickReject(Path p0, Canvas.EdgeType p1){ return false; } + public boolean quickReject(RectF p0){ return false; } + public boolean quickReject(RectF p0, Canvas.EdgeType p1){ return false; } + public boolean quickReject(float p0, float p1, float p2, float p3){ return false; } + public boolean quickReject(float p0, float p1, float p2, float p3, Canvas.EdgeType p4){ return false; } + public final Matrix getMatrix(){ return null; } + public final Rect getClipBounds(){ return null; } + public final void rotate(float p0, float p1, float p2){} + public final void scale(float p0, float p1, float p2, float p3){} + public int getDensity(){ return 0; } + public int getHeight(){ return 0; } + public int getMaximumBitmapHeight(){ return 0; } + public int getMaximumBitmapWidth(){ return 0; } + public int getSaveCount(){ return 0; } + public int getWidth(){ return 0; } + public int save(){ return 0; } + public int saveLayer(RectF p0, Paint p1){ return 0; } + public int saveLayer(RectF p0, Paint p1, int p2){ return 0; } + public int saveLayer(float p0, float p1, float p2, float p3, Paint p4){ return 0; } + public int saveLayer(float p0, float p1, float p2, float p3, Paint p4, int p5){ return 0; } + public int saveLayerAlpha(RectF p0, int p1){ return 0; } + public int saveLayerAlpha(RectF p0, int p1, int p2){ return 0; } + public int saveLayerAlpha(float p0, float p1, float p2, float p3, int p4){ return 0; } + public int saveLayerAlpha(float p0, float p1, float p2, float p3, int p4, int p5){ return 0; } + public static int ALL_SAVE_FLAG = 0; + public void concat(Matrix p0){} + public void disableZ(){} + public void drawARGB(int p0, int p1, int p2, int p3){} + public void drawArc(RectF p0, float p1, float p2, boolean p3, Paint p4){} + public void drawArc(float p0, float p1, float p2, float p3, float p4, float p5, boolean p6, Paint p7){} + public void drawBitmap(Bitmap p0, Matrix p1, Paint p2){} + public void drawBitmap(Bitmap p0, Rect p1, Rect p2, Paint p3){} + public void drawBitmap(Bitmap p0, Rect p1, RectF p2, Paint p3){} + public void drawBitmap(Bitmap p0, float p1, float p2, Paint p3){} + public void drawBitmap(int[] p0, int p1, int p2, float p3, float p4, int p5, int p6, boolean p7, Paint p8){} + public void drawBitmap(int[] p0, int p1, int p2, int p3, int p4, int p5, int p6, boolean p7, Paint p8){} + public void drawBitmapMesh(Bitmap p0, int p1, int p2, float[] p3, int p4, int[] p5, int p6, Paint p7){} + public void drawCircle(float p0, float p1, float p2, Paint p3){} + public void drawColor(int p0){} + public void drawColor(int p0, BlendMode p1){} + public void drawColor(int p0, PorterDuff.Mode p1){} + public void drawColor(long p0){} + public void drawColor(long p0, BlendMode p1){} + public void drawDoubleRoundRect(RectF p0, float p1, float p2, RectF p3, float p4, float p5, Paint p6){} + public void drawDoubleRoundRect(RectF p0, float[] p1, RectF p2, float[] p3, Paint p4){} + public void drawLine(float p0, float p1, float p2, float p3, Paint p4){} + public void drawLines(float[] p0, Paint p1){} + public void drawLines(float[] p0, int p1, int p2, Paint p3){} + public void drawOval(RectF p0, Paint p1){} + public void drawOval(float p0, float p1, float p2, float p3, Paint p4){} + public void drawPaint(Paint p0){} + public void drawPath(Path p0, Paint p1){} + public void drawPicture(Picture p0){} + public void drawPicture(Picture p0, Rect p1){} + public void drawPicture(Picture p0, RectF p1){} + public void drawPoint(float p0, float p1, Paint p2){} + public void drawPoints(float[] p0, Paint p1){} + public void drawPoints(float[] p0, int p1, int p2, Paint p3){} + public void drawPosText(String p0, float[] p1, Paint p2){} + public void drawPosText(char[] p0, int p1, int p2, float[] p3, Paint p4){} + public void drawRGB(int p0, int p1, int p2){} + public void drawRect(Rect p0, Paint p1){} + public void drawRect(RectF p0, Paint p1){} + public void drawRect(float p0, float p1, float p2, float p3, Paint p4){} + public void drawRenderNode(RenderNode p0){} + public void drawRoundRect(RectF p0, float p1, float p2, Paint p3){} + public void drawRoundRect(float p0, float p1, float p2, float p3, float p4, float p5, Paint p6){} + public void drawText(CharSequence p0, int p1, int p2, float p3, float p4, Paint p5){} + public void drawText(String p0, float p1, float p2, Paint p3){} + public void drawText(String p0, int p1, int p2, float p3, float p4, Paint p5){} + public void drawText(char[] p0, int p1, int p2, float p3, float p4, Paint p5){} + public void drawTextOnPath(String p0, Path p1, float p2, float p3, Paint p4){} + public void drawTextOnPath(char[] p0, int p1, int p2, Path p3, float p4, float p5, Paint p6){} + public void drawTextRun(CharSequence p0, int p1, int p2, int p3, int p4, float p5, float p6, boolean p7, Paint p8){} + public void drawTextRun(MeasuredText p0, int p1, int p2, int p3, int p4, float p5, float p6, boolean p7, Paint p8){} + public void drawTextRun(char[] p0, int p1, int p2, int p3, int p4, float p5, float p6, boolean p7, Paint p8){} + public void drawVertices(Canvas.VertexMode p0, int p1, float[] p2, int p3, float[] p4, int p5, int[] p6, int p7, short[] p8, int p9, int p10, Paint p11){} + public void enableZ(){} + public void getMatrix(Matrix p0){} + public void restore(){} + public void restoreToCount(int p0){} + public void rotate(float p0){} + public void scale(float p0, float p1){} + public void setBitmap(Bitmap p0){} + public void setDensity(int p0){} + public void setDrawFilter(DrawFilter p0){} + public void setMatrix(Matrix p0){} + public void skew(float p0, float p1){} + public void translate(float p0, float p1){} + static public enum EdgeType + { + AA, BW; + private EdgeType() {} + } + static public enum VertexMode + { + TRIANGLES, TRIANGLE_FAN, TRIANGLE_STRIP; + private VertexMode() {} + } +} diff --git a/java/ql/test/stubs/android/android/graphics/Color.java b/java/ql/test/stubs/android/android/graphics/Color.java new file mode 100644 index 00000000000..45f1e68548c --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/Color.java @@ -0,0 +1,80 @@ +// Generated automatically from android.graphics.Color for testing purposes + +package android.graphics; + +import android.graphics.ColorSpace; + +public class Color +{ + public Color convert(ColorSpace p0){ return null; } + public Color(){} + public ColorSpace getColorSpace(){ return null; } + public ColorSpace.Model getModel(){ return null; } + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public boolean isSrgb(){ return false; } + public boolean isWideGamut(){ return false; } + public float alpha(){ return 0; } + public float blue(){ return 0; } + public float getComponent(int p0){ return 0; } + public float green(){ return 0; } + public float luminance(){ return 0; } + public float red(){ return 0; } + public float[] getComponents(){ return null; } + public float[] getComponents(float[] p0){ return null; } + public int getComponentCount(){ return 0; } + public int hashCode(){ return 0; } + public int toArgb(){ return 0; } + public long pack(){ return 0; } + public static Color valueOf(float p0, float p1, float p2){ return null; } + public static Color valueOf(float p0, float p1, float p2, float p3){ return null; } + public static Color valueOf(float p0, float p1, float p2, float p3, ColorSpace p4){ return null; } + public static Color valueOf(float[] p0, ColorSpace p1){ return null; } + public static Color valueOf(int p0){ return null; } + public static Color valueOf(long p0){ return null; } + public static ColorSpace colorSpace(long p0){ return null; } + public static boolean isInColorSpace(long p0, ColorSpace p1){ return false; } + public static boolean isSrgb(long p0){ return false; } + public static boolean isWideGamut(long p0){ return false; } + public static float alpha(long p0){ return 0; } + public static float blue(long p0){ return 0; } + public static float green(long p0){ return 0; } + public static float luminance(int p0){ return 0; } + public static float luminance(long p0){ return 0; } + public static float red(long p0){ return 0; } + public static int BLACK = 0; + public static int BLUE = 0; + public static int CYAN = 0; + public static int DKGRAY = 0; + public static int GRAY = 0; + public static int GREEN = 0; + public static int HSVToColor(float[] p0){ return 0; } + public static int HSVToColor(int p0, float[] p1){ return 0; } + public static int LTGRAY = 0; + public static int MAGENTA = 0; + public static int RED = 0; + public static int TRANSPARENT = 0; + public static int WHITE = 0; + public static int YELLOW = 0; + public static int alpha(int p0){ return 0; } + public static int argb(float p0, float p1, float p2, float p3){ return 0; } + public static int argb(int p0, int p1, int p2, int p3){ return 0; } + public static int blue(int p0){ return 0; } + public static int green(int p0){ return 0; } + public static int parseColor(String p0){ return 0; } + public static int red(int p0){ return 0; } + public static int rgb(float p0, float p1, float p2){ return 0; } + public static int rgb(int p0, int p1, int p2){ return 0; } + public static int toArgb(long p0){ return 0; } + public static long convert(float p0, float p1, float p2, float p3, ColorSpace p4, ColorSpace p5){ return 0; } + public static long convert(float p0, float p1, float p2, float p3, ColorSpace.Connector p4){ return 0; } + public static long convert(int p0, ColorSpace p1){ return 0; } + public static long convert(long p0, ColorSpace p1){ return 0; } + public static long convert(long p0, ColorSpace.Connector p1){ return 0; } + public static long pack(float p0, float p1, float p2){ return 0; } + public static long pack(float p0, float p1, float p2, float p3){ return 0; } + public static long pack(float p0, float p1, float p2, float p3, ColorSpace p4){ return 0; } + public static long pack(int p0){ return 0; } + public static void RGBToHSV(int p0, int p1, int p2, float[] p3){} + public static void colorToHSV(int p0, float[] p1){} +} diff --git a/java/ql/test/stubs/android/android/graphics/ColorFilter.java b/java/ql/test/stubs/android/android/graphics/ColorFilter.java new file mode 100644 index 00000000000..06a565743de --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/ColorFilter.java @@ -0,0 +1,9 @@ +// Generated automatically from android.graphics.ColorFilter for testing purposes + +package android.graphics; + + +public class ColorFilter +{ + public ColorFilter(){} +} diff --git a/java/ql/test/stubs/android/android/graphics/ColorSpace.java b/java/ql/test/stubs/android/android/graphics/ColorSpace.java new file mode 100644 index 00000000000..80c1ebcbbe4 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/ColorSpace.java @@ -0,0 +1,120 @@ +// Generated automatically from android.graphics.ColorSpace for testing purposes + +package android.graphics; + +import java.util.function.DoubleUnaryOperator; + +abstract public class ColorSpace +{ + public ColorSpace.Model getModel(){ return null; } + public String getName(){ return null; } + public String toString(){ return null; } + public abstract boolean isWideGamut(); + public abstract float getMaxValue(int p0); + public abstract float getMinValue(int p0); + public abstract float[] fromXyz(float[] p0); + public abstract float[] toXyz(float[] p0); + public boolean equals(Object p0){ return false; } + public boolean isSrgb(){ return false; } + public float[] fromXyz(float p0, float p1, float p2){ return null; } + public float[] toXyz(float p0, float p1, float p2){ return null; } + public int getComponentCount(){ return 0; } + public int getId(){ return 0; } + public int hashCode(){ return 0; } + public static ColorSpace adapt(ColorSpace p0, float[] p1){ return null; } + public static ColorSpace adapt(ColorSpace p0, float[] p1, ColorSpace.Adaptation p2){ return null; } + public static ColorSpace get(ColorSpace.Named p0){ return null; } + public static ColorSpace match(float[] p0, ColorSpace.Rgb.TransferParameters p1){ return null; } + public static ColorSpace.Connector connect(ColorSpace p0){ return null; } + public static ColorSpace.Connector connect(ColorSpace p0, ColorSpace p1){ return null; } + public static ColorSpace.Connector connect(ColorSpace p0, ColorSpace p1, ColorSpace.RenderIntent p2){ return null; } + public static ColorSpace.Connector connect(ColorSpace p0, ColorSpace.RenderIntent p1){ return null; } + public static float[] ILLUMINANT_A = null; + public static float[] ILLUMINANT_B = null; + public static float[] ILLUMINANT_C = null; + public static float[] ILLUMINANT_D50 = null; + public static float[] ILLUMINANT_D55 = null; + public static float[] ILLUMINANT_D60 = null; + public static float[] ILLUMINANT_D65 = null; + public static float[] ILLUMINANT_D75 = null; + public static float[] ILLUMINANT_E = null; + public static int MAX_ID = 0; + public static int MIN_ID = 0; + static public class Connector + { + public ColorSpace getDestination(){ return null; } + public ColorSpace getSource(){ return null; } + public ColorSpace.RenderIntent getRenderIntent(){ return null; } + public float[] transform(float p0, float p1, float p2){ return null; } + public float[] transform(float[] p0){ return null; } + } + static public class Rgb extends ColorSpace + { + protected Rgb() {} + public ColorSpace.Rgb.TransferParameters getTransferParameters(){ return null; } + public DoubleUnaryOperator getEotf(){ return null; } + public DoubleUnaryOperator getOetf(){ return null; } + public Rgb(String p0, float[] p1, ColorSpace.Rgb.TransferParameters p2){} + public Rgb(String p0, float[] p1, DoubleUnaryOperator p2, DoubleUnaryOperator p3){} + public Rgb(String p0, float[] p1, double p2){} + public Rgb(String p0, float[] p1, float[] p2, ColorSpace.Rgb.TransferParameters p3){} + public Rgb(String p0, float[] p1, float[] p2, DoubleUnaryOperator p3, DoubleUnaryOperator p4, float p5, float p6){} + public Rgb(String p0, float[] p1, float[] p2, double p3){} + public boolean equals(Object p0){ return false; } + public boolean isSrgb(){ return false; } + public boolean isWideGamut(){ return false; } + public float getMaxValue(int p0){ return 0; } + public float getMinValue(int p0){ return 0; } + public float[] fromLinear(float p0, float p1, float p2){ return null; } + public float[] fromLinear(float[] p0){ return null; } + public float[] fromXyz(float[] p0){ return null; } + public float[] getInverseTransform(){ return null; } + public float[] getInverseTransform(float[] p0){ return null; } + public float[] getPrimaries(){ return null; } + public float[] getPrimaries(float[] p0){ return null; } + public float[] getTransform(){ return null; } + public float[] getTransform(float[] p0){ return null; } + public float[] getWhitePoint(){ return null; } + public float[] getWhitePoint(float[] p0){ return null; } + public float[] toLinear(float p0, float p1, float p2){ return null; } + public float[] toLinear(float[] p0){ return null; } + public float[] toXyz(float[] p0){ return null; } + public int hashCode(){ return 0; } + static public class TransferParameters + { + protected TransferParameters() {} + public TransferParameters(double p0, double p1, double p2, double p3, double p4){} + public TransferParameters(double p0, double p1, double p2, double p3, double p4, double p5, double p6){} + public boolean equals(Object p0){ return false; } + public final double a = 0; + public final double b = 0; + public final double c = 0; + public final double d = 0; + public final double e = 0; + public final double f = 0; + public final double g = 0; + public int hashCode(){ return 0; } + } + } + static public enum Adaptation + { + BRADFORD, CIECAT02, VON_KRIES; + private Adaptation() {} + } + static public enum Model + { + CMYK, LAB, RGB, XYZ; + private Model() {} + public int getComponentCount(){ return 0; } + } + static public enum Named + { + ACES, ACESCG, ADOBE_RGB, BT2020, BT709, CIE_LAB, CIE_XYZ, DCI_P3, DISPLAY_P3, EXTENDED_SRGB, LINEAR_EXTENDED_SRGB, LINEAR_SRGB, NTSC_1953, PRO_PHOTO_RGB, SMPTE_C, SRGB; + private Named() {} + } + static public enum RenderIntent + { + ABSOLUTE, PERCEPTUAL, RELATIVE, SATURATION; + private RenderIntent() {} + } +} diff --git a/java/ql/test/stubs/android/android/graphics/DrawFilter.java b/java/ql/test/stubs/android/android/graphics/DrawFilter.java new file mode 100644 index 00000000000..ed760270a81 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/DrawFilter.java @@ -0,0 +1,10 @@ +// Generated automatically from android.graphics.DrawFilter for testing purposes + +package android.graphics; + + +public class DrawFilter +{ + protected void finalize(){} + public DrawFilter(){} +} diff --git a/java/ql/test/stubs/android/android/graphics/Insets.java b/java/ql/test/stubs/android/android/graphics/Insets.java new file mode 100644 index 00000000000..3e61e03cd68 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/Insets.java @@ -0,0 +1,29 @@ +// Generated automatically from android.graphics.Insets for testing purposes + +package android.graphics; + +import android.graphics.Rect; +import android.os.Parcel; +import android.os.Parcelable; + +public class Insets implements Parcelable +{ + protected Insets() {} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public final int bottom = 0; + public final int left = 0; + public final int right = 0; + public final int top = 0; + public int describeContents(){ return 0; } + public int hashCode(){ return 0; } + public static Insets NONE = null; + public static Insets add(Insets p0, Insets p1){ return null; } + public static Insets max(Insets p0, Insets p1){ return null; } + public static Insets min(Insets p0, Insets p1){ return null; } + public static Insets of(Rect p0){ return null; } + public static Insets of(int p0, int p1, int p2, int p3){ return null; } + public static Insets subtract(Insets p0, Insets p1){ return null; } + public static Parcelable.Creator CREATOR = null; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/graphics/MaskFilter.java b/java/ql/test/stubs/android/android/graphics/MaskFilter.java new file mode 100644 index 00000000000..0355b5c1206 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/MaskFilter.java @@ -0,0 +1,10 @@ +// Generated automatically from android.graphics.MaskFilter for testing purposes + +package android.graphics; + + +public class MaskFilter +{ + protected void finalize(){} + public MaskFilter(){} +} diff --git a/java/ql/test/stubs/android/android/graphics/Matrix.java b/java/ql/test/stubs/android/android/graphics/Matrix.java new file mode 100644 index 00000000000..fc003bac004 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/Matrix.java @@ -0,0 +1,74 @@ +// Generated automatically from android.graphics.Matrix for testing purposes + +package android.graphics; + +import android.graphics.RectF; + +public class Matrix +{ + public Matrix(){} + public Matrix(Matrix p0){} + public String toShortString(){ return null; } + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public boolean invert(Matrix p0){ return false; } + public boolean isAffine(){ return false; } + public boolean isIdentity(){ return false; } + public boolean mapRect(RectF p0){ return false; } + public boolean mapRect(RectF p0, RectF p1){ return false; } + public boolean postConcat(Matrix p0){ return false; } + public boolean postRotate(float p0){ return false; } + public boolean postRotate(float p0, float p1, float p2){ return false; } + public boolean postScale(float p0, float p1){ return false; } + public boolean postScale(float p0, float p1, float p2, float p3){ return false; } + public boolean postSkew(float p0, float p1){ return false; } + public boolean postSkew(float p0, float p1, float p2, float p3){ return false; } + public boolean postTranslate(float p0, float p1){ return false; } + public boolean preConcat(Matrix p0){ return false; } + public boolean preRotate(float p0){ return false; } + public boolean preRotate(float p0, float p1, float p2){ return false; } + public boolean preScale(float p0, float p1){ return false; } + public boolean preScale(float p0, float p1, float p2, float p3){ return false; } + public boolean preSkew(float p0, float p1){ return false; } + public boolean preSkew(float p0, float p1, float p2, float p3){ return false; } + public boolean preTranslate(float p0, float p1){ return false; } + public boolean rectStaysRect(){ return false; } + public boolean setConcat(Matrix p0, Matrix p1){ return false; } + public boolean setPolyToPoly(float[] p0, int p1, float[] p2, int p3, int p4){ return false; } + public boolean setRectToRect(RectF p0, RectF p1, Matrix.ScaleToFit p2){ return false; } + public float mapRadius(float p0){ return 0; } + public int hashCode(){ return 0; } + public static int MPERSP_0 = 0; + public static int MPERSP_1 = 0; + public static int MPERSP_2 = 0; + public static int MSCALE_X = 0; + public static int MSCALE_Y = 0; + public static int MSKEW_X = 0; + public static int MSKEW_Y = 0; + public static int MTRANS_X = 0; + public static int MTRANS_Y = 0; + public void getValues(float[] p0){} + public void mapPoints(float[] p0){} + public void mapPoints(float[] p0, float[] p1){} + public void mapPoints(float[] p0, int p1, float[] p2, int p3, int p4){} + public void mapVectors(float[] p0){} + public void mapVectors(float[] p0, float[] p1){} + public void mapVectors(float[] p0, int p1, float[] p2, int p3, int p4){} + public void reset(){} + public void set(Matrix p0){} + public void setRotate(float p0){} + public void setRotate(float p0, float p1, float p2){} + public void setScale(float p0, float p1){} + public void setScale(float p0, float p1, float p2, float p3){} + public void setSinCos(float p0, float p1){} + public void setSinCos(float p0, float p1, float p2, float p3){} + public void setSkew(float p0, float p1){} + public void setSkew(float p0, float p1, float p2, float p3){} + public void setTranslate(float p0, float p1){} + public void setValues(float[] p0){} + static public enum ScaleToFit + { + CENTER, END, FILL, START; + private ScaleToFit() {} + } +} diff --git a/java/ql/test/stubs/android/android/graphics/Movie.java b/java/ql/test/stubs/android/android/graphics/Movie.java new file mode 100644 index 00000000000..dd531ba7e04 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/Movie.java @@ -0,0 +1,23 @@ +// Generated automatically from android.graphics.Movie for testing purposes + +package android.graphics; + +import android.graphics.Canvas; +import android.graphics.Paint; +import java.io.InputStream; + +public class Movie +{ + protected Movie() {} + protected void finalize(){} + public boolean isOpaque(){ return false; } + public boolean setTime(int p0){ return false; } + public int duration(){ return 0; } + public int height(){ return 0; } + public int width(){ return 0; } + public static Movie decodeByteArray(byte[] p0, int p1, int p2){ return null; } + public static Movie decodeFile(String p0){ return null; } + public static Movie decodeStream(InputStream p0){ return null; } + public void draw(Canvas p0, float p1, float p2){} + public void draw(Canvas p0, float p1, float p2, Paint p3){} +} diff --git a/java/ql/test/stubs/android/android/graphics/NinePatch.java b/java/ql/test/stubs/android/android/graphics/NinePatch.java new file mode 100644 index 00000000000..0fa7bc2eb69 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/NinePatch.java @@ -0,0 +1,31 @@ +// Generated automatically from android.graphics.NinePatch for testing purposes + +package android.graphics; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.Region; + +public class NinePatch +{ + protected NinePatch() {} + protected void finalize(){} + public Bitmap getBitmap(){ return null; } + public NinePatch(Bitmap p0, byte[] p1){} + public NinePatch(Bitmap p0, byte[] p1, String p2){} + public Paint getPaint(){ return null; } + public String getName(){ return null; } + public final Region getTransparentRegion(Rect p0){ return null; } + public final boolean hasAlpha(){ return false; } + public int getDensity(){ return 0; } + public int getHeight(){ return 0; } + public int getWidth(){ return 0; } + public static boolean isNinePatchChunk(byte[] p0){ return false; } + public void draw(Canvas p0, Rect p1){} + public void draw(Canvas p0, Rect p1, Paint p2){} + public void draw(Canvas p0, RectF p1){} + public void setPaint(Paint p0){} +} diff --git a/java/ql/test/stubs/android/android/graphics/Outline.java b/java/ql/test/stubs/android/android/graphics/Outline.java new file mode 100644 index 00000000000..4367be91cdd --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/Outline.java @@ -0,0 +1,29 @@ +// Generated automatically from android.graphics.Outline for testing purposes + +package android.graphics; + +import android.graphics.Path; +import android.graphics.Rect; + +public class Outline +{ + public Outline(){} + public Outline(Outline p0){} + public boolean canClip(){ return false; } + public boolean getRect(Rect p0){ return false; } + public boolean isEmpty(){ return false; } + public float getAlpha(){ return 0; } + public float getRadius(){ return 0; } + public void offset(int p0, int p1){} + public void set(Outline p0){} + public void setAlpha(float p0){} + public void setConvexPath(Path p0){} + public void setEmpty(){} + public void setOval(Rect p0){} + public void setOval(int p0, int p1, int p2, int p3){} + public void setPath(Path p0){} + public void setRect(Rect p0){} + public void setRect(int p0, int p1, int p2, int p3){} + public void setRoundRect(Rect p0, float p1){} + public void setRoundRect(int p0, int p1, int p2, int p3, float p4){} +} diff --git a/java/ql/test/stubs/android/android/graphics/Paint.java b/java/ql/test/stubs/android/android/graphics/Paint.java new file mode 100644 index 00000000000..810aecc3617 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/Paint.java @@ -0,0 +1,212 @@ +// Generated automatically from android.graphics.Paint for testing purposes + +package android.graphics; + +import android.graphics.BlendMode; +import android.graphics.ColorFilter; +import android.graphics.MaskFilter; +import android.graphics.Path; +import android.graphics.PathEffect; +import android.graphics.Rect; +import android.graphics.Shader; +import android.graphics.Typeface; +import android.graphics.Xfermode; +import android.os.LocaleList; +import java.util.Locale; + +public class Paint +{ + public BlendMode getBlendMode(){ return null; } + public ColorFilter getColorFilter(){ return null; } + public ColorFilter setColorFilter(ColorFilter p0){ return null; } + public Locale getTextLocale(){ return null; } + public LocaleList getTextLocales(){ return null; } + public MaskFilter getMaskFilter(){ return null; } + public MaskFilter setMaskFilter(MaskFilter p0){ return null; } + public Paint(){} + public Paint(Paint p0){} + public Paint(int p0){} + public Paint.Align getTextAlign(){ return null; } + public Paint.Cap getStrokeCap(){ return null; } + public Paint.FontMetrics getFontMetrics(){ return null; } + public Paint.FontMetricsInt getFontMetricsInt(){ return null; } + public Paint.Join getStrokeJoin(){ return null; } + public Paint.Style getStyle(){ return null; } + public PathEffect getPathEffect(){ return null; } + public PathEffect setPathEffect(PathEffect p0){ return null; } + public Shader getShader(){ return null; } + public Shader setShader(Shader p0){ return null; } + public String getFontFeatureSettings(){ return null; } + public String getFontVariationSettings(){ return null; } + public Typeface getTypeface(){ return null; } + public Typeface setTypeface(Typeface p0){ return null; } + public Xfermode getXfermode(){ return null; } + public Xfermode setXfermode(Xfermode p0){ return null; } + public boolean equalsForTextMeasurement(Paint p0){ return false; } + public boolean getFillPath(Path p0, Path p1){ return false; } + public boolean hasGlyph(String p0){ return false; } + public boolean isElegantTextHeight(){ return false; } + public boolean setFontVariationSettings(String p0){ return false; } + public final boolean isAntiAlias(){ return false; } + public final boolean isDither(){ return false; } + public final boolean isFakeBoldText(){ return false; } + public final boolean isFilterBitmap(){ return false; } + public final boolean isLinearText(){ return false; } + public final boolean isStrikeThruText(){ return false; } + public final boolean isSubpixelText(){ return false; } + public final boolean isUnderlineText(){ return false; } + public float ascent(){ return 0; } + public float descent(){ return 0; } + public float getFontMetrics(Paint.FontMetrics p0){ return 0; } + public float getFontSpacing(){ return 0; } + public float getLetterSpacing(){ return 0; } + public float getRunAdvance(CharSequence p0, int p1, int p2, int p3, int p4, boolean p5, int p6){ return 0; } + public float getRunAdvance(char[] p0, int p1, int p2, int p3, int p4, boolean p5, int p6){ return 0; } + public float getShadowLayerDx(){ return 0; } + public float getShadowLayerDy(){ return 0; } + public float getShadowLayerRadius(){ return 0; } + public float getStrikeThruPosition(){ return 0; } + public float getStrikeThruThickness(){ return 0; } + public float getStrokeMiter(){ return 0; } + public float getStrokeWidth(){ return 0; } + public float getTextRunAdvances(char[] p0, int p1, int p2, int p3, int p4, boolean p5, float[] p6, int p7){ return 0; } + public float getTextScaleX(){ return 0; } + public float getTextSize(){ return 0; } + public float getTextSkewX(){ return 0; } + public float getUnderlinePosition(){ return 0; } + public float getUnderlineThickness(){ return 0; } + public float getWordSpacing(){ return 0; } + public float measureText(CharSequence p0, int p1, int p2){ return 0; } + public float measureText(String p0){ return 0; } + public float measureText(String p0, int p1, int p2){ return 0; } + public float measureText(char[] p0, int p1, int p2){ return 0; } + public int breakText(CharSequence p0, int p1, int p2, boolean p3, float p4, float[] p5){ return 0; } + public int breakText(String p0, boolean p1, float p2, float[] p3){ return 0; } + public int breakText(char[] p0, int p1, int p2, float p3, float[] p4){ return 0; } + public int getAlpha(){ return 0; } + public int getColor(){ return 0; } + public int getEndHyphenEdit(){ return 0; } + public int getFlags(){ return 0; } + public int getFontMetricsInt(Paint.FontMetricsInt p0){ return 0; } + public int getHinting(){ return 0; } + public int getOffsetForAdvance(CharSequence p0, int p1, int p2, int p3, int p4, boolean p5, float p6){ return 0; } + public int getOffsetForAdvance(char[] p0, int p1, int p2, int p3, int p4, boolean p5, float p6){ return 0; } + public int getShadowLayerColor(){ return 0; } + public int getStartHyphenEdit(){ return 0; } + public int getTextRunCursor(CharSequence p0, int p1, int p2, boolean p3, int p4, int p5){ return 0; } + public int getTextRunCursor(char[] p0, int p1, int p2, boolean p3, int p4, int p5){ return 0; } + public int getTextWidths(CharSequence p0, int p1, int p2, float[] p3){ return 0; } + public int getTextWidths(String p0, float[] p1){ return 0; } + public int getTextWidths(String p0, int p1, int p2, float[] p3){ return 0; } + public int getTextWidths(char[] p0, int p1, int p2, float[] p3){ return 0; } + public long getColorLong(){ return 0; } + public long getShadowLayerColorLong(){ return 0; } + public static int ANTI_ALIAS_FLAG = 0; + public static int CURSOR_AFTER = 0; + public static int CURSOR_AT = 0; + public static int CURSOR_AT_OR_AFTER = 0; + public static int CURSOR_AT_OR_BEFORE = 0; + public static int CURSOR_BEFORE = 0; + public static int DEV_KERN_TEXT_FLAG = 0; + public static int DITHER_FLAG = 0; + public static int EMBEDDED_BITMAP_TEXT_FLAG = 0; + public static int END_HYPHEN_EDIT_INSERT_ARMENIAN_HYPHEN = 0; + public static int END_HYPHEN_EDIT_INSERT_HYPHEN = 0; + public static int END_HYPHEN_EDIT_INSERT_MAQAF = 0; + public static int END_HYPHEN_EDIT_INSERT_UCAS_HYPHEN = 0; + public static int END_HYPHEN_EDIT_INSERT_ZWJ_AND_HYPHEN = 0; + public static int END_HYPHEN_EDIT_NO_EDIT = 0; + public static int END_HYPHEN_EDIT_REPLACE_WITH_HYPHEN = 0; + public static int FAKE_BOLD_TEXT_FLAG = 0; + public static int FILTER_BITMAP_FLAG = 0; + public static int HINTING_OFF = 0; + public static int HINTING_ON = 0; + public static int LINEAR_TEXT_FLAG = 0; + public static int START_HYPHEN_EDIT_INSERT_HYPHEN = 0; + public static int START_HYPHEN_EDIT_INSERT_ZWJ = 0; + public static int START_HYPHEN_EDIT_NO_EDIT = 0; + public static int STRIKE_THRU_TEXT_FLAG = 0; + public static int SUBPIXEL_TEXT_FLAG = 0; + public static int UNDERLINE_TEXT_FLAG = 0; + public void clearShadowLayer(){} + public void getTextBounds(CharSequence p0, int p1, int p2, Rect p3){} + public void getTextBounds(String p0, int p1, int p2, Rect p3){} + public void getTextBounds(char[] p0, int p1, int p2, Rect p3){} + public void getTextPath(String p0, int p1, int p2, float p3, float p4, Path p5){} + public void getTextPath(char[] p0, int p1, int p2, float p3, float p4, Path p5){} + public void reset(){} + public void set(Paint p0){} + public void setARGB(int p0, int p1, int p2, int p3){} + public void setAlpha(int p0){} + public void setAntiAlias(boolean p0){} + public void setBlendMode(BlendMode p0){} + public void setColor(int p0){} + public void setColor(long p0){} + public void setDither(boolean p0){} + public void setElegantTextHeight(boolean p0){} + public void setEndHyphenEdit(int p0){} + public void setFakeBoldText(boolean p0){} + public void setFilterBitmap(boolean p0){} + public void setFlags(int p0){} + public void setFontFeatureSettings(String p0){} + public void setHinting(int p0){} + public void setLetterSpacing(float p0){} + public void setLinearText(boolean p0){} + public void setShadowLayer(float p0, float p1, float p2, int p3){} + public void setShadowLayer(float p0, float p1, float p2, long p3){} + public void setStartHyphenEdit(int p0){} + public void setStrikeThruText(boolean p0){} + public void setStrokeCap(Paint.Cap p0){} + public void setStrokeJoin(Paint.Join p0){} + public void setStrokeMiter(float p0){} + public void setStrokeWidth(float p0){} + public void setStyle(Paint.Style p0){} + public void setSubpixelText(boolean p0){} + public void setTextAlign(Paint.Align p0){} + public void setTextLocale(Locale p0){} + public void setTextLocales(LocaleList p0){} + public void setTextScaleX(float p0){} + public void setTextSize(float p0){} + public void setTextSkewX(float p0){} + public void setUnderlineText(boolean p0){} + public void setWordSpacing(float p0){} + static public class FontMetrics + { + public FontMetrics(){} + public float ascent = 0; + public float bottom = 0; + public float descent = 0; + public float leading = 0; + public float top = 0; + } + static public class FontMetricsInt + { + public FontMetricsInt(){} + public String toString(){ return null; } + public int ascent = 0; + public int bottom = 0; + public int descent = 0; + public int leading = 0; + public int top = 0; + } + static public enum Align + { + CENTER, LEFT, RIGHT; + private Align() {} + } + static public enum Cap + { + BUTT, ROUND, SQUARE; + private Cap() {} + } + static public enum Join + { + BEVEL, MITER, ROUND; + private Join() {} + } + static public enum Style + { + FILL, FILL_AND_STROKE, STROKE; + private Style() {} + } +} diff --git a/java/ql/test/stubs/android/android/graphics/Path.java b/java/ql/test/stubs/android/android/graphics/Path.java new file mode 100644 index 00000000000..c7164e37b01 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/Path.java @@ -0,0 +1,73 @@ +// Generated automatically from android.graphics.Path for testing purposes + +package android.graphics; + +import android.graphics.Matrix; +import android.graphics.RectF; + +public class Path +{ + public Path(){} + public Path(Path p0){} + public Path.FillType getFillType(){ return null; } + public boolean isConvex(){ return false; } + public boolean isEmpty(){ return false; } + public boolean isInverseFillType(){ return false; } + public boolean isRect(RectF p0){ return false; } + public boolean op(Path p0, Path p1, Path.Op p2){ return false; } + public boolean op(Path p0, Path.Op p1){ return false; } + public float[] approximate(float p0){ return null; } + public void addArc(RectF p0, float p1, float p2){} + public void addArc(float p0, float p1, float p2, float p3, float p4, float p5){} + public void addCircle(float p0, float p1, float p2, Path.Direction p3){} + public void addOval(RectF p0, Path.Direction p1){} + public void addOval(float p0, float p1, float p2, float p3, Path.Direction p4){} + public void addPath(Path p0){} + public void addPath(Path p0, Matrix p1){} + public void addPath(Path p0, float p1, float p2){} + public void addRect(RectF p0, Path.Direction p1){} + public void addRect(float p0, float p1, float p2, float p3, Path.Direction p4){} + public void addRoundRect(RectF p0, float p1, float p2, Path.Direction p3){} + public void addRoundRect(RectF p0, float[] p1, Path.Direction p2){} + public void addRoundRect(float p0, float p1, float p2, float p3, float p4, float p5, Path.Direction p6){} + public void addRoundRect(float p0, float p1, float p2, float p3, float[] p4, Path.Direction p5){} + public void arcTo(RectF p0, float p1, float p2){} + public void arcTo(RectF p0, float p1, float p2, boolean p3){} + public void arcTo(float p0, float p1, float p2, float p3, float p4, float p5, boolean p6){} + public void close(){} + public void computeBounds(RectF p0, boolean p1){} + public void cubicTo(float p0, float p1, float p2, float p3, float p4, float p5){} + public void incReserve(int p0){} + public void lineTo(float p0, float p1){} + public void moveTo(float p0, float p1){} + public void offset(float p0, float p1){} + public void offset(float p0, float p1, Path p2){} + public void quadTo(float p0, float p1, float p2, float p3){} + public void rCubicTo(float p0, float p1, float p2, float p3, float p4, float p5){} + public void rLineTo(float p0, float p1){} + public void rMoveTo(float p0, float p1){} + public void rQuadTo(float p0, float p1, float p2, float p3){} + public void reset(){} + public void rewind(){} + public void set(Path p0){} + public void setFillType(Path.FillType p0){} + public void setLastPoint(float p0, float p1){} + public void toggleInverseFillType(){} + public void transform(Matrix p0){} + public void transform(Matrix p0, Path p1){} + static public enum Direction + { + CCW, CW; + private Direction() {} + } + static public enum FillType + { + EVEN_ODD, INVERSE_EVEN_ODD, INVERSE_WINDING, WINDING; + private FillType() {} + } + static public enum Op + { + DIFFERENCE, INTERSECT, REVERSE_DIFFERENCE, UNION, XOR; + private Op() {} + } +} diff --git a/java/ql/test/stubs/android/android/graphics/PathEffect.java b/java/ql/test/stubs/android/android/graphics/PathEffect.java new file mode 100644 index 00000000000..c9ca9aeae86 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/PathEffect.java @@ -0,0 +1,10 @@ +// Generated automatically from android.graphics.PathEffect for testing purposes + +package android.graphics; + + +public class PathEffect +{ + protected void finalize(){} + public PathEffect(){} +} diff --git a/java/ql/test/stubs/android/android/graphics/Picture.java b/java/ql/test/stubs/android/android/graphics/Picture.java new file mode 100644 index 00000000000..328321a2139 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/Picture.java @@ -0,0 +1,18 @@ +// Generated automatically from android.graphics.Picture for testing purposes + +package android.graphics; + +import android.graphics.Canvas; + +public class Picture +{ + protected void finalize(){} + public Canvas beginRecording(int p0, int p1){ return null; } + public Picture(){} + public Picture(Picture p0){} + public boolean requiresHardwareAcceleration(){ return false; } + public int getHeight(){ return 0; } + public int getWidth(){ return 0; } + public void draw(Canvas p0){} + public void endRecording(){} +} diff --git a/java/ql/test/stubs/android/android/graphics/Point.java b/java/ql/test/stubs/android/android/graphics/Point.java new file mode 100644 index 00000000000..0e97248f44b --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/Point.java @@ -0,0 +1,26 @@ +// Generated automatically from android.graphics.Point for testing purposes + +package android.graphics; + +import android.os.Parcel; +import android.os.Parcelable; + +public class Point implements Parcelable +{ + public Point(){} + public Point(Point p0){} + public Point(int p0, int p1){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public final boolean equals(int p0, int p1){ return false; } + public final void negate(){} + public final void offset(int p0, int p1){} + public int describeContents(){ return 0; } + public int hashCode(){ return 0; } + public int x = 0; + public int y = 0; + public static Parcelable.Creator CREATOR = null; + public void readFromParcel(Parcel p0){} + public void set(int p0, int p1){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/graphics/PorterDuff.java b/java/ql/test/stubs/android/android/graphics/PorterDuff.java new file mode 100644 index 00000000000..39a82e655d6 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/PorterDuff.java @@ -0,0 +1,14 @@ +// Generated automatically from android.graphics.PorterDuff for testing purposes + +package android.graphics; + + +public class PorterDuff +{ + public PorterDuff(){} + static public enum Mode + { + ADD, CLEAR, DARKEN, DST, DST_ATOP, DST_IN, DST_OUT, DST_OVER, LIGHTEN, MULTIPLY, OVERLAY, SCREEN, SRC, SRC_ATOP, SRC_IN, SRC_OUT, SRC_OVER, XOR; + private Mode() {} + } +} diff --git a/java/ql/test/stubs/android/android/graphics/RecordingCanvas.java b/java/ql/test/stubs/android/android/graphics/RecordingCanvas.java new file mode 100644 index 00000000000..1d992a53ec0 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/RecordingCanvas.java @@ -0,0 +1,82 @@ +// Generated automatically from android.graphics.RecordingCanvas for testing purposes + +package android.graphics; + +import android.graphics.Bitmap; +import android.graphics.BlendMode; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.NinePatch; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.Picture; +import android.graphics.PorterDuff; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.RenderNode; +import android.graphics.text.MeasuredText; + +public class RecordingCanvas extends Canvas +{ + public boolean isHardwareAccelerated(){ return false; } + public boolean isOpaque(){ return false; } + public final void drawARGB(int p0, int p1, int p2, int p3){} + public final void drawArc(RectF p0, float p1, float p2, boolean p3, Paint p4){} + public final void drawArc(float p0, float p1, float p2, float p3, float p4, float p5, boolean p6, Paint p7){} + public final void drawBitmap(Bitmap p0, Matrix p1, Paint p2){} + public final void drawBitmap(Bitmap p0, Rect p1, Rect p2, Paint p3){} + public final void drawBitmap(Bitmap p0, Rect p1, RectF p2, Paint p3){} + public final void drawBitmap(Bitmap p0, float p1, float p2, Paint p3){} + public final void drawBitmap(int[] p0, int p1, int p2, float p3, float p4, int p5, int p6, boolean p7, Paint p8){} + public final void drawBitmap(int[] p0, int p1, int p2, int p3, int p4, int p5, int p6, boolean p7, Paint p8){} + public final void drawBitmapMesh(Bitmap p0, int p1, int p2, float[] p3, int p4, int[] p5, int p6, Paint p7){} + public final void drawCircle(float p0, float p1, float p2, Paint p3){} + public final void drawColor(int p0){} + public final void drawColor(int p0, BlendMode p1){} + public final void drawColor(int p0, PorterDuff.Mode p1){} + public final void drawColor(long p0, BlendMode p1){} + public final void drawDoubleRoundRect(RectF p0, float p1, float p2, RectF p3, float p4, float p5, Paint p6){} + public final void drawDoubleRoundRect(RectF p0, float[] p1, RectF p2, float[] p3, Paint p4){} + public final void drawLine(float p0, float p1, float p2, float p3, Paint p4){} + public final void drawLines(float[] p0, Paint p1){} + public final void drawLines(float[] p0, int p1, int p2, Paint p3){} + public final void drawOval(RectF p0, Paint p1){} + public final void drawOval(float p0, float p1, float p2, float p3, Paint p4){} + public final void drawPaint(Paint p0){} + public final void drawPatch(NinePatch p0, Rect p1, Paint p2){} + public final void drawPatch(NinePatch p0, RectF p1, Paint p2){} + public final void drawPath(Path p0, Paint p1){} + public final void drawPicture(Picture p0){} + public final void drawPicture(Picture p0, Rect p1){} + public final void drawPicture(Picture p0, RectF p1){} + public final void drawPoint(float p0, float p1, Paint p2){} + public final void drawPoints(float[] p0, Paint p1){} + public final void drawPoints(float[] p0, int p1, int p2, Paint p3){} + public final void drawPosText(String p0, float[] p1, Paint p2){} + public final void drawPosText(char[] p0, int p1, int p2, float[] p3, Paint p4){} + public final void drawRGB(int p0, int p1, int p2){} + public final void drawRect(Rect p0, Paint p1){} + public final void drawRect(RectF p0, Paint p1){} + public final void drawRect(float p0, float p1, float p2, float p3, Paint p4){} + public final void drawRoundRect(RectF p0, float p1, float p2, Paint p3){} + public final void drawRoundRect(float p0, float p1, float p2, float p3, float p4, float p5, Paint p6){} + public final void drawText(CharSequence p0, int p1, int p2, float p3, float p4, Paint p5){} + public final void drawText(String p0, float p1, float p2, Paint p3){} + public final void drawText(String p0, int p1, int p2, float p3, float p4, Paint p5){} + public final void drawText(char[] p0, int p1, int p2, float p3, float p4, Paint p5){} + public final void drawTextOnPath(String p0, Path p1, float p2, float p3, Paint p4){} + public final void drawTextOnPath(char[] p0, int p1, int p2, Path p3, float p4, float p5, Paint p6){} + public final void drawTextRun(CharSequence p0, int p1, int p2, int p3, int p4, float p5, float p6, boolean p7, Paint p8){} + public final void drawTextRun(char[] p0, int p1, int p2, int p3, int p4, float p5, float p6, boolean p7, Paint p8){} + public final void drawVertices(Canvas.VertexMode p0, int p1, float[] p2, int p3, float[] p4, int p5, int[] p6, int p7, short[] p8, int p9, int p10, Paint p11){} + public int getHeight(){ return 0; } + public int getMaximumBitmapHeight(){ return 0; } + public int getMaximumBitmapWidth(){ return 0; } + public int getWidth(){ return 0; } + public void disableZ(){} + public void drawRenderNode(RenderNode p0){} + public void drawTextRun(MeasuredText p0, int p1, int p2, int p3, int p4, float p5, float p6, boolean p7, Paint p8){} + public void enableZ(){} + public void setBitmap(Bitmap p0){} + public void setDensity(int p0){} +} diff --git a/java/ql/test/stubs/android/android/graphics/Rect.java b/java/ql/test/stubs/android/android/graphics/Rect.java new file mode 100644 index 00000000000..c29950cb31d --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/Rect.java @@ -0,0 +1,52 @@ +// Generated automatically from android.graphics.Rect for testing purposes + +package android.graphics; + +import android.os.Parcel; +import android.os.Parcelable; + +public class Rect implements Parcelable +{ + public Rect(){} + public Rect(Rect p0){} + public Rect(int p0, int p1, int p2, int p3){} + public String flattenToString(){ return null; } + public String toShortString(){ return null; } + public String toString(){ return null; } + public boolean contains(Rect p0){ return false; } + public boolean contains(int p0, int p1){ return false; } + public boolean contains(int p0, int p1, int p2, int p3){ return false; } + public boolean equals(Object p0){ return false; } + public boolean intersect(Rect p0){ return false; } + public boolean intersect(int p0, int p1, int p2, int p3){ return false; } + public boolean intersects(int p0, int p1, int p2, int p3){ return false; } + public boolean isEmpty(){ return false; } + public boolean setIntersect(Rect p0, Rect p1){ return false; } + public float exactCenterX(){ return 0; } + public float exactCenterY(){ return 0; } + public int bottom = 0; + public int centerX(){ return 0; } + public int centerY(){ return 0; } + public int describeContents(){ return 0; } + public int hashCode(){ return 0; } + public int height(){ return 0; } + public int left = 0; + public int right = 0; + public int top = 0; + public int width(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static Rect unflattenFromString(String p0){ return null; } + public static boolean intersects(Rect p0, Rect p1){ return false; } + public void inset(int p0, int p1){} + public void offset(int p0, int p1){} + public void offsetTo(int p0, int p1){} + public void readFromParcel(Parcel p0){} + public void set(Rect p0){} + public void set(int p0, int p1, int p2, int p3){} + public void setEmpty(){} + public void sort(){} + public void union(Rect p0){} + public void union(int p0, int p1){} + public void union(int p0, int p1, int p2, int p3){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/graphics/RectF.java b/java/ql/test/stubs/android/android/graphics/RectF.java new file mode 100644 index 00000000000..59489dd3f17 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/RectF.java @@ -0,0 +1,53 @@ +// Generated automatically from android.graphics.RectF for testing purposes + +package android.graphics; + +import android.graphics.Rect; +import android.os.Parcel; +import android.os.Parcelable; + +public class RectF implements Parcelable +{ + public RectF(){} + public RectF(Rect p0){} + public RectF(RectF p0){} + public RectF(float p0, float p1, float p2, float p3){} + public String toShortString(){ return null; } + public String toString(){ return null; } + public boolean contains(RectF p0){ return false; } + public boolean contains(float p0, float p1){ return false; } + public boolean contains(float p0, float p1, float p2, float p3){ return false; } + public boolean equals(Object p0){ return false; } + public boolean intersect(RectF p0){ return false; } + public boolean intersect(float p0, float p1, float p2, float p3){ return false; } + public boolean intersects(float p0, float p1, float p2, float p3){ return false; } + public boolean setIntersect(RectF p0, RectF p1){ return false; } + public final boolean isEmpty(){ return false; } + public final float centerX(){ return 0; } + public final float centerY(){ return 0; } + public final float height(){ return 0; } + public final float width(){ return 0; } + public float bottom = 0; + public float left = 0; + public float right = 0; + public float top = 0; + public int describeContents(){ return 0; } + public int hashCode(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static boolean intersects(RectF p0, RectF p1){ return false; } + public void inset(float p0, float p1){} + public void offset(float p0, float p1){} + public void offsetTo(float p0, float p1){} + public void readFromParcel(Parcel p0){} + public void round(Rect p0){} + public void roundOut(Rect p0){} + public void set(Rect p0){} + public void set(RectF p0){} + public void set(float p0, float p1, float p2, float p3){} + public void setEmpty(){} + public void sort(){} + public void union(RectF p0){} + public void union(float p0, float p1){} + public void union(float p0, float p1, float p2, float p3){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/graphics/Region.java b/java/ql/test/stubs/android/android/graphics/Region.java new file mode 100644 index 00000000000..7fbd2b4dafc --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/Region.java @@ -0,0 +1,53 @@ +// Generated automatically from android.graphics.Region for testing purposes + +package android.graphics; + +import android.graphics.Path; +import android.graphics.Rect; +import android.os.Parcel; +import android.os.Parcelable; + +public class Region implements Parcelable +{ + protected void finalize(){} + public Path getBoundaryPath(){ return null; } + public Rect getBounds(){ return null; } + public Region(){} + public Region(Rect p0){} + public Region(Region p0){} + public Region(int p0, int p1, int p2, int p3){} + public String toString(){ return null; } + public boolean contains(int p0, int p1){ return false; } + public boolean equals(Object p0){ return false; } + public boolean getBoundaryPath(Path p0){ return false; } + public boolean getBounds(Rect p0){ return false; } + public boolean isComplex(){ return false; } + public boolean isEmpty(){ return false; } + public boolean isRect(){ return false; } + public boolean op(Rect p0, Region p1, Region.Op p2){ return false; } + public boolean op(Rect p0, Region.Op p1){ return false; } + public boolean op(Region p0, Region p1, Region.Op p2){ return false; } + public boolean op(Region p0, Region.Op p1){ return false; } + public boolean op(int p0, int p1, int p2, int p3, Region.Op p4){ return false; } + public boolean quickContains(Rect p0){ return false; } + public boolean quickContains(int p0, int p1, int p2, int p3){ return false; } + public boolean quickReject(Rect p0){ return false; } + public boolean quickReject(Region p0){ return false; } + public boolean quickReject(int p0, int p1, int p2, int p3){ return false; } + public boolean set(Rect p0){ return false; } + public boolean set(Region p0){ return false; } + public boolean set(int p0, int p1, int p2, int p3){ return false; } + public boolean setPath(Path p0, Region p1){ return false; } + public final boolean union(Rect p0){ return false; } + public int describeContents(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public void setEmpty(){} + public void translate(int p0, int p1){} + public void translate(int p0, int p1, Region p2){} + public void writeToParcel(Parcel p0, int p1){} + static public enum Op + { + DIFFERENCE, INTERSECT, REPLACE, REVERSE_DIFFERENCE, UNION, XOR; + private Op() {} + } +} diff --git a/java/ql/test/stubs/android/android/graphics/RenderNode.java b/java/ql/test/stubs/android/android/graphics/RenderNode.java new file mode 100644 index 00000000000..9384cd4cd4e --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/RenderNode.java @@ -0,0 +1,82 @@ +// Generated automatically from android.graphics.RenderNode for testing purposes + +package android.graphics; + +import android.graphics.Matrix; +import android.graphics.Outline; +import android.graphics.Paint; +import android.graphics.RecordingCanvas; +import android.graphics.Rect; + +public class RenderNode +{ + protected RenderNode() {} + public RecordingCanvas beginRecording(){ return null; } + public RecordingCanvas beginRecording(int p0, int p1){ return null; } + public RenderNode(String p0){} + public boolean getClipToBounds(){ return false; } + public boolean getClipToOutline(){ return false; } + public boolean getUseCompositingLayer(){ return false; } + public boolean hasDisplayList(){ return false; } + public boolean hasIdentityMatrix(){ return false; } + public boolean hasOverlappingRendering(){ return false; } + public boolean hasShadow(){ return false; } + public boolean isForceDarkAllowed(){ return false; } + public boolean isPivotExplicitlySet(){ return false; } + public boolean offsetLeftAndRight(int p0){ return false; } + public boolean offsetTopAndBottom(int p0){ return false; } + public boolean resetPivot(){ return false; } + public boolean setAlpha(float p0){ return false; } + public boolean setAmbientShadowColor(int p0){ return false; } + public boolean setCameraDistance(float p0){ return false; } + public boolean setClipRect(Rect p0){ return false; } + public boolean setClipToBounds(boolean p0){ return false; } + public boolean setClipToOutline(boolean p0){ return false; } + public boolean setElevation(float p0){ return false; } + public boolean setForceDarkAllowed(boolean p0){ return false; } + public boolean setHasOverlappingRendering(boolean p0){ return false; } + public boolean setOutline(Outline p0){ return false; } + public boolean setPivotX(float p0){ return false; } + public boolean setPivotY(float p0){ return false; } + public boolean setPosition(Rect p0){ return false; } + public boolean setPosition(int p0, int p1, int p2, int p3){ return false; } + public boolean setProjectBackwards(boolean p0){ return false; } + public boolean setProjectionReceiver(boolean p0){ return false; } + public boolean setRotationX(float p0){ return false; } + public boolean setRotationY(float p0){ return false; } + public boolean setRotationZ(float p0){ return false; } + public boolean setScaleX(float p0){ return false; } + public boolean setScaleY(float p0){ return false; } + public boolean setSpotShadowColor(int p0){ return false; } + public boolean setTranslationX(float p0){ return false; } + public boolean setTranslationY(float p0){ return false; } + public boolean setTranslationZ(float p0){ return false; } + public boolean setUseCompositingLayer(boolean p0, Paint p1){ return false; } + public float getAlpha(){ return 0; } + public float getCameraDistance(){ return 0; } + public float getElevation(){ return 0; } + public float getPivotX(){ return 0; } + public float getPivotY(){ return 0; } + public float getRotationX(){ return 0; } + public float getRotationY(){ return 0; } + public float getRotationZ(){ return 0; } + public float getScaleX(){ return 0; } + public float getScaleY(){ return 0; } + public float getTranslationX(){ return 0; } + public float getTranslationY(){ return 0; } + public float getTranslationZ(){ return 0; } + public int getAmbientShadowColor(){ return 0; } + public int getBottom(){ return 0; } + public int getHeight(){ return 0; } + public int getLeft(){ return 0; } + public int getRight(){ return 0; } + public int getSpotShadowColor(){ return 0; } + public int getTop(){ return 0; } + public int getWidth(){ return 0; } + public long computeApproximateMemoryUsage(){ return 0; } + public long getUniqueId(){ return 0; } + public void discardDisplayList(){} + public void endRecording(){} + public void getInverseMatrix(Matrix p0){} + public void getMatrix(Matrix p0){} +} diff --git a/java/ql/test/stubs/android/android/graphics/Shader.java b/java/ql/test/stubs/android/android/graphics/Shader.java new file mode 100644 index 00000000000..3e845aa0c0a --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/Shader.java @@ -0,0 +1,12 @@ +// Generated automatically from android.graphics.Shader for testing purposes + +package android.graphics; + +import android.graphics.Matrix; + +public class Shader +{ + public Shader(){} + public boolean getLocalMatrix(Matrix p0){ return false; } + public void setLocalMatrix(Matrix p0){} +} diff --git a/java/ql/test/stubs/android/android/graphics/Typeface.java b/java/ql/test/stubs/android/android/graphics/Typeface.java new file mode 100644 index 00000000000..a2ab630e8d0 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/Typeface.java @@ -0,0 +1,33 @@ +// Generated automatically from android.graphics.Typeface for testing purposes + +package android.graphics; + +import android.content.res.AssetManager; +import java.io.File; + +public class Typeface +{ + protected Typeface() {} + public boolean equals(Object p0){ return false; } + public final boolean isBold(){ return false; } + public final boolean isItalic(){ return false; } + public int getStyle(){ return 0; } + public int getWeight(){ return 0; } + public int hashCode(){ return 0; } + public static Typeface DEFAULT = null; + public static Typeface DEFAULT_BOLD = null; + public static Typeface MONOSPACE = null; + public static Typeface SANS_SERIF = null; + public static Typeface SERIF = null; + public static Typeface create(String p0, int p1){ return null; } + public static Typeface create(Typeface p0, int p1){ return null; } + public static Typeface create(Typeface p0, int p1, boolean p2){ return null; } + public static Typeface createFromAsset(AssetManager p0, String p1){ return null; } + public static Typeface createFromFile(File p0){ return null; } + public static Typeface createFromFile(String p0){ return null; } + public static Typeface defaultFromStyle(int p0){ return null; } + public static int BOLD = 0; + public static int BOLD_ITALIC = 0; + public static int ITALIC = 0; + public static int NORMAL = 0; +} diff --git a/java/ql/test/stubs/android/android/graphics/Xfermode.java b/java/ql/test/stubs/android/android/graphics/Xfermode.java new file mode 100644 index 00000000000..7b6e5ade001 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/Xfermode.java @@ -0,0 +1,9 @@ +// Generated automatically from android.graphics.Xfermode for testing purposes + +package android.graphics; + + +public class Xfermode +{ + public Xfermode(){} +} diff --git a/java/ql/test/stubs/android/android/graphics/drawable/Drawable.java b/java/ql/test/stubs/android/android/graphics/drawable/Drawable.java new file mode 100644 index 00000000000..5bb5b00f898 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/drawable/Drawable.java @@ -0,0 +1,111 @@ +// Generated automatically from android.graphics.drawable.Drawable for testing purposes + +package android.graphics.drawable; + +import android.content.res.ColorStateList; +import android.content.res.Resources; +import android.graphics.BitmapFactory; +import android.graphics.BlendMode; +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Insets; +import android.graphics.Outline; +import android.graphics.PorterDuff; +import android.graphics.Rect; +import android.graphics.Region; +import android.util.AttributeSet; +import android.util.TypedValue; +import java.io.InputStream; +import org.xmlpull.v1.XmlPullParser; + +abstract public class Drawable +{ + abstract static public class ConstantState + { + public ConstantState(){} + public Drawable newDrawable(Resources p0){ return null; } + public Drawable newDrawable(Resources p0, Resources.Theme p1){ return null; } + public abstract Drawable newDrawable(); + public abstract int getChangingConfigurations(); + public boolean canApplyTheme(){ return false; } + } + protected boolean onLevelChange(int p0){ return false; } + protected boolean onStateChange(int[] p0){ return false; } + protected void onBoundsChange(Rect p0){} + public ColorFilter getColorFilter(){ return null; } + public Drawable getCurrent(){ return null; } + public Drawable mutate(){ return null; } + public Drawable(){} + public Drawable.Callback getCallback(){ return null; } + public Drawable.ConstantState getConstantState(){ return null; } + public Insets getOpticalInsets(){ return null; } + public Rect getDirtyBounds(){ return null; } + public Region getTransparentRegion(){ return null; } + public abstract int getOpacity(); + public abstract void draw(Canvas p0); + public abstract void setAlpha(int p0); + public abstract void setColorFilter(ColorFilter p0); + public boolean canApplyTheme(){ return false; } + public boolean getPadding(Rect p0){ return false; } + public boolean isAutoMirrored(){ return false; } + public boolean isFilterBitmap(){ return false; } + public boolean isProjected(){ return false; } + public boolean isStateful(){ return false; } + public boolean onLayoutDirectionChanged(int p0){ return false; } + public boolean setState(int[] p0){ return false; } + public boolean setVisible(boolean p0, boolean p1){ return false; } + public final Rect copyBounds(){ return null; } + public final Rect getBounds(){ return null; } + public final boolean isVisible(){ return false; } + public final boolean setLayoutDirection(int p0){ return false; } + public final boolean setLevel(int p0){ return false; } + public final int getLevel(){ return 0; } + public final void copyBounds(Rect p0){} + public final void setCallback(Drawable.Callback p0){} + public int getAlpha(){ return 0; } + public int getChangingConfigurations(){ return 0; } + public int getIntrinsicHeight(){ return 0; } + public int getIntrinsicWidth(){ return 0; } + public int getLayoutDirection(){ return 0; } + public int getMinimumHeight(){ return 0; } + public int getMinimumWidth(){ return 0; } + public int[] getState(){ return null; } + public static Drawable createFromPath(String p0){ return null; } + public static Drawable createFromResourceStream(Resources p0, TypedValue p1, InputStream p2, String p3){ return null; } + public static Drawable createFromResourceStream(Resources p0, TypedValue p1, InputStream p2, String p3, BitmapFactory.Options p4){ return null; } + public static Drawable createFromStream(InputStream p0, String p1){ return null; } + public static Drawable createFromXml(Resources p0, XmlPullParser p1){ return null; } + public static Drawable createFromXml(Resources p0, XmlPullParser p1, Resources.Theme p2){ return null; } + public static Drawable createFromXmlInner(Resources p0, XmlPullParser p1, AttributeSet p2){ return null; } + public static Drawable createFromXmlInner(Resources p0, XmlPullParser p1, AttributeSet p2, Resources.Theme p3){ return null; } + public static int resolveOpacity(int p0, int p1){ return 0; } + public void applyTheme(Resources.Theme p0){} + public void clearColorFilter(){} + public void getHotspotBounds(Rect p0){} + public void getOutline(Outline p0){} + public void inflate(Resources p0, XmlPullParser p1, AttributeSet p2){} + public void inflate(Resources p0, XmlPullParser p1, AttributeSet p2, Resources.Theme p3){} + public void invalidateSelf(){} + public void jumpToCurrentState(){} + public void scheduleSelf(Runnable p0, long p1){} + public void setAutoMirrored(boolean p0){} + public void setBounds(Rect p0){} + public void setBounds(int p0, int p1, int p2, int p3){} + public void setChangingConfigurations(int p0){} + public void setColorFilter(int p0, PorterDuff.Mode p1){} + public void setDither(boolean p0){} + public void setFilterBitmap(boolean p0){} + public void setHotspot(float p0, float p1){} + public void setHotspotBounds(int p0, int p1, int p2, int p3){} + public void setTint(int p0){} + public void setTintBlendMode(BlendMode p0){} + public void setTintList(ColorStateList p0){} + public void setTintMode(PorterDuff.Mode p0){} + public void unscheduleSelf(Runnable p0){} + static public interface Callback + { + void invalidateDrawable(Drawable p0); + void scheduleDrawable(Drawable p0, Runnable p1, long p2); + void unscheduleDrawable(Drawable p0, Runnable p1); + } +} diff --git a/java/ql/test/stubs/android/android/graphics/drawable/Icon.java b/java/ql/test/stubs/android/android/graphics/drawable/Icon.java new file mode 100644 index 00000000000..fcfeb2b7109 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/drawable/Icon.java @@ -0,0 +1,55 @@ +// Generated automatically from android.graphics.drawable.Icon for testing purposes + +package android.graphics.drawable; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.Bitmap; +import android.graphics.BlendMode; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Handler; +import android.os.Message; +import android.os.Parcel; +import android.os.Parcelable; + +public class Icon implements Parcelable +{ + protected Icon() {} + public Drawable loadDrawable(Context p0){ return null; } + public Icon setTint(int p0){ return null; } + public Icon setTintBlendMode(BlendMode p0){ return null; } + public Icon setTintList(ColorStateList p0){ return null; } + public Icon setTintMode(PorterDuff.Mode p0){ return null; } + public String getResPackage(){ return null; } + public String toString(){ return null; } + public Uri getUri(){ return null; } + public int describeContents(){ return 0; } + public int getResId(){ return 0; } + public int getType(){ return 0; } + public static Icon createWithAdaptiveBitmap(Bitmap p0){ return null; } + public static Icon createWithAdaptiveBitmapContentUri(String p0){ return null; } + public static Icon createWithAdaptiveBitmapContentUri(Uri p0){ return null; } + public static Icon createWithBitmap(Bitmap p0){ return null; } + public static Icon createWithContentUri(String p0){ return null; } + public static Icon createWithContentUri(Uri p0){ return null; } + public static Icon createWithData(byte[] p0, int p1, int p2){ return null; } + public static Icon createWithFilePath(String p0){ return null; } + public static Icon createWithResource(Context p0, int p1){ return null; } + public static Icon createWithResource(String p0, int p1){ return null; } + public static Parcelable.Creator CREATOR = null; + public static int TYPE_ADAPTIVE_BITMAP = 0; + public static int TYPE_BITMAP = 0; + public static int TYPE_DATA = 0; + public static int TYPE_RESOURCE = 0; + public static int TYPE_URI = 0; + public static int TYPE_URI_ADAPTIVE_BITMAP = 0; + public void loadDrawableAsync(Context p0, Icon.OnDrawableLoadedListener p1, Handler p2){} + public void loadDrawableAsync(Context p0, Message p1){} + public void writeToParcel(Parcel p0, int p1){} + static public interface OnDrawableLoadedListener + { + void onDrawableLoaded(Drawable p0); + } +} diff --git a/java/ql/test/stubs/android/android/graphics/text/MeasuredText.java b/java/ql/test/stubs/android/android/graphics/text/MeasuredText.java new file mode 100644 index 00000000000..c737bd5dfc1 --- /dev/null +++ b/java/ql/test/stubs/android/android/graphics/text/MeasuredText.java @@ -0,0 +1,13 @@ +// Generated automatically from android.graphics.text.MeasuredText for testing purposes + +package android.graphics.text; + +import android.graphics.Rect; + +public class MeasuredText +{ + protected MeasuredText() {} + public float getCharWidthAt(int p0){ return 0; } + public float getWidth(int p0, int p1){ return 0; } + public void getBounds(int p0, int p1, Rect p2){} +} diff --git a/java/ql/test/stubs/android/android/hardware/HardwareBuffer.java b/java/ql/test/stubs/android/android/hardware/HardwareBuffer.java new file mode 100644 index 00000000000..0f4e5888a21 --- /dev/null +++ b/java/ql/test/stubs/android/android/hardware/HardwareBuffer.java @@ -0,0 +1,50 @@ +// Generated automatically from android.hardware.HardwareBuffer for testing purposes + +package android.hardware; + +import android.os.Parcel; +import android.os.Parcelable; + +public class HardwareBuffer implements AutoCloseable, Parcelable +{ + protected HardwareBuffer() {} + protected void finalize(){} + public boolean isClosed(){ return false; } + public int describeContents(){ return 0; } + public int getFormat(){ return 0; } + public int getHeight(){ return 0; } + public int getLayers(){ return 0; } + public int getWidth(){ return 0; } + public long getUsage(){ return 0; } + public static HardwareBuffer create(int p0, int p1, int p2, int p3, long p4){ return null; } + public static Parcelable.Creator CREATOR = null; + public static boolean isSupported(int p0, int p1, int p2, int p3, long p4){ return false; } + public static int BLOB = 0; + public static int DS_24UI8 = 0; + public static int DS_FP32UI8 = 0; + public static int D_16 = 0; + public static int D_24 = 0; + public static int D_FP32 = 0; + public static int RGBA_1010102 = 0; + public static int RGBA_8888 = 0; + public static int RGBA_FP16 = 0; + public static int RGBX_8888 = 0; + public static int RGB_565 = 0; + public static int RGB_888 = 0; + public static int S_UI8 = 0; + public static int YCBCR_420_888 = 0; + public static long USAGE_CPU_READ_OFTEN = 0; + public static long USAGE_CPU_READ_RARELY = 0; + public static long USAGE_CPU_WRITE_OFTEN = 0; + public static long USAGE_CPU_WRITE_RARELY = 0; + public static long USAGE_GPU_COLOR_OUTPUT = 0; + public static long USAGE_GPU_CUBE_MAP = 0; + public static long USAGE_GPU_DATA_BUFFER = 0; + public static long USAGE_GPU_MIPMAP_COMPLETE = 0; + public static long USAGE_GPU_SAMPLED_IMAGE = 0; + public static long USAGE_PROTECTED_CONTENT = 0; + public static long USAGE_SENSOR_DIRECT_DATA = 0; + public static long USAGE_VIDEO_ENCODE = 0; + public void close(){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/icu/util/ULocale.java b/java/ql/test/stubs/android/android/icu/util/ULocale.java new file mode 100644 index 00000000000..1e1ea662c22 --- /dev/null +++ b/java/ql/test/stubs/android/android/icu/util/ULocale.java @@ -0,0 +1,138 @@ +// Generated automatically from android.icu.util.ULocale for testing purposes + +package android.icu.util; + +import java.io.Serializable; +import java.util.Iterator; +import java.util.Locale; +import java.util.Set; + +public class ULocale implements Comparable, Serializable +{ + protected ULocale() {} + public Iterator getKeywords(){ return null; } + public Locale toLocale(){ return null; } + public Object clone(){ return null; } + public Set getExtensionKeys(){ return null; } + public Set getUnicodeLocaleAttributes(){ return null; } + public Set getUnicodeLocaleKeys(){ return null; } + public String getBaseName(){ return null; } + public String getCharacterOrientation(){ return null; } + public String getCountry(){ return null; } + public String getDisplayCountry(){ return null; } + public String getDisplayCountry(ULocale p0){ return null; } + public String getDisplayKeywordValue(String p0){ return null; } + public String getDisplayKeywordValue(String p0, ULocale p1){ return null; } + public String getDisplayLanguage(){ return null; } + public String getDisplayLanguage(ULocale p0){ return null; } + public String getDisplayLanguageWithDialect(){ return null; } + public String getDisplayLanguageWithDialect(ULocale p0){ return null; } + public String getDisplayName(){ return null; } + public String getDisplayName(ULocale p0){ return null; } + public String getDisplayNameWithDialect(){ return null; } + public String getDisplayNameWithDialect(ULocale p0){ return null; } + public String getDisplayScript(){ return null; } + public String getDisplayScript(ULocale p0){ return null; } + public String getDisplayVariant(){ return null; } + public String getDisplayVariant(ULocale p0){ return null; } + public String getExtension(char p0){ return null; } + public String getISO3Country(){ return null; } + public String getISO3Language(){ return null; } + public String getKeywordValue(String p0){ return null; } + public String getLanguage(){ return null; } + public String getLineOrientation(){ return null; } + public String getName(){ return null; } + public String getScript(){ return null; } + public String getUnicodeLocaleType(String p0){ return null; } + public String getVariant(){ return null; } + public String toLanguageTag(){ return null; } + public String toString(){ return null; } + public ULocale getFallback(){ return null; } + public ULocale setKeywordValue(String p0, String p1){ return null; } + public ULocale(String p0){} + public ULocale(String p0, String p1){} + public ULocale(String p0, String p1, String p2){} + public boolean equals(Object p0){ return false; } + public boolean isRightToLeft(){ return false; } + public int compareTo(ULocale p0){ return 0; } + public int hashCode(){ return 0; } + public static Iterator getKeywords(String p0){ return null; } + public static String canonicalize(String p0){ return null; } + public static String getBaseName(String p0){ return null; } + public static String getCountry(String p0){ return null; } + public static String getDisplayCountry(String p0, String p1){ return null; } + public static String getDisplayCountry(String p0, ULocale p1){ return null; } + public static String getDisplayKeyword(String p0){ return null; } + public static String getDisplayKeyword(String p0, String p1){ return null; } + public static String getDisplayKeyword(String p0, ULocale p1){ return null; } + public static String getDisplayKeywordValue(String p0, String p1, String p2){ return null; } + public static String getDisplayKeywordValue(String p0, String p1, ULocale p2){ return null; } + public static String getDisplayLanguage(String p0, String p1){ return null; } + public static String getDisplayLanguage(String p0, ULocale p1){ return null; } + public static String getDisplayLanguageWithDialect(String p0, String p1){ return null; } + public static String getDisplayLanguageWithDialect(String p0, ULocale p1){ return null; } + public static String getDisplayName(String p0, String p1){ return null; } + public static String getDisplayName(String p0, ULocale p1){ return null; } + public static String getDisplayNameWithDialect(String p0, String p1){ return null; } + public static String getDisplayNameWithDialect(String p0, ULocale p1){ return null; } + public static String getDisplayScript(String p0, String p1){ return null; } + public static String getDisplayScript(String p0, ULocale p1){ return null; } + public static String getDisplayVariant(String p0, String p1){ return null; } + public static String getDisplayVariant(String p0, ULocale p1){ return null; } + public static String getFallback(String p0){ return null; } + public static String getISO3Country(String p0){ return null; } + public static String getISO3Language(String p0){ return null; } + public static String getKeywordValue(String p0, String p1){ return null; } + public static String getLanguage(String p0){ return null; } + public static String getName(String p0){ return null; } + public static String getScript(String p0){ return null; } + public static String getVariant(String p0){ return null; } + public static String setKeywordValue(String p0, String p1, String p2){ return null; } + public static String toLegacyKey(String p0){ return null; } + public static String toLegacyType(String p0, String p1){ return null; } + public static String toUnicodeLocaleKey(String p0){ return null; } + public static String toUnicodeLocaleType(String p0, String p1){ return null; } + public static String[] getISOCountries(){ return null; } + public static String[] getISOLanguages(){ return null; } + public static ULocale CANADA = null; + public static ULocale CANADA_FRENCH = null; + public static ULocale CHINA = null; + public static ULocale CHINESE = null; + public static ULocale ENGLISH = null; + public static ULocale FRANCE = null; + public static ULocale FRENCH = null; + public static ULocale GERMAN = null; + public static ULocale GERMANY = null; + public static ULocale ITALIAN = null; + public static ULocale ITALY = null; + public static ULocale JAPAN = null; + public static ULocale JAPANESE = null; + public static ULocale KOREA = null; + public static ULocale KOREAN = null; + public static ULocale PRC = null; + public static ULocale ROOT = null; + public static ULocale SIMPLIFIED_CHINESE = null; + public static ULocale TAIWAN = null; + public static ULocale TRADITIONAL_CHINESE = null; + public static ULocale UK = null; + public static ULocale US = null; + public static ULocale acceptLanguage(String p0, ULocale[] p1, boolean[] p2){ return null; } + public static ULocale acceptLanguage(String p0, boolean[] p1){ return null; } + public static ULocale acceptLanguage(ULocale[] p0, ULocale[] p1, boolean[] p2){ return null; } + public static ULocale acceptLanguage(ULocale[] p0, boolean[] p1){ return null; } + public static ULocale addLikelySubtags(ULocale p0){ return null; } + public static ULocale createCanonical(String p0){ return null; } + public static ULocale forLanguageTag(String p0){ return null; } + public static ULocale forLocale(Locale p0){ return null; } + public static ULocale getDefault(){ return null; } + public static ULocale getDefault(ULocale.Category p0){ return null; } + public static ULocale minimizeSubtags(ULocale p0){ return null; } + public static ULocale[] getAvailableLocales(){ return null; } + public static char PRIVATE_USE_EXTENSION = '0'; + public static char UNICODE_LOCALE_EXTENSION = '0'; + static public enum Category + { + DISPLAY, FORMAT; + private Category() {} + } +} diff --git a/java/ql/test/stubs/android/android/net/Uri.java b/java/ql/test/stubs/android/android/net/Uri.java index 371dab3cc97..ec3e601b7bb 100644 --- a/java/ql/test/stubs/android/android/net/Uri.java +++ b/java/ql/test/stubs/android/android/net/Uri.java @@ -1,5 +1,76 @@ +// Generated automatically from android.net.Uri for testing purposes + package android.net; -public class Uri { +import android.os.Parcel; +import android.os.Parcelable; +import java.io.File; +import java.util.List; +import java.util.Set; +abstract public class Uri implements Comparable, Parcelable +{ + protected Uri() {} + public List getQueryParameters(String p0){ return null; } + public Set getQueryParameterNames(){ return null; } + public String getQueryParameter(String p0){ return null; } + public Uri normalizeScheme(){ return null; } + public abstract List getPathSegments(); + public abstract String getAuthority(); + public abstract String getEncodedAuthority(); + public abstract String getEncodedFragment(); + public abstract String getEncodedPath(); + public abstract String getEncodedQuery(); + public abstract String getEncodedSchemeSpecificPart(); + public abstract String getEncodedUserInfo(); + public abstract String getFragment(); + public abstract String getHost(); + public abstract String getLastPathSegment(); + public abstract String getPath(); + public abstract String getQuery(); + public abstract String getScheme(); + public abstract String getSchemeSpecificPart(); + public abstract String getUserInfo(); + public abstract String toString(); + public abstract Uri.Builder buildUpon(); + public abstract boolean isHierarchical(); + public abstract boolean isRelative(); + public abstract int getPort(); + public boolean equals(Object p0){ return false; } + public boolean getBooleanQueryParameter(String p0, boolean p1){ return false; } + public boolean isAbsolute(){ return false; } + public boolean isOpaque(){ return false; } + public int compareTo(Uri p0){ return 0; } + public int hashCode(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static String decode(String p0){ return null; } + public static String encode(String p0){ return null; } + public static String encode(String p0, String p1){ return null; } + public static Uri EMPTY = null; + public static Uri fromFile(File p0){ return null; } + public static Uri fromParts(String p0, String p1, String p2){ return null; } + public static Uri parse(String p0){ return null; } + public static Uri withAppendedPath(Uri p0, String p1){ return null; } + public static void writeToParcel(Parcel p0, Uri p1){} + static public class Builder + { + public Builder(){} + public String toString(){ return null; } + public Uri build(){ return null; } + public Uri.Builder appendEncodedPath(String p0){ return null; } + public Uri.Builder appendPath(String p0){ return null; } + public Uri.Builder appendQueryParameter(String p0, String p1){ return null; } + public Uri.Builder authority(String p0){ return null; } + public Uri.Builder clearQuery(){ return null; } + public Uri.Builder encodedAuthority(String p0){ return null; } + public Uri.Builder encodedFragment(String p0){ return null; } + public Uri.Builder encodedOpaquePart(String p0){ return null; } + public Uri.Builder encodedPath(String p0){ return null; } + public Uri.Builder encodedQuery(String p0){ return null; } + public Uri.Builder fragment(String p0){ return null; } + public Uri.Builder opaquePart(String p0){ return null; } + public Uri.Builder path(String p0){ return null; } + public Uri.Builder query(String p0){ return null; } + public Uri.Builder scheme(String p0){ return null; } + } } diff --git a/java/ql/test/stubs/android/android/os/BaseBundle.java b/java/ql/test/stubs/android/android/os/BaseBundle.java new file mode 100644 index 00000000000..3cc3c310c38 --- /dev/null +++ b/java/ql/test/stubs/android/android/os/BaseBundle.java @@ -0,0 +1,43 @@ +// Generated automatically from android.os.BaseBundle for testing purposes + +package android.os; + +import android.os.PersistableBundle; +import java.util.Set; + +public class BaseBundle +{ + public Object get(String p0){ return null; } + public Set keySet(){ return null; } + public String getString(String p0){ return null; } + public String getString(String p0, String p1){ return null; } + public String[] getStringArray(String p0){ return null; } + public boolean containsKey(String p0){ return false; } + public boolean getBoolean(String p0){ return false; } + public boolean getBoolean(String p0, boolean p1){ return false; } + public boolean isEmpty(){ return false; } + public boolean[] getBooleanArray(String p0){ return null; } + public double getDouble(String p0){ return 0; } + public double getDouble(String p0, double p1){ return 0; } + public double[] getDoubleArray(String p0){ return null; } + public int getInt(String p0){ return 0; } + public int getInt(String p0, int p1){ return 0; } + public int size(){ return 0; } + public int[] getIntArray(String p0){ return null; } + public long getLong(String p0){ return 0; } + public long getLong(String p0, long p1){ return 0; } + public long[] getLongArray(String p0){ return null; } + public void clear(){} + public void putAll(PersistableBundle p0){} + public void putBoolean(String p0, boolean p1){} + public void putBooleanArray(String p0, boolean[] p1){} + public void putDouble(String p0, double p1){} + public void putDoubleArray(String p0, double[] p1){} + public void putInt(String p0, int p1){} + public void putIntArray(String p0, int[] p1){} + public void putLong(String p0, long p1){} + public void putLongArray(String p0, long[] p1){} + public void putString(String p0, String p1){} + public void putStringArray(String p0, String[] p1){} + public void remove(String p0){} +} diff --git a/java/ql/test/stubs/android/android/os/Bundle.java b/java/ql/test/stubs/android/android/os/Bundle.java index fa49a640f30..4beb1cf5dee 100644 --- a/java/ql/test/stubs/android/android/os/Bundle.java +++ b/java/ql/test/stubs/android/android/os/Bundle.java @@ -1,87 +1,86 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Generated automatically from android.os.Bundle for testing purposes package android.os; -public final class Bundle { - public Bundle() { - } - - public Bundle(ClassLoader loader) { - } - - public Bundle(int capacity) { - } - - public Bundle(Bundle b) { - } - - public static Bundle forPair(String key, String value) { - return null; - } - - public boolean setAllowFds(boolean allowFds) { - return false; - } - - public void setDefusable(boolean defusable) { - } - - public static Bundle setDefusable(Bundle bundle, boolean defusable) { - return null; - } - - @Override - public Object clone() { - return null; - } - - public Bundle deepCopy() { - return null; - } - - public void remove(String key) { - } - - public void putAll(Bundle bundle) { - } - - public int getSize() { - return 0; - } - - public boolean hasFileDescriptors() { - return false; - } - - public Bundle filterValues() { - return null; - } - - @Override - public synchronized String toString() { - return null; - } - - public synchronized String toShortString() { - return null; - } - - public String getString(String string) { - return null; - } +import android.os.BaseBundle; +import android.os.IBinder; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.PersistableBundle; +import android.util.Size; +import android.util.SizeF; +import android.util.SparseArray; +import java.io.Serializable; +import java.util.ArrayList; +public class Bundle extends BaseBundle implements Cloneable, Parcelable +{ + public ArrayList getParcelableArrayList(String p0){ return null; } + public SparseArray getSparseParcelableArray(String p0){ return null; } + public T getParcelable(String p0){ return null; } + public ArrayList getCharSequenceArrayList(String p0){ return null; } + public ArrayList getIntegerArrayList(String p0){ return null; } + public ArrayList getStringArrayList(String p0){ return null; } + public Bundle deepCopy(){ return null; } + public Bundle getBundle(String p0){ return null; } + public Bundle(){} + public Bundle(Bundle p0){} + public Bundle(ClassLoader p0){} + public Bundle(PersistableBundle p0){} + public Bundle(int p0){} + public Byte getByte(String p0, byte p1){ return null; } + public CharSequence getCharSequence(String p0){ return null; } + public CharSequence getCharSequence(String p0, CharSequence p1){ return null; } + public CharSequence[] getCharSequenceArray(String p0){ return null; } + public ClassLoader getClassLoader(){ return null; } + public IBinder getBinder(String p0){ return null; } + public Object clone(){ return null; } + public Parcelable[] getParcelableArray(String p0){ return null; } + public Serializable getSerializable(String p0){ return null; } + public Size getSize(String p0){ return null; } + public SizeF getSizeF(String p0){ return null; } + public String toString(){ return null; } + public boolean hasFileDescriptors(){ return false; } + public byte getByte(String p0){ return 0; } + public byte[] getByteArray(String p0){ return null; } + public char getChar(String p0){ return '0'; } + public char getChar(String p0, char p1){ return '0'; } + public char[] getCharArray(String p0){ return null; } + public float getFloat(String p0){ return 0; } + public float getFloat(String p0, float p1){ return 0; } + public float[] getFloatArray(String p0){ return null; } + public int describeContents(){ return 0; } + public short getShort(String p0){ return 0; } + public short getShort(String p0, short p1){ return 0; } + public short[] getShortArray(String p0){ return null; } + public static Bundle EMPTY = null; + public static Parcelable.Creator CREATOR = null; + public void clear(){} + public void putAll(Bundle p0){} + public void putBinder(String p0, IBinder p1){} + public void putBundle(String p0, Bundle p1){} + public void putByte(String p0, byte p1){} + public void putByteArray(String p0, byte[] p1){} + public void putChar(String p0, char p1){} + public void putCharArray(String p0, char[] p1){} + public void putCharSequence(String p0, CharSequence p1){} + public void putCharSequenceArray(String p0, CharSequence[] p1){} + public void putCharSequenceArrayList(String p0, ArrayList p1){} + public void putFloat(String p0, float p1){} + public void putFloatArray(String p0, float[] p1){} + public void putIntegerArrayList(String p0, ArrayList p1){} + public void putParcelable(String p0, Parcelable p1){} + public void putParcelableArray(String p0, Parcelable[] p1){} + public void putParcelableArrayList(String p0, ArrayList p1){} + public void putSerializable(String p0, Serializable p1){} + public void putShort(String p0, short p1){} + public void putShortArray(String p0, short[] p1){} + public void putSize(String p0, Size p1){} + public void putSizeF(String p0, SizeF p1){} + public void putSparseParcelableArray(String p0, SparseArray p1){} + public void putStringArrayList(String p0, ArrayList p1){} + public void readFromParcel(Parcel p0){} + public void remove(String p0){} + public void setClassLoader(ClassLoader p0){} + public void writeToParcel(Parcel p0, int p1){} } diff --git a/java/ql/test/stubs/android/android/os/CancellationSignal.java b/java/ql/test/stubs/android/android/os/CancellationSignal.java index 212e605a819..5112eb46595 100644 --- a/java/ql/test/stubs/android/android/os/CancellationSignal.java +++ b/java/ql/test/stubs/android/android/os/CancellationSignal.java @@ -1,5 +1,17 @@ +// Generated automatically from android.os.CancellationSignal for testing purposes + package android.os; -public class CancellationSignal { +public class CancellationSignal +{ + public CancellationSignal(){} + public boolean isCanceled(){ return false; } + public void cancel(){} + public void setOnCancelListener(CancellationSignal.OnCancelListener p0){} + public void throwIfCanceled(){} + static public interface OnCancelListener + { + void onCancel(); + } } diff --git a/java/ql/test/stubs/android/android/os/Handler.java b/java/ql/test/stubs/android/android/os/Handler.java new file mode 100644 index 00000000000..5d1ae91db88 --- /dev/null +++ b/java/ql/test/stubs/android/android/os/Handler.java @@ -0,0 +1,53 @@ +// Generated automatically from android.os.Handler for testing purposes + +package android.os; + +import android.os.Looper; +import android.os.Message; +import android.util.Printer; + +public class Handler +{ + public Handler(){} + public Handler(Handler.Callback p0){} + public Handler(Looper p0){} + public Handler(Looper p0, Handler.Callback p1){} + public String getMessageName(Message p0){ return null; } + public String toString(){ return null; } + public boolean sendMessageAtTime(Message p0, long p1){ return false; } + public final Looper getLooper(){ return null; } + public final Message obtainMessage(){ return null; } + public final Message obtainMessage(int p0){ return null; } + public final Message obtainMessage(int p0, Object p1){ return null; } + public final Message obtainMessage(int p0, int p1, int p2){ return null; } + public final Message obtainMessage(int p0, int p1, int p2, Object p3){ return null; } + public final boolean hasCallbacks(Runnable p0){ return false; } + public final boolean hasMessages(int p0){ return false; } + public final boolean hasMessages(int p0, Object p1){ return false; } + public final boolean post(Runnable p0){ return false; } + public final boolean postAtFrontOfQueue(Runnable p0){ return false; } + public final boolean postAtTime(Runnable p0, Object p1, long p2){ return false; } + public final boolean postAtTime(Runnable p0, long p1){ return false; } + public final boolean postDelayed(Runnable p0, Object p1, long p2){ return false; } + public final boolean postDelayed(Runnable p0, long p1){ return false; } + public final boolean sendEmptyMessage(int p0){ return false; } + public final boolean sendEmptyMessageAtTime(int p0, long p1){ return false; } + public final boolean sendEmptyMessageDelayed(int p0, long p1){ return false; } + public final boolean sendMessage(Message p0){ return false; } + public final boolean sendMessageAtFrontOfQueue(Message p0){ return false; } + public final boolean sendMessageDelayed(Message p0, long p1){ return false; } + public final void dump(Printer p0, String p1){} + public final void removeCallbacks(Runnable p0){} + public final void removeCallbacks(Runnable p0, Object p1){} + public final void removeCallbacksAndMessages(Object p0){} + public final void removeMessages(int p0){} + public final void removeMessages(int p0, Object p1){} + public static Handler createAsync(Looper p0){ return null; } + public static Handler createAsync(Looper p0, Handler.Callback p1){ return null; } + public void dispatchMessage(Message p0){} + public void handleMessage(Message p0){} + static public interface Callback + { + boolean handleMessage(Message p0); + } +} diff --git a/java/ql/test/stubs/android/android/os/IBinder.java b/java/ql/test/stubs/android/android/os/IBinder.java new file mode 100644 index 00000000000..4441468b00f --- /dev/null +++ b/java/ql/test/stubs/android/android/os/IBinder.java @@ -0,0 +1,33 @@ +// Generated automatically from android.os.IBinder for testing purposes + +package android.os; + +import android.os.IInterface; +import android.os.Parcel; +import java.io.FileDescriptor; + +public interface IBinder +{ + IInterface queryLocalInterface(String p0); + String getInterfaceDescriptor(); + boolean isBinderAlive(); + boolean pingBinder(); + boolean transact(int p0, Parcel p1, Parcel p2, int p3); + boolean unlinkToDeath(IBinder.DeathRecipient p0, int p1); + static int DUMP_TRANSACTION = 0; + static int FIRST_CALL_TRANSACTION = 0; + static int FLAG_ONEWAY = 0; + static int INTERFACE_TRANSACTION = 0; + static int LAST_CALL_TRANSACTION = 0; + static int LIKE_TRANSACTION = 0; + static int PING_TRANSACTION = 0; + static int TWEET_TRANSACTION = 0; + static int getSuggestedMaxIpcSizeBytes(){ return 0; } + static public interface DeathRecipient + { + void binderDied(); + } + void dump(FileDescriptor p0, String[] p1); + void dumpAsync(FileDescriptor p0, String[] p1); + void linkToDeath(IBinder.DeathRecipient p0, int p1); +} diff --git a/java/ql/test/stubs/android/android/os/IInterface.java b/java/ql/test/stubs/android/android/os/IInterface.java new file mode 100644 index 00000000000..ccc3ae0a62d --- /dev/null +++ b/java/ql/test/stubs/android/android/os/IInterface.java @@ -0,0 +1,10 @@ +// Generated automatically from android.os.IInterface for testing purposes + +package android.os; + +import android.os.IBinder; + +public interface IInterface +{ + IBinder asBinder(); +} diff --git a/java/ql/test/stubs/android/android/os/LocaleList.java b/java/ql/test/stubs/android/android/os/LocaleList.java new file mode 100644 index 00000000000..113f5910a49 --- /dev/null +++ b/java/ql/test/stubs/android/android/os/LocaleList.java @@ -0,0 +1,32 @@ +// Generated automatically from android.os.LocaleList for testing purposes + +package android.os; + +import android.icu.util.ULocale; +import android.os.Parcel; +import android.os.Parcelable; +import java.util.Locale; + +public class LocaleList implements Parcelable +{ + protected LocaleList() {} + public Locale get(int p0){ return null; } + public Locale getFirstMatch(String[] p0){ return null; } + public LocaleList(Locale... p0){} + public String toLanguageTags(){ return null; } + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public int describeContents(){ return 0; } + public int hashCode(){ return 0; } + public int indexOf(Locale p0){ return 0; } + public int size(){ return 0; } + public static LocaleList forLanguageTags(String p0){ return null; } + public static LocaleList getAdjustedDefault(){ return null; } + public static LocaleList getDefault(){ return null; } + public static LocaleList getEmptyLocaleList(){ return null; } + public static Parcelable.Creator CREATOR = null; + public static boolean isPseudoLocale(ULocale p0){ return false; } + public static void setDefault(LocaleList p0){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/os/Looper.java b/java/ql/test/stubs/android/android/os/Looper.java new file mode 100644 index 00000000000..bc7076c2125 --- /dev/null +++ b/java/ql/test/stubs/android/android/os/Looper.java @@ -0,0 +1,25 @@ +// Generated automatically from android.os.Looper for testing purposes + +package android.os; + +import android.os.MessageQueue; +import android.util.Printer; + +public class Looper +{ + protected Looper() {} + public MessageQueue getQueue(){ return null; } + public String toString(){ return null; } + public Thread getThread(){ return null; } + public boolean isCurrentThread(){ return false; } + public static Looper getMainLooper(){ return null; } + public static Looper myLooper(){ return null; } + public static MessageQueue myQueue(){ return null; } + public static void loop(){} + public static void prepare(){} + public static void prepareMainLooper(){} + public void dump(Printer p0, String p1){} + public void quit(){} + public void quitSafely(){} + public void setMessageLogging(Printer p0){} +} diff --git a/java/ql/test/stubs/android/android/os/Message.java b/java/ql/test/stubs/android/android/os/Message.java new file mode 100644 index 00000000000..b6f98d43430 --- /dev/null +++ b/java/ql/test/stubs/android/android/os/Message.java @@ -0,0 +1,44 @@ +// Generated automatically from android.os.Message for testing purposes + +package android.os; + +import android.os.Bundle; +import android.os.Handler; +import android.os.Messenger; +import android.os.Parcel; +import android.os.Parcelable; + +public class Message implements Parcelable +{ + public Bundle getData(){ return null; } + public Bundle peekData(){ return null; } + public Handler getTarget(){ return null; } + public Message(){} + public Messenger replyTo = null; + public Object obj = null; + public Runnable getCallback(){ return null; } + public String toString(){ return null; } + public boolean isAsynchronous(){ return false; } + public int arg1 = 0; + public int arg2 = 0; + public int describeContents(){ return 0; } + public int sendingUid = 0; + public int what = 0; + public long getWhen(){ return 0; } + public static Message obtain(){ return null; } + public static Message obtain(Handler p0){ return null; } + public static Message obtain(Handler p0, Runnable p1){ return null; } + public static Message obtain(Handler p0, int p1){ return null; } + public static Message obtain(Handler p0, int p1, Object p2){ return null; } + public static Message obtain(Handler p0, int p1, int p2, int p3){ return null; } + public static Message obtain(Handler p0, int p1, int p2, int p3, Object p4){ return null; } + public static Message obtain(Message p0){ return null; } + public static Parcelable.Creator CREATOR = null; + public void copyFrom(Message p0){} + public void recycle(){} + public void sendToTarget(){} + public void setAsynchronous(boolean p0){} + public void setData(Bundle p0){} + public void setTarget(Handler p0){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/os/MessageQueue.java b/java/ql/test/stubs/android/android/os/MessageQueue.java new file mode 100644 index 00000000000..71d1e4b9fdd --- /dev/null +++ b/java/ql/test/stubs/android/android/os/MessageQueue.java @@ -0,0 +1,26 @@ +// Generated automatically from android.os.MessageQueue for testing purposes + +package android.os; + +import java.io.FileDescriptor; + +public class MessageQueue +{ + protected void finalize(){} + public boolean isIdle(){ return false; } + public void addIdleHandler(MessageQueue.IdleHandler p0){} + public void addOnFileDescriptorEventListener(FileDescriptor p0, int p1, MessageQueue.OnFileDescriptorEventListener p2){} + public void removeIdleHandler(MessageQueue.IdleHandler p0){} + public void removeOnFileDescriptorEventListener(FileDescriptor p0){} + static public interface IdleHandler + { + boolean queueIdle(); + } + static public interface OnFileDescriptorEventListener + { + int onFileDescriptorEvents(FileDescriptor p0, int p1); + static int EVENT_ERROR = 0; + static int EVENT_INPUT = 0; + static int EVENT_OUTPUT = 0; + } +} diff --git a/java/ql/test/stubs/android/android/os/Messenger.java b/java/ql/test/stubs/android/android/os/Messenger.java new file mode 100644 index 00000000000..08d2a975153 --- /dev/null +++ b/java/ql/test/stubs/android/android/os/Messenger.java @@ -0,0 +1,25 @@ +// Generated automatically from android.os.Messenger for testing purposes + +package android.os; + +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.os.Parcel; +import android.os.Parcelable; + +public class Messenger implements Parcelable +{ + protected Messenger() {} + public IBinder getBinder(){ return null; } + public Messenger(Handler p0){} + public Messenger(IBinder p0){} + public boolean equals(Object p0){ return false; } + public int describeContents(){ return 0; } + public int hashCode(){ return 0; } + public static Messenger readMessengerOrNullFromParcel(Parcel p0){ return null; } + public static Parcelable.Creator CREATOR = null; + public static void writeMessengerOrNullToParcel(Messenger p0, Parcel p1){} + public void send(Message p0){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/os/Parcel.java b/java/ql/test/stubs/android/android/os/Parcel.java new file mode 100644 index 00000000000..ef6dcdeb085 --- /dev/null +++ b/java/ql/test/stubs/android/android/os/Parcel.java @@ -0,0 +1,146 @@ +// Generated automatically from android.os.Parcel for testing purposes + +package android.os; + +import android.os.Bundle; +import android.os.IBinder; +import android.os.IInterface; +import android.os.ParcelFileDescriptor; +import android.os.Parcelable; +import android.os.PersistableBundle; +import android.util.ArrayMap; +import android.util.Size; +import android.util.SizeF; +import android.util.SparseArray; +import android.util.SparseBooleanArray; +import java.io.FileDescriptor; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Parcel +{ + protected Parcel() {} + protected void finalize(){} + public ArrayMap createTypedArrayMap(Parcelable.Creator p0){ return null; } + public List readParcelableList(List p0, ClassLoader p1){ return null; } + public SparseArray createTypedSparseArray(Parcelable.Creator p0){ return null; } + public T readParcelable(ClassLoader p0){ return null; } + public void writeParcelableArray(T[] p0, int p1){} + public void writeParcelableList(List p0, int p1){} + public void writeTypedArray(T[] p0, int p1){} + public void writeTypedArrayMap(ArrayMap p0, int p1){} + public void writeTypedList(List p0){} + public void writeTypedObject(T p0, int p1){} + public void writeTypedSparseArray(SparseArray p0, int p1){} + public ArrayList createTypedArrayList(Parcelable.Creator p0){ return null; } + public SparseArray readSparseArray(ClassLoader p0){ return null; } + public T readTypedObject(Parcelable.Creator p0){ return null; } + public T[] createTypedArray(Parcelable.Creator p0){ return null; } + public void readTypedArray(T[] p0, Parcelable.Creator p1){} + public void readTypedList(List p0, Parcelable.Creator p1){} + public void writeSparseArray(SparseArray p0){} + public ArrayList readArrayList(ClassLoader p0){ return null; } + public ArrayList createBinderArrayList(){ return null; } + public ArrayList createStringArrayList(){ return null; } + public Bundle readBundle(){ return null; } + public Bundle readBundle(ClassLoader p0){ return null; } + public HashMap readHashMap(ClassLoader p0){ return null; } + public IBinder readStrongBinder(){ return null; } + public IBinder[] createBinderArray(){ return null; } + public Object readValue(ClassLoader p0){ return null; } + public Object[] readArray(ClassLoader p0){ return null; } + public ParcelFileDescriptor readFileDescriptor(){ return null; } + public Parcelable.Creator readParcelableCreator(ClassLoader p0){ return null; } + public Parcelable[] readParcelableArray(ClassLoader p0){ return null; } + public PersistableBundle readPersistableBundle(){ return null; } + public PersistableBundle readPersistableBundle(ClassLoader p0){ return null; } + public Serializable readSerializable(){ return null; } + public Size readSize(){ return null; } + public SizeF readSizeF(){ return null; } + public SparseBooleanArray readSparseBooleanArray(){ return null; } + public String readString(){ return null; } + public String[] createStringArray(){ return null; } + public boolean hasFileDescriptors(){ return false; } + public boolean readBoolean(){ return false; } + public boolean[] createBooleanArray(){ return null; } + public byte readByte(){ return 0; } + public byte[] createByteArray(){ return null; } + public byte[] marshall(){ return null; } + public char[] createCharArray(){ return null; } + public double readDouble(){ return 0; } + public double[] createDoubleArray(){ return null; } + public float readFloat(){ return 0; } + public float[] createFloatArray(){ return null; } + public int dataAvail(){ return 0; } + public int dataCapacity(){ return 0; } + public int dataPosition(){ return 0; } + public int dataSize(){ return 0; } + public int readInt(){ return 0; } + public int[] createIntArray(){ return null; } + public long readLong(){ return 0; } + public long[] createLongArray(){ return null; } + public static Parcel obtain(){ return null; } + public static Parcelable.Creator STRING_CREATOR = null; + public void appendFrom(Parcel p0, int p1, int p2){} + public void enforceInterface(String p0){} + public void readBinderArray(IBinder[] p0){} + public void readBinderList(List p0){} + public void readBooleanArray(boolean[] p0){} + public void readByteArray(byte[] p0){} + public void readCharArray(char[] p0){} + public void readDoubleArray(double[] p0){} + public void readException(){} + public void readException(int p0, String p1){} + public void readFloatArray(float[] p0){} + public void readIntArray(int[] p0){} + public void readList(List p0, ClassLoader p1){} + public void readLongArray(long[] p0){} + public void readMap(Map p0, ClassLoader p1){} + public void readStringArray(String[] p0){} + public void readStringList(List p0){} + public void recycle(){} + public void setDataCapacity(int p0){} + public void setDataPosition(int p0){} + public void setDataSize(int p0){} + public void unmarshall(byte[] p0, int p1, int p2){} + public void writeArray(Object[] p0){} + public void writeBinderArray(IBinder[] p0){} + public void writeBinderList(List p0){} + public void writeBoolean(boolean p0){} + public void writeBooleanArray(boolean[] p0){} + public void writeBundle(Bundle p0){} + public void writeByte(byte p0){} + public void writeByteArray(byte[] p0){} + public void writeByteArray(byte[] p0, int p1, int p2){} + public void writeCharArray(char[] p0){} + public void writeDouble(double p0){} + public void writeDoubleArray(double[] p0){} + public void writeException(Exception p0){} + public void writeFileDescriptor(FileDescriptor p0){} + public void writeFloat(float p0){} + public void writeFloatArray(float[] p0){} + public void writeInt(int p0){} + public void writeIntArray(int[] p0){} + public void writeInterfaceToken(String p0){} + public void writeList(List p0){} + public void writeLong(long p0){} + public void writeLongArray(long[] p0){} + public void writeMap(Map p0){} + public void writeNoException(){} + public void writeParcelable(Parcelable p0, int p1){} + public void writeParcelableCreator(Parcelable p0){} + public void writePersistableBundle(PersistableBundle p0){} + public void writeSerializable(Serializable p0){} + public void writeSize(Size p0){} + public void writeSizeF(SizeF p0){} + public void writeSparseBooleanArray(SparseBooleanArray p0){} + public void writeString(String p0){} + public void writeStringArray(String[] p0){} + public void writeStringList(List p0){} + public void writeStrongBinder(IBinder p0){} + public void writeStrongInterface(IInterface p0){} + public void writeValue(Object p0){} +} diff --git a/java/ql/test/stubs/android/android/os/ParcelFileDescriptor.java b/java/ql/test/stubs/android/android/os/ParcelFileDescriptor.java index 757872bb457..05b41873d41 100644 --- a/java/ql/test/stubs/android/android/os/ParcelFileDescriptor.java +++ b/java/ql/test/stubs/android/android/os/ParcelFileDescriptor.java @@ -1,5 +1,58 @@ +// Generated automatically from android.os.ParcelFileDescriptor for testing purposes + package android.os; -public class ParcelFileDescriptor { +import android.os.Handler; +import android.os.Parcel; +import android.os.Parcelable; +import java.io.Closeable; +import java.io.File; +import java.io.FileDescriptor; +import java.io.IOException; +import java.net.DatagramSocket; +import java.net.Socket; +public class ParcelFileDescriptor implements Closeable, Parcelable +{ + protected ParcelFileDescriptor() {} + protected void finalize(){} + public FileDescriptor getFileDescriptor(){ return null; } + public ParcelFileDescriptor dup(){ return null; } + public ParcelFileDescriptor(ParcelFileDescriptor p0){} + public String toString(){ return null; } + public boolean canDetectErrors(){ return false; } + public int describeContents(){ return 0; } + public int detachFd(){ return 0; } + public int getFd(){ return 0; } + public long getStatSize(){ return 0; } + public static ParcelFileDescriptor adoptFd(int p0){ return null; } + public static ParcelFileDescriptor dup(FileDescriptor p0){ return null; } + public static ParcelFileDescriptor fromDatagramSocket(DatagramSocket p0){ return null; } + public static ParcelFileDescriptor fromFd(int p0){ return null; } + public static ParcelFileDescriptor fromSocket(Socket p0){ return null; } + public static ParcelFileDescriptor open(File p0, int p1){ return null; } + public static ParcelFileDescriptor open(File p0, int p1, Handler p2, ParcelFileDescriptor.OnCloseListener p3){ return null; } + public static ParcelFileDescriptor wrap(ParcelFileDescriptor p0, Handler p1, ParcelFileDescriptor.OnCloseListener p2){ return null; } + public static ParcelFileDescriptor[] createPipe(){ return null; } + public static ParcelFileDescriptor[] createReliablePipe(){ return null; } + public static ParcelFileDescriptor[] createReliableSocketPair(){ return null; } + public static ParcelFileDescriptor[] createSocketPair(){ return null; } + public static Parcelable.Creator CREATOR = null; + public static int MODE_APPEND = 0; + public static int MODE_CREATE = 0; + public static int MODE_READ_ONLY = 0; + public static int MODE_READ_WRITE = 0; + public static int MODE_TRUNCATE = 0; + public static int MODE_WORLD_READABLE = 0; + public static int MODE_WORLD_WRITEABLE = 0; + public static int MODE_WRITE_ONLY = 0; + public static int parseMode(String p0){ return 0; } + public void checkError(){} + public void close(){} + public void closeWithError(String p0){} + public void writeToParcel(Parcel p0, int p1){} + static public interface OnCloseListener + { + void onClose(IOException p0); + } } diff --git a/java/ql/test/stubs/android/android/os/Parcelable.java b/java/ql/test/stubs/android/android/os/Parcelable.java new file mode 100644 index 00000000000..626061a6799 --- /dev/null +++ b/java/ql/test/stubs/android/android/os/Parcelable.java @@ -0,0 +1,18 @@ +// Generated automatically from android.os.Parcelable for testing purposes + +package android.os; + +import android.os.Parcel; + +public interface Parcelable +{ + int describeContents(); + static int CONTENTS_FILE_DESCRIPTOR = 0; + static int PARCELABLE_WRITE_RETURN_VALUE = 0; + static public interface Creator + { + T createFromParcel(Parcel p0); + T[] newArray(int p0); + } + void writeToParcel(Parcel p0, int p1); +} diff --git a/java/ql/test/stubs/android/android/os/PatternMatcher.java b/java/ql/test/stubs/android/android/os/PatternMatcher.java new file mode 100644 index 00000000000..d23c55aefd1 --- /dev/null +++ b/java/ql/test/stubs/android/android/os/PatternMatcher.java @@ -0,0 +1,24 @@ +// Generated automatically from android.os.PatternMatcher for testing purposes + +package android.os; + +import android.os.Parcel; +import android.os.Parcelable; + +public class PatternMatcher implements Parcelable +{ + protected PatternMatcher() {} + public PatternMatcher(Parcel p0){} + public PatternMatcher(String p0, int p1){} + public String toString(){ return null; } + public boolean match(String p0){ return false; } + public final String getPath(){ return null; } + public final int getType(){ return 0; } + public int describeContents(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static int PATTERN_ADVANCED_GLOB = 0; + public static int PATTERN_LITERAL = 0; + public static int PATTERN_PREFIX = 0; + public static int PATTERN_SIMPLE_GLOB = 0; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/os/PersistableBundle.java b/java/ql/test/stubs/android/android/os/PersistableBundle.java new file mode 100644 index 00000000000..45354eb5b53 --- /dev/null +++ b/java/ql/test/stubs/android/android/os/PersistableBundle.java @@ -0,0 +1,27 @@ +// Generated automatically from android.os.PersistableBundle for testing purposes + +package android.os; + +import android.os.BaseBundle; +import android.os.Parcel; +import android.os.Parcelable; +import java.io.InputStream; +import java.io.OutputStream; + +public class PersistableBundle extends BaseBundle implements Cloneable, Parcelable +{ + public Object clone(){ return null; } + public PersistableBundle deepCopy(){ return null; } + public PersistableBundle getPersistableBundle(String p0){ return null; } + public PersistableBundle(){} + public PersistableBundle(PersistableBundle p0){} + public PersistableBundle(int p0){} + public String toString(){ return null; } + public int describeContents(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static PersistableBundle EMPTY = null; + public static PersistableBundle readFromStream(InputStream p0){ return null; } + public void putPersistableBundle(String p0, PersistableBundle p1){} + public void writeToParcel(Parcel p0, int p1){} + public void writeToStream(OutputStream p0){} +} diff --git a/java/ql/test/stubs/android/android/os/UserHandle.java b/java/ql/test/stubs/android/android/os/UserHandle.java new file mode 100644 index 00000000000..a2e4d596054 --- /dev/null +++ b/java/ql/test/stubs/android/android/os/UserHandle.java @@ -0,0 +1,21 @@ +// Generated automatically from android.os.UserHandle for testing purposes + +package android.os; + +import android.os.Parcel; +import android.os.Parcelable; + +public class UserHandle implements Parcelable +{ + protected UserHandle() {} + public String toString(){ return null; } + public UserHandle(Parcel p0){} + public boolean equals(Object p0){ return false; } + public int describeContents(){ return 0; } + public int hashCode(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static UserHandle getUserHandleForUid(int p0){ return null; } + public static UserHandle readFromParcel(Parcel p0){ return null; } + public static void writeToParcel(UserHandle p0, Parcel p1){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/android/android/util/AndroidException.java b/java/ql/test/stubs/android/android/util/AndroidException.java new file mode 100644 index 00000000000..aee2fef29f7 --- /dev/null +++ b/java/ql/test/stubs/android/android/util/AndroidException.java @@ -0,0 +1,12 @@ +// Generated automatically from android.util.AndroidException for testing purposes + +package android.util; + + +public class AndroidException extends Exception +{ + public AndroidException(){} + public AndroidException(Exception p0){} + public AndroidException(String p0){} + public AndroidException(String p0, Throwable p1){} +} diff --git a/java/ql/test/stubs/android/android/util/ArrayMap.java b/java/ql/test/stubs/android/android/util/ArrayMap.java new file mode 100644 index 00000000000..55c7adebea7 --- /dev/null +++ b/java/ql/test/stubs/android/android/util/ArrayMap.java @@ -0,0 +1,40 @@ +// Generated automatically from android.util.ArrayMap for testing purposes + +package android.util; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +public class ArrayMap implements Map +{ + public ArrayMap(){} + public ArrayMap(ArrayMap p0){} + public ArrayMap(int p0){} + public Collection values(){ return null; } + public K keyAt(int p0){ return null; } + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public String toString(){ return null; } + public V get(Object p0){ return null; } + public V put(K p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public V removeAt(int p0){ return null; } + public V setValueAt(int p0, V p1){ return null; } + public V valueAt(int p0){ return null; } + public boolean containsAll(Collection p0){ return false; } + public boolean containsKey(Object p0){ return false; } + public boolean containsValue(Object p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public int hashCode(){ return 0; } + public int indexOfKey(Object p0){ return 0; } + public int indexOfValue(Object p0){ return 0; } + public int size(){ return 0; } + public void clear(){} + public void ensureCapacity(int p0){} + public void putAll(ArrayMap p0){} + public void putAll(Map p0){} +} diff --git a/java/ql/test/stubs/android/android/util/AttributeSet.java b/java/ql/test/stubs/android/android/util/AttributeSet.java index 27159b91485..04bdbe6b8d2 100644 --- a/java/ql/test/stubs/android/android/util/AttributeSet.java +++ b/java/ql/test/stubs/android/android/util/AttributeSet.java @@ -1,74 +1,31 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Generated automatically from android.util.AttributeSet for testing purposes package android.util; -public interface AttributeSet { - public int getAttributeCount(); - - default String getAttributeNamespace (int index) { - return null; - } - - public String getAttributeName(int index); - - public String getAttributeValue(int index); - - public String getAttributeValue(String namespace, String name); - - public String getPositionDescription(); - - public int getAttributeNameResource(int index); - - public int getAttributeListValue(String namespace, String attribute, - String[] options, int defaultValue); - - public boolean getAttributeBooleanValue(String namespace, String attribute, - boolean defaultValue); - - public int getAttributeResourceValue(String namespace, String attribute, - int defaultValue); - - public int getAttributeIntValue(String namespace, String attribute, - int defaultValue); - - public int getAttributeUnsignedIntValue(String namespace, String attribute, - int defaultValue); - - public float getAttributeFloatValue(String namespace, String attribute, - float defaultValue); - - public int getAttributeListValue(int index, String[] options, int defaultValue); - - public boolean getAttributeBooleanValue(int index, boolean defaultValue); - - public int getAttributeResourceValue(int index, int defaultValue); - - public int getAttributeIntValue(int index, int defaultValue); - - public int getAttributeUnsignedIntValue(int index, int defaultValue); - - public float getAttributeFloatValue(int index, float defaultValue); - - public String getIdAttribute(); - - public String getClassAttribute(); - - public int getIdAttributeResourceValue(int defaultValue); - - public int getStyleAttribute(); +public interface AttributeSet +{ + String getAttributeName(int p0); + String getAttributeValue(String p0, String p1); + String getAttributeValue(int p0); + String getClassAttribute(); + String getIdAttribute(); + String getPositionDescription(); + boolean getAttributeBooleanValue(String p0, String p1, boolean p2); + boolean getAttributeBooleanValue(int p0, boolean p1); + default String getAttributeNamespace(int p0){ return null; } + float getAttributeFloatValue(String p0, String p1, float p2); + float getAttributeFloatValue(int p0, float p1); + int getAttributeCount(); + int getAttributeIntValue(String p0, String p1, int p2); + int getAttributeIntValue(int p0, int p1); + int getAttributeListValue(String p0, String p1, String[] p2, int p3); + int getAttributeListValue(int p0, String[] p1, int p2); + int getAttributeNameResource(int p0); + int getAttributeResourceValue(String p0, String p1, int p2); + int getAttributeResourceValue(int p0, int p1); + int getAttributeUnsignedIntValue(String p0, String p1, int p2); + int getAttributeUnsignedIntValue(int p0, int p1); + int getIdAttributeResourceValue(int p0); + int getStyleAttribute(); } diff --git a/java/ql/test/stubs/android/android/util/DisplayMetrics.java b/java/ql/test/stubs/android/android/util/DisplayMetrics.java new file mode 100644 index 00000000000..fe64b670921 --- /dev/null +++ b/java/ql/test/stubs/android/android/util/DisplayMetrics.java @@ -0,0 +1,46 @@ +// Generated automatically from android.util.DisplayMetrics for testing purposes + +package android.util; + + +public class DisplayMetrics +{ + public DisplayMetrics(){} + public String toString(){ return null; } + public boolean equals(DisplayMetrics p0){ return false; } + public boolean equals(Object p0){ return false; } + public float density = 0; + public float scaledDensity = 0; + public float xdpi = 0; + public float ydpi = 0; + public int densityDpi = 0; + public int hashCode(){ return 0; } + public int heightPixels = 0; + public int widthPixels = 0; + public static int DENSITY_140 = 0; + public static int DENSITY_180 = 0; + public static int DENSITY_200 = 0; + public static int DENSITY_220 = 0; + public static int DENSITY_260 = 0; + public static int DENSITY_280 = 0; + public static int DENSITY_300 = 0; + public static int DENSITY_340 = 0; + public static int DENSITY_360 = 0; + public static int DENSITY_400 = 0; + public static int DENSITY_420 = 0; + public static int DENSITY_440 = 0; + public static int DENSITY_450 = 0; + public static int DENSITY_560 = 0; + public static int DENSITY_600 = 0; + public static int DENSITY_DEFAULT = 0; + public static int DENSITY_DEVICE_STABLE = 0; + public static int DENSITY_HIGH = 0; + public static int DENSITY_LOW = 0; + public static int DENSITY_MEDIUM = 0; + public static int DENSITY_TV = 0; + public static int DENSITY_XHIGH = 0; + public static int DENSITY_XXHIGH = 0; + public static int DENSITY_XXXHIGH = 0; + public void setTo(DisplayMetrics p0){} + public void setToDefaults(){} +} diff --git a/java/ql/test/stubs/android/android/util/Pair.java b/java/ql/test/stubs/android/android/util/Pair.java new file mode 100644 index 00000000000..84a73730e05 --- /dev/null +++ b/java/ql/test/stubs/android/android/util/Pair.java @@ -0,0 +1,16 @@ +// Generated automatically from android.util.Pair for testing purposes + +package android.util; + + +public class Pair +{ + protected Pair() {} + public Pair(F p0, S p1){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public final F first = null; + public final S second = null; + public int hashCode(){ return 0; } + public static Pair create(A p0, B p1){ return null; } +} diff --git a/java/ql/test/stubs/android/android/util/Printer.java b/java/ql/test/stubs/android/android/util/Printer.java new file mode 100644 index 00000000000..e6b67a13572 --- /dev/null +++ b/java/ql/test/stubs/android/android/util/Printer.java @@ -0,0 +1,9 @@ +// Generated automatically from android.util.Printer for testing purposes + +package android.util; + + +public interface Printer +{ + void println(String p0); +} diff --git a/java/ql/test/stubs/android/android/util/Size.java b/java/ql/test/stubs/android/android/util/Size.java new file mode 100644 index 00000000000..9cd6edc8555 --- /dev/null +++ b/java/ql/test/stubs/android/android/util/Size.java @@ -0,0 +1,16 @@ +// Generated automatically from android.util.Size for testing purposes + +package android.util; + + +public class Size +{ + protected Size() {} + public Size(int p0, int p1){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public int getHeight(){ return 0; } + public int getWidth(){ return 0; } + public int hashCode(){ return 0; } + public static Size parseSize(String p0){ return null; } +} diff --git a/java/ql/test/stubs/android/android/util/SizeF.java b/java/ql/test/stubs/android/android/util/SizeF.java new file mode 100644 index 00000000000..16558fd17e6 --- /dev/null +++ b/java/ql/test/stubs/android/android/util/SizeF.java @@ -0,0 +1,16 @@ +// Generated automatically from android.util.SizeF for testing purposes + +package android.util; + + +public class SizeF +{ + protected SizeF() {} + public SizeF(float p0, float p1){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public float getHeight(){ return 0; } + public float getWidth(){ return 0; } + public int hashCode(){ return 0; } + public static SizeF parseSizeF(String p0){ return null; } +} diff --git a/java/ql/test/stubs/android/android/util/SparseArray.java b/java/ql/test/stubs/android/android/util/SparseArray.java new file mode 100644 index 00000000000..11f3ffa5427 --- /dev/null +++ b/java/ql/test/stubs/android/android/util/SparseArray.java @@ -0,0 +1,28 @@ +// Generated automatically from android.util.SparseArray for testing purposes + +package android.util; + + +public class SparseArray implements Cloneable +{ + public E get(int p0){ return null; } + public E get(int p0, E p1){ return null; } + public E valueAt(int p0){ return null; } + public SparseArray(){} + public SparseArray(int p0){} + public SparseArray clone(){ return null; } + public String toString(){ return null; } + public boolean contains(int p0){ return false; } + public int indexOfKey(int p0){ return 0; } + public int indexOfValue(E p0){ return 0; } + public int keyAt(int p0){ return 0; } + public int size(){ return 0; } + public void append(int p0, E p1){} + public void clear(){} + public void delete(int p0){} + public void put(int p0, E p1){} + public void remove(int p0){} + public void removeAt(int p0){} + public void removeAtRange(int p0, int p1){} + public void setValueAt(int p0, E p1){} +} diff --git a/java/ql/test/stubs/android/android/util/SparseBooleanArray.java b/java/ql/test/stubs/android/android/util/SparseBooleanArray.java new file mode 100644 index 00000000000..3c84c18e71b --- /dev/null +++ b/java/ql/test/stubs/android/android/util/SparseBooleanArray.java @@ -0,0 +1,27 @@ +// Generated automatically from android.util.SparseBooleanArray for testing purposes + +package android.util; + + +public class SparseBooleanArray implements Cloneable +{ + public SparseBooleanArray clone(){ return null; } + public SparseBooleanArray(){} + public SparseBooleanArray(int p0){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public boolean get(int p0){ return false; } + public boolean get(int p0, boolean p1){ return false; } + public boolean valueAt(int p0){ return false; } + public int hashCode(){ return 0; } + public int indexOfKey(int p0){ return 0; } + public int indexOfValue(boolean p0){ return 0; } + public int keyAt(int p0){ return 0; } + public int size(){ return 0; } + public void append(int p0, boolean p1){} + public void clear(){} + public void delete(int p0){} + public void put(int p0, boolean p1){} + public void removeAt(int p0){} + public void setValueAt(int p0, boolean p1){} +} diff --git a/java/ql/test/stubs/android/android/util/TypedValue.java b/java/ql/test/stubs/android/android/util/TypedValue.java new file mode 100644 index 00000000000..269ab8bcf67 --- /dev/null +++ b/java/ql/test/stubs/android/android/util/TypedValue.java @@ -0,0 +1,73 @@ +// Generated automatically from android.util.TypedValue for testing purposes + +package android.util; + +import android.util.DisplayMetrics; + +public class TypedValue +{ + public CharSequence string = null; + public String toString(){ return null; } + public TypedValue(){} + public boolean isColorType(){ return false; } + public final CharSequence coerceToString(){ return null; } + public final float getFloat(){ return 0; } + public float getDimension(DisplayMetrics p0){ return 0; } + public float getFraction(float p0, float p1){ return 0; } + public int assetCookie = 0; + public int changingConfigurations = 0; + public int data = 0; + public int density = 0; + public int getComplexUnit(){ return 0; } + public int resourceId = 0; + public int sourceResourceId = 0; + public int type = 0; + public static String coerceToString(int p0, int p1){ return null; } + public static float applyDimension(int p0, float p1, DisplayMetrics p2){ return 0; } + public static float complexToDimension(int p0, DisplayMetrics p1){ return 0; } + public static float complexToFloat(int p0){ return 0; } + public static float complexToFraction(int p0, float p1, float p2){ return 0; } + public static int COMPLEX_MANTISSA_MASK = 0; + public static int COMPLEX_MANTISSA_SHIFT = 0; + public static int COMPLEX_RADIX_0p23 = 0; + public static int COMPLEX_RADIX_16p7 = 0; + public static int COMPLEX_RADIX_23p0 = 0; + public static int COMPLEX_RADIX_8p15 = 0; + public static int COMPLEX_RADIX_MASK = 0; + public static int COMPLEX_RADIX_SHIFT = 0; + public static int COMPLEX_UNIT_DIP = 0; + public static int COMPLEX_UNIT_FRACTION = 0; + public static int COMPLEX_UNIT_FRACTION_PARENT = 0; + public static int COMPLEX_UNIT_IN = 0; + public static int COMPLEX_UNIT_MASK = 0; + public static int COMPLEX_UNIT_MM = 0; + public static int COMPLEX_UNIT_PT = 0; + public static int COMPLEX_UNIT_PX = 0; + public static int COMPLEX_UNIT_SHIFT = 0; + public static int COMPLEX_UNIT_SP = 0; + public static int DATA_NULL_EMPTY = 0; + public static int DATA_NULL_UNDEFINED = 0; + public static int DENSITY_DEFAULT = 0; + public static int DENSITY_NONE = 0; + public static int TYPE_ATTRIBUTE = 0; + public static int TYPE_DIMENSION = 0; + public static int TYPE_FIRST_COLOR_INT = 0; + public static int TYPE_FIRST_INT = 0; + public static int TYPE_FLOAT = 0; + public static int TYPE_FRACTION = 0; + public static int TYPE_INT_BOOLEAN = 0; + public static int TYPE_INT_COLOR_ARGB4 = 0; + public static int TYPE_INT_COLOR_ARGB8 = 0; + public static int TYPE_INT_COLOR_RGB4 = 0; + public static int TYPE_INT_COLOR_RGB8 = 0; + public static int TYPE_INT_DEC = 0; + public static int TYPE_INT_HEX = 0; + public static int TYPE_LAST_COLOR_INT = 0; + public static int TYPE_LAST_INT = 0; + public static int TYPE_NULL = 0; + public static int TYPE_REFERENCE = 0; + public static int TYPE_STRING = 0; + public static int complexToDimensionPixelOffset(int p0, DisplayMetrics p1){ return 0; } + public static int complexToDimensionPixelSize(int p0, DisplayMetrics p1){ return 0; } + public void setTo(TypedValue p0){} +} diff --git a/java/ql/test/stubs/android/android/view/Display.java b/java/ql/test/stubs/android/android/view/Display.java new file mode 100644 index 00000000000..8c8061f00cb --- /dev/null +++ b/java/ql/test/stubs/android/android/view/Display.java @@ -0,0 +1,89 @@ +// Generated automatically from android.view.Display for testing purposes + +package android.view; + +import android.graphics.ColorSpace; +import android.graphics.Point; +import android.graphics.Rect; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.DisplayMetrics; +import android.view.DisplayCutout; + +public class Display +{ + public ColorSpace getPreferredWideGamutColorSpace(){ return null; } + public Display.HdrCapabilities getHdrCapabilities(){ return null; } + public Display.Mode getMode(){ return null; } + public Display.Mode[] getSupportedModes(){ return null; } + public DisplayCutout getCutout(){ return null; } + public String getName(){ return null; } + public String toString(){ return null; } + public boolean isHdr(){ return false; } + public boolean isMinimalPostProcessingSupported(){ return false; } + public boolean isValid(){ return false; } + public boolean isWideColorGamut(){ return false; } + public float getRefreshRate(){ return 0; } + public float[] getSupportedRefreshRates(){ return null; } + public int getDisplayId(){ return 0; } + public int getFlags(){ return 0; } + public int getHeight(){ return 0; } + public int getOrientation(){ return 0; } + public int getPixelFormat(){ return 0; } + public int getRotation(){ return 0; } + public int getState(){ return 0; } + public int getWidth(){ return 0; } + public long getAppVsyncOffsetNanos(){ return 0; } + public long getPresentationDeadlineNanos(){ return 0; } + public static int DEFAULT_DISPLAY = 0; + public static int FLAG_PRESENTATION = 0; + public static int FLAG_PRIVATE = 0; + public static int FLAG_ROUND = 0; + public static int FLAG_SECURE = 0; + public static int FLAG_SUPPORTS_PROTECTED_BUFFERS = 0; + public static int INVALID_DISPLAY = 0; + public static int STATE_DOZE = 0; + public static int STATE_DOZE_SUSPEND = 0; + public static int STATE_OFF = 0; + public static int STATE_ON = 0; + public static int STATE_ON_SUSPEND = 0; + public static int STATE_UNKNOWN = 0; + public static int STATE_VR = 0; + public void getCurrentSizeRange(Point p0, Point p1){} + public void getMetrics(DisplayMetrics p0){} + public void getRealMetrics(DisplayMetrics p0){} + public void getRealSize(Point p0){} + public void getRectSize(Rect p0){} + public void getSize(Point p0){} + static public class HdrCapabilities implements Parcelable + { + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public float getDesiredMaxAverageLuminance(){ return 0; } + public float getDesiredMaxLuminance(){ return 0; } + public float getDesiredMinLuminance(){ return 0; } + public int describeContents(){ return 0; } + public int hashCode(){ return 0; } + public int[] getSupportedHdrTypes(){ return null; } + public static Parcelable.Creator CREATOR = null; + public static float INVALID_LUMINANCE = 0; + public static int HDR_TYPE_DOLBY_VISION = 0; + public static int HDR_TYPE_HDR10 = 0; + public static int HDR_TYPE_HDR10_PLUS = 0; + public static int HDR_TYPE_HLG = 0; + public void writeToParcel(Parcel p0, int p1){} + } + static public class Mode implements Parcelable + { + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public float getRefreshRate(){ return 0; } + public int describeContents(){ return 0; } + public int getModeId(){ return 0; } + public int getPhysicalHeight(){ return 0; } + public int getPhysicalWidth(){ return 0; } + public int hashCode(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public void writeToParcel(Parcel p0, int p1){} + } +} diff --git a/java/ql/test/stubs/android/android/view/DisplayCutout.java b/java/ql/test/stubs/android/android/view/DisplayCutout.java new file mode 100644 index 00000000000..90d3ecf0b44 --- /dev/null +++ b/java/ql/test/stubs/android/android/view/DisplayCutout.java @@ -0,0 +1,28 @@ +// Generated automatically from android.view.DisplayCutout for testing purposes + +package android.view; + +import android.graphics.Insets; +import android.graphics.Rect; +import java.util.List; + +public class DisplayCutout +{ + protected DisplayCutout() {} + public DisplayCutout(Insets p0, Rect p1, Rect p2, Rect p3, Rect p4){} + public DisplayCutout(Insets p0, Rect p1, Rect p2, Rect p3, Rect p4, Insets p5){} + public DisplayCutout(Rect p0, List p1){} + public Insets getWaterfallInsets(){ return null; } + public List getBoundingRects(){ return null; } + public Rect getBoundingRectBottom(){ return null; } + public Rect getBoundingRectLeft(){ return null; } + public Rect getBoundingRectRight(){ return null; } + public Rect getBoundingRectTop(){ return null; } + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public int getSafeInsetBottom(){ return 0; } + public int getSafeInsetLeft(){ return 0; } + public int getSafeInsetRight(){ return 0; } + public int getSafeInsetTop(){ return 0; } + public int hashCode(){ return 0; } +} diff --git a/java/ql/test/stubs/android/org/xmlpull/v1/XmlPullParser.java b/java/ql/test/stubs/android/org/xmlpull/v1/XmlPullParser.java new file mode 100644 index 00000000000..c693a5f6289 --- /dev/null +++ b/java/ql/test/stubs/android/org/xmlpull/v1/XmlPullParser.java @@ -0,0 +1,64 @@ +// Generated automatically from org.xmlpull.v1.XmlPullParser for testing purposes + +package org.xmlpull.v1; + +import java.io.InputStream; +import java.io.Reader; + +public interface XmlPullParser +{ + Object getProperty(String p0); + String getAttributeName(int p0); + String getAttributeNamespace(int p0); + String getAttributePrefix(int p0); + String getAttributeType(int p0); + String getAttributeValue(String p0, String p1); + String getAttributeValue(int p0); + String getInputEncoding(); + String getName(); + String getNamespace(); + String getNamespace(String p0); + String getNamespacePrefix(int p0); + String getNamespaceUri(int p0); + String getPositionDescription(); + String getPrefix(); + String getText(); + String nextText(); + boolean getFeature(String p0); + boolean isAttributeDefault(int p0); + boolean isEmptyElementTag(); + boolean isWhitespace(); + char[] getTextCharacters(int[] p0); + int getAttributeCount(); + int getColumnNumber(); + int getDepth(); + int getEventType(); + int getLineNumber(); + int getNamespaceCount(int p0); + int next(); + int nextTag(); + int nextToken(); + static String FEATURE_PROCESS_DOCDECL = null; + static String FEATURE_PROCESS_NAMESPACES = null; + static String FEATURE_REPORT_NAMESPACE_ATTRIBUTES = null; + static String FEATURE_VALIDATION = null; + static String NO_NAMESPACE = null; + static String[] TYPES = null; + static int CDSECT = 0; + static int COMMENT = 0; + static int DOCDECL = 0; + static int END_DOCUMENT = 0; + static int END_TAG = 0; + static int ENTITY_REF = 0; + static int IGNORABLE_WHITESPACE = 0; + static int PROCESSING_INSTRUCTION = 0; + static int START_DOCUMENT = 0; + static int START_TAG = 0; + static int TEXT = 0; + void defineEntityReplacementText(String p0, String p1); + void require(int p0, String p1, String p2); + void setFeature(String p0, boolean p1); + void setInput(InputStream p0, String p1); + void setInput(Reader p0); + void setProperty(String p0, Object p1); +} diff --git a/java/ql/test/stubs/android/org/xmlpull/v1/XmlSerializer.java b/java/ql/test/stubs/android/org/xmlpull/v1/XmlSerializer.java new file mode 100644 index 00000000000..f0a985adebe --- /dev/null +++ b/java/ql/test/stubs/android/org/xmlpull/v1/XmlSerializer.java @@ -0,0 +1,35 @@ +// Generated automatically from org.xmlpull.v1.XmlSerializer for testing purposes + +package org.xmlpull.v1; + +import java.io.OutputStream; +import java.io.Writer; + +public interface XmlSerializer +{ + Object getProperty(String p0); + String getName(); + String getNamespace(); + String getPrefix(String p0, boolean p1); + XmlSerializer attribute(String p0, String p1, String p2); + XmlSerializer endTag(String p0, String p1); + XmlSerializer startTag(String p0, String p1); + XmlSerializer text(String p0); + XmlSerializer text(char[] p0, int p1, int p2); + boolean getFeature(String p0); + int getDepth(); + void cdsect(String p0); + void comment(String p0); + void docdecl(String p0); + void endDocument(); + void entityRef(String p0); + void flush(); + void ignorableWhitespace(String p0); + void processingInstruction(String p0); + void setFeature(String p0, boolean p1); + void setOutput(OutputStream p0, String p1); + void setOutput(Writer p0); + void setPrefix(String p0, String p1); + void setProperty(String p0, Object p1); + void startDocument(String p0, Boolean p1); +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/BoundedCollection.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/BoundedCollection.java new file mode 100644 index 00000000000..4ef11898c3c --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/BoundedCollection.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.commons.collections4.BoundedCollection for testing purposes + +package org.apache.commons.collections4; + +import java.util.Collection; + +public interface BoundedCollection extends Collection +{ + boolean isFull(); + int maxSize(); +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/BoundedMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/BoundedMap.java new file mode 100644 index 00000000000..9ceec3f2a90 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/BoundedMap.java @@ -0,0 +1,11 @@ +// Generated automatically from org.apache.commons.collections4.BoundedMap for testing purposes + +package org.apache.commons.collections4; + +import org.apache.commons.collections4.IterableMap; + +public interface BoundedMap extends IterableMap +{ + boolean isFull(); + int maxSize(); +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/SortedBidiMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/SortedBidiMap.java new file mode 100644 index 00000000000..add3beaf1bd --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/SortedBidiMap.java @@ -0,0 +1,13 @@ +// Generated automatically from org.apache.commons.collections4.SortedBidiMap for testing purposes + +package org.apache.commons.collections4; + +import java.util.Comparator; +import java.util.SortedMap; +import org.apache.commons.collections4.OrderedBidiMap; + +public interface SortedBidiMap extends OrderedBidiMap, SortedMap +{ + Comparator valueComparator(); + SortedBidiMap inverseBidiMap(); +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/AbstractBagDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/AbstractBagDecorator.java new file mode 100644 index 00000000000..5701036d5a1 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/AbstractBagDecorator.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.commons.collections4.bag.AbstractBagDecorator for testing purposes + +package org.apache.commons.collections4.bag; + +import java.util.Set; +import org.apache.commons.collections4.Bag; +import org.apache.commons.collections4.collection.AbstractCollectionDecorator; + +abstract public class AbstractBagDecorator extends AbstractCollectionDecorator implements Bag +{ + protected AbstractBagDecorator(){} + protected AbstractBagDecorator(Bag p0){} + protected Bag decorated(){ return null; } + public Set uniqueSet(){ return null; } + public boolean add(E p0, int p1){ return false; } + public boolean equals(Object p0){ return false; } + public boolean remove(Object p0, int p1){ return false; } + public int getCount(Object p0){ return 0; } + public int hashCode(){ return 0; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/AbstractMapBag.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/AbstractMapBag.java index 78374820036..1f4fb4b0ec3 100644 --- a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/AbstractMapBag.java +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/AbstractMapBag.java @@ -39,7 +39,7 @@ abstract public class AbstractMapBag implements Bag public int hashCode(){ return 0; } public int size(){ return 0; } public void clear(){} - static class MutableInteger + protected static class MutableInteger { protected MutableInteger() {} MutableInteger(int p0){} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/AbstractSortedBagDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/AbstractSortedBagDecorator.java new file mode 100644 index 00000000000..2d6fa60c2ec --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/AbstractSortedBagDecorator.java @@ -0,0 +1,17 @@ +// Generated automatically from org.apache.commons.collections4.bag.AbstractSortedBagDecorator for testing purposes + +package org.apache.commons.collections4.bag; + +import java.util.Comparator; +import org.apache.commons.collections4.SortedBag; +import org.apache.commons.collections4.bag.AbstractBagDecorator; + +abstract public class AbstractSortedBagDecorator extends AbstractBagDecorator implements SortedBag +{ + protected AbstractSortedBagDecorator(){} + protected AbstractSortedBagDecorator(SortedBag p0){} + protected SortedBag decorated(){ return null; } + public Comparator comparator(){ return null; } + public E first(){ return null; } + public E last(){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/CollectionBag.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/CollectionBag.java new file mode 100644 index 00000000000..e0714f1b4e8 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/CollectionBag.java @@ -0,0 +1,21 @@ +// Generated automatically from org.apache.commons.collections4.bag.CollectionBag for testing purposes + +package org.apache.commons.collections4.bag; + +import java.util.Collection; +import org.apache.commons.collections4.Bag; +import org.apache.commons.collections4.bag.AbstractBagDecorator; + +public class CollectionBag extends AbstractBagDecorator +{ + protected CollectionBag() {} + public CollectionBag(Bag p0){} + public boolean add(E p0){ return false; } + public boolean add(E p0, int p1){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean containsAll(Collection p0){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public static Bag collectionBag(Bag p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/CollectionSortedBag.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/CollectionSortedBag.java new file mode 100644 index 00000000000..e0a5586af0d --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/CollectionSortedBag.java @@ -0,0 +1,21 @@ +// Generated automatically from org.apache.commons.collections4.bag.CollectionSortedBag for testing purposes + +package org.apache.commons.collections4.bag; + +import java.util.Collection; +import org.apache.commons.collections4.SortedBag; +import org.apache.commons.collections4.bag.AbstractSortedBagDecorator; + +public class CollectionSortedBag extends AbstractSortedBagDecorator +{ + protected CollectionSortedBag() {} + public CollectionSortedBag(SortedBag p0){} + public boolean add(E p0){ return false; } + public boolean add(E p0, int p1){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean containsAll(Collection p0){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public static SortedBag collectionSortedBag(SortedBag p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/HashBag.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/HashBag.java new file mode 100644 index 00000000000..7bfe8b9fcb0 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/HashBag.java @@ -0,0 +1,13 @@ +// Generated automatically from org.apache.commons.collections4.bag.HashBag for testing purposes + +package org.apache.commons.collections4.bag; + +import java.io.Serializable; +import java.util.Collection; +import org.apache.commons.collections4.bag.AbstractMapBag; + +public class HashBag extends AbstractMapBag implements Serializable +{ + public HashBag(){} + public HashBag(Collection p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/PredicatedBag.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/PredicatedBag.java new file mode 100644 index 00000000000..01e93cb07a5 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/PredicatedBag.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.commons.collections4.bag.PredicatedBag for testing purposes + +package org.apache.commons.collections4.bag; + +import java.util.Set; +import org.apache.commons.collections4.Bag; +import org.apache.commons.collections4.Predicate; +import org.apache.commons.collections4.collection.PredicatedCollection; + +public class PredicatedBag extends PredicatedCollection implements Bag +{ + protected PredicatedBag() {} + protected Bag decorated(){ return null; } + protected PredicatedBag(Bag p0, Predicate p1){} + public Set uniqueSet(){ return null; } + public boolean add(E p0, int p1){ return false; } + public boolean equals(Object p0){ return false; } + public boolean remove(Object p0, int p1){ return false; } + public int getCount(Object p0){ return 0; } + public int hashCode(){ return 0; } + public static PredicatedBag predicatedBag(Bag p0, Predicate p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/PredicatedSortedBag.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/PredicatedSortedBag.java new file mode 100644 index 00000000000..7fa0c1c31bf --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/PredicatedSortedBag.java @@ -0,0 +1,19 @@ +// Generated automatically from org.apache.commons.collections4.bag.PredicatedSortedBag for testing purposes + +package org.apache.commons.collections4.bag; + +import java.util.Comparator; +import org.apache.commons.collections4.Predicate; +import org.apache.commons.collections4.SortedBag; +import org.apache.commons.collections4.bag.PredicatedBag; + +public class PredicatedSortedBag extends PredicatedBag implements SortedBag +{ + protected PredicatedSortedBag() {} + protected PredicatedSortedBag(SortedBag p0, Predicate p1){} + protected SortedBag decorated(){ return null; } + public Comparator comparator(){ return null; } + public E first(){ return null; } + public E last(){ return null; } + public static PredicatedSortedBag predicatedSortedBag(SortedBag p0, Predicate p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/SynchronizedBag.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/SynchronizedBag.java new file mode 100644 index 00000000000..27befe5a2c2 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/SynchronizedBag.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.commons.collections4.bag.SynchronizedBag for testing purposes + +package org.apache.commons.collections4.bag; + +import java.util.Set; +import org.apache.commons.collections4.Bag; +import org.apache.commons.collections4.collection.SynchronizedCollection; + +public class SynchronizedBag extends SynchronizedCollection implements Bag +{ + protected SynchronizedBag() {} + protected Bag getBag(){ return null; } + protected SynchronizedBag(Bag p0){} + protected SynchronizedBag(Bag p0, Object p1){} + public Set uniqueSet(){ return null; } + public boolean add(E p0, int p1){ return false; } + public boolean equals(Object p0){ return false; } + public boolean remove(Object p0, int p1){ return false; } + public int getCount(Object p0){ return 0; } + public int hashCode(){ return 0; } + public static SynchronizedBag synchronizedBag(Bag p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/SynchronizedSortedBag.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/SynchronizedSortedBag.java new file mode 100644 index 00000000000..5eb69ad48fd --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/SynchronizedSortedBag.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.commons.collections4.bag.SynchronizedSortedBag for testing purposes + +package org.apache.commons.collections4.bag; + +import java.util.Comparator; +import org.apache.commons.collections4.Bag; +import org.apache.commons.collections4.SortedBag; +import org.apache.commons.collections4.bag.SynchronizedBag; + +public class SynchronizedSortedBag extends SynchronizedBag implements SortedBag +{ + protected SynchronizedSortedBag() {} + protected SortedBag getSortedBag(){ return null; } + protected SynchronizedSortedBag(Bag p0, Object p1){} + protected SynchronizedSortedBag(SortedBag p0){} + public Comparator comparator(){ return null; } + public E first(){ return null; } + public E last(){ return null; } + public static SynchronizedSortedBag synchronizedSortedBag(SortedBag p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/TransformedBag.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/TransformedBag.java new file mode 100644 index 00000000000..a42ef6f2e76 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/TransformedBag.java @@ -0,0 +1,23 @@ +// Generated automatically from org.apache.commons.collections4.bag.TransformedBag for testing purposes + +package org.apache.commons.collections4.bag; + +import java.util.Set; +import org.apache.commons.collections4.Bag; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.collection.TransformedCollection; + +public class TransformedBag extends TransformedCollection implements Bag +{ + protected TransformedBag() {} + protected Bag getBag(){ return null; } + protected TransformedBag(Bag p0, Transformer p1){} + public Set uniqueSet(){ return null; } + public boolean add(E p0, int p1){ return false; } + public boolean equals(Object p0){ return false; } + public boolean remove(Object p0, int p1){ return false; } + public int getCount(Object p0){ return 0; } + public int hashCode(){ return 0; } + public static Bag transformedBag(Bag p0, Transformer p1){ return null; } + public static Bag transformingBag(Bag p0, Transformer p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/TransformedSortedBag.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/TransformedSortedBag.java new file mode 100644 index 00000000000..1908765c13a --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/TransformedSortedBag.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.commons.collections4.bag.TransformedSortedBag for testing purposes + +package org.apache.commons.collections4.bag; + +import java.util.Comparator; +import org.apache.commons.collections4.SortedBag; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.bag.TransformedBag; + +public class TransformedSortedBag extends TransformedBag implements SortedBag +{ + protected TransformedSortedBag() {} + protected SortedBag getSortedBag(){ return null; } + protected TransformedSortedBag(SortedBag p0, Transformer p1){} + public Comparator comparator(){ return null; } + public E first(){ return null; } + public E last(){ return null; } + public static TransformedSortedBag transformedSortedBag(SortedBag p0, Transformer p1){ return null; } + public static TransformedSortedBag transformingSortedBag(SortedBag p0, Transformer p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/UnmodifiableBag.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/UnmodifiableBag.java new file mode 100644 index 00000000000..9b3fcfbc3d9 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/UnmodifiableBag.java @@ -0,0 +1,28 @@ +// Generated automatically from org.apache.commons.collections4.bag.UnmodifiableBag for testing purposes + +package org.apache.commons.collections4.bag; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; +import java.util.function.Predicate; +import org.apache.commons.collections4.Bag; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.bag.AbstractBagDecorator; + +public class UnmodifiableBag extends AbstractBagDecorator implements Unmodifiable +{ + protected UnmodifiableBag() {} + public Iterator iterator(){ return null; } + public Set uniqueSet(){ return null; } + public boolean add(E p0){ return false; } + public boolean add(E p0, int p1){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean remove(Object p0){ return false; } + public boolean remove(Object p0, int p1){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public static Bag unmodifiableBag(Bag p0){ return null; } + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/UnmodifiableSortedBag.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/UnmodifiableSortedBag.java new file mode 100644 index 00000000000..8e0bd59afee --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bag/UnmodifiableSortedBag.java @@ -0,0 +1,28 @@ +// Generated automatically from org.apache.commons.collections4.bag.UnmodifiableSortedBag for testing purposes + +package org.apache.commons.collections4.bag; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; +import java.util.function.Predicate; +import org.apache.commons.collections4.SortedBag; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.bag.AbstractSortedBagDecorator; + +public class UnmodifiableSortedBag extends AbstractSortedBagDecorator implements Unmodifiable +{ + protected UnmodifiableSortedBag() {} + public Iterator iterator(){ return null; } + public Set uniqueSet(){ return null; } + public boolean add(E p0){ return false; } + public boolean add(E p0, int p1){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean remove(Object p0){ return false; } + public boolean remove(Object p0, int p1){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public static SortedBag unmodifiableSortedBag(SortedBag p0){ return null; } + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/AbstractBidiMapDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/AbstractBidiMapDecorator.java new file mode 100644 index 00000000000..56437edf8a7 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/AbstractBidiMapDecorator.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.commons.collections4.bidimap.AbstractBidiMapDecorator for testing purposes + +package org.apache.commons.collections4.bidimap; + +import java.util.Set; +import org.apache.commons.collections4.BidiMap; +import org.apache.commons.collections4.MapIterator; +import org.apache.commons.collections4.map.AbstractMapDecorator; + +abstract public class AbstractBidiMapDecorator extends AbstractMapDecorator implements BidiMap +{ + protected AbstractBidiMapDecorator() {} + protected AbstractBidiMapDecorator(BidiMap p0){} + protected BidiMap decorated(){ return null; } + public BidiMap inverseBidiMap(){ return null; } + public K getKey(Object p0){ return null; } + public K removeValue(Object p0){ return null; } + public MapIterator mapIterator(){ return null; } + public Set values(){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/AbstractDualBidiMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/AbstractDualBidiMap.java new file mode 100644 index 00000000000..e53b5027448 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/AbstractDualBidiMap.java @@ -0,0 +1,39 @@ +// Generated automatically from org.apache.commons.collections4.bidimap.AbstractDualBidiMap for testing purposes + +package org.apache.commons.collections4.bidimap; + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import org.apache.commons.collections4.BidiMap; +import org.apache.commons.collections4.MapIterator; + +abstract public class AbstractDualBidiMap implements BidiMap +{ + protected AbstractDualBidiMap(){} + protected AbstractDualBidiMap(Map p0, Map p1){} + protected AbstractDualBidiMap(Map p0, Map p1, BidiMap p2){} + protected Iterator createKeySetIterator(Iterator p0){ return null; } + protected Iterator> createEntrySetIterator(Iterator> p0){ return null; } + protected Iterator createValuesIterator(Iterator p0){ return null; } + protected abstract BidiMap createBidiMap(Map p0, Map p1, BidiMap p2); + public BidiMap inverseBidiMap(){ return null; } + public K getKey(Object p0){ return null; } + public K removeValue(Object p0){ return null; } + public MapIterator mapIterator(){ return null; } + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public Set values(){ return null; } + public String toString(){ return null; } + public V get(Object p0){ return null; } + public V put(K p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public boolean containsKey(Object p0){ return false; } + public boolean containsValue(Object p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public int hashCode(){ return 0; } + public int size(){ return 0; } + public void clear(){} + public void putAll(Map p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/AbstractOrderedBidiMapDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/AbstractOrderedBidiMapDecorator.java new file mode 100644 index 00000000000..274cc7f76cf --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/AbstractOrderedBidiMapDecorator.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.commons.collections4.bidimap.AbstractOrderedBidiMapDecorator for testing purposes + +package org.apache.commons.collections4.bidimap; + +import org.apache.commons.collections4.OrderedBidiMap; +import org.apache.commons.collections4.OrderedMapIterator; +import org.apache.commons.collections4.bidimap.AbstractBidiMapDecorator; + +abstract public class AbstractOrderedBidiMapDecorator extends AbstractBidiMapDecorator implements OrderedBidiMap +{ + protected AbstractOrderedBidiMapDecorator() {} + protected AbstractOrderedBidiMapDecorator(OrderedBidiMap p0){} + protected OrderedBidiMap decorated(){ return null; } + public K firstKey(){ return null; } + public K lastKey(){ return null; } + public K nextKey(K p0){ return null; } + public K previousKey(K p0){ return null; } + public OrderedBidiMap inverseBidiMap(){ return null; } + public OrderedMapIterator mapIterator(){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/AbstractSortedBidiMapDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/AbstractSortedBidiMapDecorator.java new file mode 100644 index 00000000000..9a351f99b67 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/AbstractSortedBidiMapDecorator.java @@ -0,0 +1,21 @@ +// Generated automatically from org.apache.commons.collections4.bidimap.AbstractSortedBidiMapDecorator for testing purposes + +package org.apache.commons.collections4.bidimap; + +import java.util.Comparator; +import java.util.SortedMap; +import org.apache.commons.collections4.SortedBidiMap; +import org.apache.commons.collections4.bidimap.AbstractOrderedBidiMapDecorator; + +abstract public class AbstractSortedBidiMapDecorator extends AbstractOrderedBidiMapDecorator implements SortedBidiMap +{ + protected AbstractSortedBidiMapDecorator() {} + protected SortedBidiMap decorated(){ return null; } + public AbstractSortedBidiMapDecorator(SortedBidiMap p0){} + public Comparator comparator(){ return null; } + public Comparator valueComparator(){ return null; } + public SortedBidiMap inverseBidiMap(){ return null; } + public SortedMap headMap(K p0){ return null; } + public SortedMap subMap(K p0, K p1){ return null; } + public SortedMap tailMap(K p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/DualHashBidiMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/DualHashBidiMap.java new file mode 100644 index 00000000000..f5f7a60e530 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/DualHashBidiMap.java @@ -0,0 +1,16 @@ +// Generated automatically from org.apache.commons.collections4.bidimap.DualHashBidiMap for testing purposes + +package org.apache.commons.collections4.bidimap; + +import java.io.Serializable; +import java.util.Map; +import org.apache.commons.collections4.BidiMap; +import org.apache.commons.collections4.bidimap.AbstractDualBidiMap; + +public class DualHashBidiMap extends AbstractDualBidiMap implements Serializable +{ + protected BidiMap createBidiMap(Map p0, Map p1, BidiMap p2){ return null; } + protected DualHashBidiMap(Map p0, Map p1, BidiMap p2){} + public DualHashBidiMap(){} + public DualHashBidiMap(Map p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/DualLinkedHashBidiMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/DualLinkedHashBidiMap.java new file mode 100644 index 00000000000..6fbeb4ad431 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/DualLinkedHashBidiMap.java @@ -0,0 +1,16 @@ +// Generated automatically from org.apache.commons.collections4.bidimap.DualLinkedHashBidiMap for testing purposes + +package org.apache.commons.collections4.bidimap; + +import java.io.Serializable; +import java.util.Map; +import org.apache.commons.collections4.BidiMap; +import org.apache.commons.collections4.bidimap.AbstractDualBidiMap; + +public class DualLinkedHashBidiMap extends AbstractDualBidiMap implements Serializable +{ + protected BidiMap createBidiMap(Map p0, Map p1, BidiMap p2){ return null; } + protected DualLinkedHashBidiMap(Map p0, Map p1, BidiMap p2){} + public DualLinkedHashBidiMap(){} + public DualLinkedHashBidiMap(Map p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/DualTreeBidiMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/DualTreeBidiMap.java new file mode 100644 index 00000000000..70243fd10c3 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/DualTreeBidiMap.java @@ -0,0 +1,35 @@ +// Generated automatically from org.apache.commons.collections4.bidimap.DualTreeBidiMap for testing purposes + +package org.apache.commons.collections4.bidimap; + +import java.io.Serializable; +import java.util.Comparator; +import java.util.Map; +import java.util.SortedMap; +import org.apache.commons.collections4.BidiMap; +import org.apache.commons.collections4.OrderedBidiMap; +import org.apache.commons.collections4.OrderedMapIterator; +import org.apache.commons.collections4.SortedBidiMap; +import org.apache.commons.collections4.bidimap.AbstractDualBidiMap; + +public class DualTreeBidiMap extends AbstractDualBidiMap implements Serializable, SortedBidiMap +{ + protected DualTreeBidiMap(Map p0, Map p1, BidiMap p2){} + protected DualTreeBidiMap createBidiMap(Map p0, Map p1, BidiMap p2){ return null; } + public Comparator comparator(){ return null; } + public Comparator valueComparator(){ return null; } + public DualTreeBidiMap(){} + public DualTreeBidiMap(Comparator p0, Comparator p1){} + public DualTreeBidiMap(Map p0){} + public K firstKey(){ return null; } + public K lastKey(){ return null; } + public K nextKey(K p0){ return null; } + public K previousKey(K p0){ return null; } + public OrderedBidiMap inverseOrderedBidiMap(){ return null; } + public OrderedMapIterator mapIterator(){ return null; } + public SortedBidiMap inverseBidiMap(){ return null; } + public SortedBidiMap inverseSortedBidiMap(){ return null; } + public SortedMap headMap(K p0){ return null; } + public SortedMap subMap(K p0, K p1){ return null; } + public SortedMap tailMap(K p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/UnmodifiableBidiMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/UnmodifiableBidiMap.java new file mode 100644 index 00000000000..b971b59a01e --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/UnmodifiableBidiMap.java @@ -0,0 +1,26 @@ +// Generated automatically from org.apache.commons.collections4.bidimap.UnmodifiableBidiMap for testing purposes + +package org.apache.commons.collections4.bidimap; + +import java.util.Map; +import java.util.Set; +import org.apache.commons.collections4.BidiMap; +import org.apache.commons.collections4.MapIterator; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.bidimap.AbstractBidiMapDecorator; + +public class UnmodifiableBidiMap extends AbstractBidiMapDecorator implements Unmodifiable +{ + protected UnmodifiableBidiMap() {} + public BidiMap inverseBidiMap(){ return null; } + public K removeValue(Object p0){ return null; } + public MapIterator mapIterator(){ return null; } + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public Set values(){ return null; } + public V put(K p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public static BidiMap unmodifiableBidiMap(BidiMap p0){ return null; } + public void clear(){} + public void putAll(Map p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/UnmodifiableOrderedBidiMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/UnmodifiableOrderedBidiMap.java new file mode 100644 index 00000000000..acb6be51f0f --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/UnmodifiableOrderedBidiMap.java @@ -0,0 +1,27 @@ +// Generated automatically from org.apache.commons.collections4.bidimap.UnmodifiableOrderedBidiMap for testing purposes + +package org.apache.commons.collections4.bidimap; + +import java.util.Map; +import java.util.Set; +import org.apache.commons.collections4.OrderedBidiMap; +import org.apache.commons.collections4.OrderedMapIterator; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.bidimap.AbstractOrderedBidiMapDecorator; + +public class UnmodifiableOrderedBidiMap extends AbstractOrderedBidiMapDecorator implements Unmodifiable +{ + protected UnmodifiableOrderedBidiMap() {} + public K removeValue(Object p0){ return null; } + public OrderedBidiMap inverseBidiMap(){ return null; } + public OrderedBidiMap inverseOrderedBidiMap(){ return null; } + public OrderedMapIterator mapIterator(){ return null; } + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public Set values(){ return null; } + public V put(K p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public static OrderedBidiMap unmodifiableOrderedBidiMap(OrderedBidiMap p0){ return null; } + public void clear(){} + public void putAll(Map p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/UnmodifiableSortedBidiMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/UnmodifiableSortedBidiMap.java new file mode 100644 index 00000000000..e75c748db02 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/bidimap/UnmodifiableSortedBidiMap.java @@ -0,0 +1,30 @@ +// Generated automatically from org.apache.commons.collections4.bidimap.UnmodifiableSortedBidiMap for testing purposes + +package org.apache.commons.collections4.bidimap; + +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import org.apache.commons.collections4.OrderedMapIterator; +import org.apache.commons.collections4.SortedBidiMap; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.bidimap.AbstractSortedBidiMapDecorator; + +public class UnmodifiableSortedBidiMap extends AbstractSortedBidiMapDecorator implements Unmodifiable +{ + protected UnmodifiableSortedBidiMap() {} + public K removeValue(Object p0){ return null; } + public OrderedMapIterator mapIterator(){ return null; } + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public Set values(){ return null; } + public SortedBidiMap inverseBidiMap(){ return null; } + public SortedMap headMap(K p0){ return null; } + public SortedMap subMap(K p0, K p1){ return null; } + public SortedMap tailMap(K p0){ return null; } + public V put(K p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public static SortedBidiMap unmodifiableSortedBidiMap(SortedBidiMap p0){ return null; } + public void clear(){} + public void putAll(Map p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/AbstractCollectionDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/AbstractCollectionDecorator.java new file mode 100644 index 00000000000..3e68fac883f --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/AbstractCollectionDecorator.java @@ -0,0 +1,31 @@ +// Generated automatically from org.apache.commons.collections4.collection.AbstractCollectionDecorator for testing purposes + +package org.apache.commons.collections4.collection; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Iterator; +import java.util.function.Predicate; + +abstract public class AbstractCollectionDecorator implements Collection, Serializable +{ + protected AbstractCollectionDecorator(){} + protected AbstractCollectionDecorator(Collection p0){} + protected Collection decorated(){ return null; } + protected void setCollection(Collection p0){} + public T[] toArray(T[] p0){ return null; } + public Iterator iterator(){ return null; } + public Object[] toArray(){ return null; } + public String toString(){ return null; } + public boolean add(E p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean contains(Object p0){ return false; } + public boolean containsAll(Collection p0){ return false; } + public boolean isEmpty(){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public int size(){ return 0; } + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/CompositeCollection.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/CompositeCollection.java new file mode 100644 index 00000000000..f77222d20d5 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/CompositeCollection.java @@ -0,0 +1,45 @@ +// Generated automatically from org.apache.commons.collections4.collection.CompositeCollection for testing purposes + +package org.apache.commons.collections4.collection; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.function.Predicate; + +public class CompositeCollection implements Collection, Serializable +{ + protected CompositeCollection.CollectionMutator getMutator(){ return null; } + public T[] toArray(T[] p0){ return null; } + public Collection toCollection(){ return null; } + public CompositeCollection(){} + public CompositeCollection(Collection p0){} + public CompositeCollection(Collection p0, Collection p1){} + public CompositeCollection(Collection... p0){} + public Iterator iterator(){ return null; } + public List> getCollections(){ return null; } + public Object[] toArray(){ return null; } + public boolean add(E p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean contains(Object p0){ return false; } + public boolean containsAll(Collection p0){ return false; } + public boolean isEmpty(){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public int size(){ return 0; } + public void addComposited(Collection p0){} + public void addComposited(Collection p0, Collection p1){} + public void addComposited(Collection... p0){} + public void clear(){} + public void removeComposited(Collection p0){} + public void setMutator(CompositeCollection.CollectionMutator p0){} + static public interface CollectionMutator extends Serializable + { + boolean add(CompositeCollection p0, List> p1, E p2); + boolean addAll(CompositeCollection p0, List> p1, Collection p2); + boolean remove(CompositeCollection p0, List> p1, Object p2); + } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/IndexedCollection.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/IndexedCollection.java new file mode 100644 index 00000000000..a27e2c2872b --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/IndexedCollection.java @@ -0,0 +1,29 @@ +// Generated automatically from org.apache.commons.collections4.collection.IndexedCollection for testing purposes + +package org.apache.commons.collections4.collection; + +import java.util.Collection; +import java.util.function.Predicate; +import org.apache.commons.collections4.MultiMap; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.collection.AbstractCollectionDecorator; + +public class IndexedCollection extends AbstractCollectionDecorator +{ + protected IndexedCollection() {} + public C get(K p0){ return null; } + public Collection values(K p0){ return null; } + public IndexedCollection(Collection p0, Transformer p1, MultiMap p2, boolean p3){} + public boolean add(C p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean contains(Object p0){ return false; } + public boolean containsAll(Collection p0){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public static IndexedCollection nonUniqueIndexedCollection(Collection p0, Transformer p1){ return null; } + public static IndexedCollection uniqueIndexedCollection(Collection p0, Transformer p1){ return null; } + public void clear(){} + public void reindex(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/PredicatedCollection.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/PredicatedCollection.java new file mode 100644 index 00000000000..1a27a4b7d05 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/PredicatedCollection.java @@ -0,0 +1,43 @@ +// Generated automatically from org.apache.commons.collections4.collection.PredicatedCollection for testing purposes + +package org.apache.commons.collections4.collection; + +import java.util.Collection; +import java.util.List; +import java.util.Queue; +import java.util.Set; +import org.apache.commons.collections4.Bag; +import org.apache.commons.collections4.MultiSet; +import org.apache.commons.collections4.Predicate; +import org.apache.commons.collections4.collection.AbstractCollectionDecorator; + +public class PredicatedCollection extends AbstractCollectionDecorator +{ + protected PredicatedCollection() {} + protected PredicatedCollection(Collection p0, Predicate p1){} + protected final Predicate predicate = null; + protected void validate(E p0){} + public boolean add(E p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public static PredicatedCollection.Builder builder(Predicate p0){ return null; } + public static PredicatedCollection.Builder notNullBuilder(){ return null; } + public static PredicatedCollection predicatedCollection(Collection p0, Predicate p1){ return null; } + static public class Builder + { + protected Builder() {} + public Bag createPredicatedBag(){ return null; } + public Bag createPredicatedBag(Bag p0){ return null; } + public Builder(Predicate p0){} + public Collection rejectedElements(){ return null; } + public List createPredicatedList(){ return null; } + public List createPredicatedList(List p0){ return null; } + public MultiSet createPredicatedMultiSet(){ return null; } + public MultiSet createPredicatedMultiSet(MultiSet p0){ return null; } + public PredicatedCollection.Builder add(E p0){ return null; } + public PredicatedCollection.Builder addAll(Collection p0){ return null; } + public Queue createPredicatedQueue(){ return null; } + public Queue createPredicatedQueue(Queue p0){ return null; } + public Set createPredicatedSet(){ return null; } + public Set createPredicatedSet(Set p0){ return null; } + } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/SynchronizedCollection.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/SynchronizedCollection.java new file mode 100644 index 00000000000..a5cee14caad --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/SynchronizedCollection.java @@ -0,0 +1,35 @@ +// Generated automatically from org.apache.commons.collections4.collection.SynchronizedCollection for testing purposes + +package org.apache.commons.collections4.collection; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Iterator; +import java.util.function.Predicate; + +public class SynchronizedCollection implements Collection, Serializable +{ + protected SynchronizedCollection() {} + protected Collection decorated(){ return null; } + protected SynchronizedCollection(Collection p0){} + protected SynchronizedCollection(Collection p0, Object p1){} + protected final Object lock = null; + public T[] toArray(T[] p0){ return null; } + public Iterator iterator(){ return null; } + public Object[] toArray(){ return null; } + public String toString(){ return null; } + public boolean add(E p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean contains(Object p0){ return false; } + public boolean containsAll(Collection p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public int hashCode(){ return 0; } + public int size(){ return 0; } + public static SynchronizedCollection synchronizedCollection(Collection p0){ return null; } + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/TransformedCollection.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/TransformedCollection.java new file mode 100644 index 00000000000..92abb09f605 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/TransformedCollection.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.commons.collections4.collection.TransformedCollection for testing purposes + +package org.apache.commons.collections4.collection; + +import java.util.Collection; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.collection.AbstractCollectionDecorator; + +public class TransformedCollection extends AbstractCollectionDecorator +{ + protected TransformedCollection() {} + protected Collection transform(Collection p0){ return null; } + protected E transform(E p0){ return null; } + protected TransformedCollection(Collection p0, Transformer p1){} + protected final Transformer transformer = null; + public boolean add(E p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public static TransformedCollection transformedCollection(Collection p0, Transformer p1){ return null; } + public static TransformedCollection transformingCollection(Collection p0, Transformer p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/UnmodifiableBoundedCollection.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/UnmodifiableBoundedCollection.java new file mode 100644 index 00000000000..d5108904143 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/UnmodifiableBoundedCollection.java @@ -0,0 +1,28 @@ +// Generated automatically from org.apache.commons.collections4.collection.UnmodifiableBoundedCollection for testing purposes + +package org.apache.commons.collections4.collection; + +import java.util.Collection; +import java.util.Iterator; +import java.util.function.Predicate; +import org.apache.commons.collections4.BoundedCollection; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.collection.AbstractCollectionDecorator; + +public class UnmodifiableBoundedCollection extends AbstractCollectionDecorator implements BoundedCollection, Unmodifiable +{ + protected UnmodifiableBoundedCollection() {} + protected BoundedCollection decorated(){ return null; } + public Iterator iterator(){ return null; } + public boolean add(E p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean isFull(){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public int maxSize(){ return 0; } + public static BoundedCollection unmodifiableBoundedCollection(BoundedCollection p0){ return null; } + public static BoundedCollection unmodifiableBoundedCollection(Collection p0){ return null; } + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/UnmodifiableCollection.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/UnmodifiableCollection.java new file mode 100644 index 00000000000..fe8a36abd81 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/collection/UnmodifiableCollection.java @@ -0,0 +1,23 @@ +// Generated automatically from org.apache.commons.collections4.collection.UnmodifiableCollection for testing purposes + +package org.apache.commons.collections4.collection; + +import java.util.Collection; +import java.util.Iterator; +import java.util.function.Predicate; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.collection.AbstractCollectionDecorator; + +public class UnmodifiableCollection extends AbstractCollectionDecorator implements Unmodifiable +{ + protected UnmodifiableCollection() {} + public Iterator iterator(){ return null; } + public boolean add(E p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public static Collection unmodifiableCollection(Collection p0){ return null; } + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/AbstractListIteratorDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/AbstractListIteratorDecorator.java new file mode 100644 index 00000000000..806828bdc20 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/AbstractListIteratorDecorator.java @@ -0,0 +1,21 @@ +// Generated automatically from org.apache.commons.collections4.iterators.AbstractListIteratorDecorator for testing purposes + +package org.apache.commons.collections4.iterators; + +import java.util.ListIterator; + +public class AbstractListIteratorDecorator implements ListIterator +{ + protected AbstractListIteratorDecorator() {} + protected ListIterator getListIterator(){ return null; } + public AbstractListIteratorDecorator(ListIterator p0){} + public E next(){ return null; } + public E previous(){ return null; } + public boolean hasNext(){ return false; } + public boolean hasPrevious(){ return false; } + public int nextIndex(){ return 0; } + public int previousIndex(){ return 0; } + public void add(E p0){} + public void remove(){} + public void set(E p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/AbstractMapIteratorDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/AbstractMapIteratorDecorator.java new file mode 100644 index 00000000000..f4369771782 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/AbstractMapIteratorDecorator.java @@ -0,0 +1,18 @@ +// Generated automatically from org.apache.commons.collections4.iterators.AbstractMapIteratorDecorator for testing purposes + +package org.apache.commons.collections4.iterators; + +import org.apache.commons.collections4.MapIterator; + +public class AbstractMapIteratorDecorator implements MapIterator +{ + protected AbstractMapIteratorDecorator() {} + protected MapIterator getMapIterator(){ return null; } + public AbstractMapIteratorDecorator(MapIterator p0){} + public K getKey(){ return null; } + public K next(){ return null; } + public V getValue(){ return null; } + public V setValue(V p0){ return null; } + public boolean hasNext(){ return false; } + public void remove(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/AbstractOrderedMapIteratorDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/AbstractOrderedMapIteratorDecorator.java new file mode 100644 index 00000000000..cd80159d26a --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/AbstractOrderedMapIteratorDecorator.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.commons.collections4.iterators.AbstractOrderedMapIteratorDecorator for testing purposes + +package org.apache.commons.collections4.iterators; + +import org.apache.commons.collections4.OrderedMapIterator; + +public class AbstractOrderedMapIteratorDecorator implements OrderedMapIterator +{ + protected AbstractOrderedMapIteratorDecorator() {} + protected OrderedMapIterator getOrderedMapIterator(){ return null; } + public AbstractOrderedMapIteratorDecorator(OrderedMapIterator p0){} + public K getKey(){ return null; } + public K next(){ return null; } + public K previous(){ return null; } + public V getValue(){ return null; } + public V setValue(V p0){ return null; } + public boolean hasNext(){ return false; } + public boolean hasPrevious(){ return false; } + public void remove(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ArrayIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ArrayIterator.java new file mode 100644 index 00000000000..c2c9cd2ff44 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ArrayIterator.java @@ -0,0 +1,21 @@ +// Generated automatically from org.apache.commons.collections4.iterators.ArrayIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import org.apache.commons.collections4.ResettableIterator; + +public class ArrayIterator implements ResettableIterator +{ + protected ArrayIterator() {} + protected void checkBound(int p0, int p1, String p2){} + public ArrayIterator(Object p0){} + public ArrayIterator(Object p0, int p1){} + public ArrayIterator(Object p0, int p1, int p2){} + public E next(){ return null; } + public Object getArray(){ return null; } + public boolean hasNext(){ return false; } + public int getEndIndex(){ return 0; } + public int getStartIndex(){ return 0; } + public void remove(){} + public void reset(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ArrayListIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ArrayListIterator.java new file mode 100644 index 00000000000..22adf916a7d --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ArrayListIterator.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.commons.collections4.iterators.ArrayListIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import org.apache.commons.collections4.ResettableListIterator; +import org.apache.commons.collections4.iterators.ArrayIterator; + +public class ArrayListIterator extends ArrayIterator implements ResettableListIterator +{ + protected ArrayListIterator() {} + public ArrayListIterator(Object p0){} + public ArrayListIterator(Object p0, int p1){} + public ArrayListIterator(Object p0, int p1, int p2){} + public E next(){ return null; } + public E previous(){ return null; } + public boolean hasPrevious(){ return false; } + public int nextIndex(){ return 0; } + public int previousIndex(){ return 0; } + public void add(Object p0){} + public void reset(){} + public void set(Object p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/CollatingIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/CollatingIterator.java new file mode 100644 index 00000000000..524ac37e3ef --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/CollatingIterator.java @@ -0,0 +1,27 @@ +// Generated automatically from org.apache.commons.collections4.iterators.CollatingIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +public class CollatingIterator implements Iterator +{ + public CollatingIterator(){} + public CollatingIterator(Comparator p0){} + public CollatingIterator(Comparator p0, Collection> p1){} + public CollatingIterator(Comparator p0, Iterator p1, Iterator p2){} + public CollatingIterator(Comparator p0, Iterator[] p1){} + public CollatingIterator(Comparator p0, int p1){} + public Comparator getComparator(){ return null; } + public E next(){ return null; } + public List> getIterators(){ return null; } + public boolean hasNext(){ return false; } + public int getIteratorIndex(){ return 0; } + public void addIterator(Iterator p0){} + public void remove(){} + public void setComparator(Comparator p0){} + public void setIterator(int p0, Iterator p1){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/EnumerationIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/EnumerationIterator.java new file mode 100644 index 00000000000..fa1934b73cc --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/EnumerationIterator.java @@ -0,0 +1,19 @@ +// Generated automatically from org.apache.commons.collections4.iterators.EnumerationIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import java.util.Collection; +import java.util.Enumeration; +import java.util.Iterator; + +public class EnumerationIterator implements Iterator +{ + public E next(){ return null; } + public Enumeration getEnumeration(){ return null; } + public EnumerationIterator(){} + public EnumerationIterator(Enumeration p0){} + public EnumerationIterator(Enumeration p0, Collection p1){} + public boolean hasNext(){ return false; } + public void remove(){} + public void setEnumeration(Enumeration p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/FilterIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/FilterIterator.java new file mode 100644 index 00000000000..f0070748b30 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/FilterIterator.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.commons.collections4.iterators.FilterIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import java.util.Iterator; +import org.apache.commons.collections4.Predicate; + +public class FilterIterator implements Iterator +{ + public E next(){ return null; } + public FilterIterator(){} + public FilterIterator(Iterator p0){} + public FilterIterator(Iterator p0, Predicate p1){} + public Iterator getIterator(){ return null; } + public Predicate getPredicate(){ return null; } + public boolean hasNext(){ return false; } + public void remove(){} + public void setIterator(Iterator p0){} + public void setPredicate(Predicate p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/FilterListIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/FilterListIterator.java new file mode 100644 index 00000000000..dbaea3c5a1a --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/FilterListIterator.java @@ -0,0 +1,27 @@ +// Generated automatically from org.apache.commons.collections4.iterators.FilterListIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import java.util.ListIterator; +import org.apache.commons.collections4.Predicate; + +public class FilterListIterator implements ListIterator +{ + public E next(){ return null; } + public E previous(){ return null; } + public FilterListIterator(){} + public FilterListIterator(ListIterator p0){} + public FilterListIterator(ListIterator p0, Predicate p1){} + public FilterListIterator(Predicate p0){} + public ListIterator getListIterator(){ return null; } + public Predicate getPredicate(){ return null; } + public boolean hasNext(){ return false; } + public boolean hasPrevious(){ return false; } + public int nextIndex(){ return 0; } + public int previousIndex(){ return 0; } + public void add(E p0){} + public void remove(){} + public void set(E p0){} + public void setListIterator(ListIterator p0){} + public void setPredicate(Predicate p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/IteratorChain.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/IteratorChain.java new file mode 100644 index 00000000000..8278c401464 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/IteratorChain.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.commons.collections4.iterators.IteratorChain for testing purposes + +package org.apache.commons.collections4.iterators; + +import java.util.Collection; +import java.util.Iterator; + +public class IteratorChain implements Iterator +{ + protected void updateCurrentIterator(){} + public E next(){ return null; } + public IteratorChain(){} + public IteratorChain(Collection> p0){} + public IteratorChain(Iterator p0){} + public IteratorChain(Iterator p0, Iterator p1){} + public IteratorChain(Iterator... p0){} + public boolean hasNext(){ return false; } + public boolean isLocked(){ return false; } + public int size(){ return 0; } + public void addIterator(Iterator p0){} + public void remove(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/IteratorIterable.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/IteratorIterable.java new file mode 100644 index 00000000000..ccecd51ccbb --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/IteratorIterable.java @@ -0,0 +1,13 @@ +// Generated automatically from org.apache.commons.collections4.iterators.IteratorIterable for testing purposes + +package org.apache.commons.collections4.iterators; + +import java.util.Iterator; + +public class IteratorIterable implements Iterable +{ + protected IteratorIterable() {} + public Iterator iterator(){ return null; } + public IteratorIterable(Iterator p0){} + public IteratorIterable(Iterator p0, boolean p1){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ListIteratorWrapper.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ListIteratorWrapper.java new file mode 100644 index 00000000000..56d742b41d9 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ListIteratorWrapper.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.commons.collections4.iterators.ListIteratorWrapper for testing purposes + +package org.apache.commons.collections4.iterators; + +import java.util.Iterator; +import org.apache.commons.collections4.ResettableListIterator; + +public class ListIteratorWrapper implements ResettableListIterator +{ + protected ListIteratorWrapper() {} + public E next(){ return null; } + public E previous(){ return null; } + public ListIteratorWrapper(Iterator p0){} + public boolean hasNext(){ return false; } + public boolean hasPrevious(){ return false; } + public int nextIndex(){ return 0; } + public int previousIndex(){ return 0; } + public void add(E p0){} + public void remove(){} + public void reset(){} + public void set(E p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/LoopingIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/LoopingIterator.java new file mode 100644 index 00000000000..3723fbf0af6 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/LoopingIterator.java @@ -0,0 +1,17 @@ +// Generated automatically from org.apache.commons.collections4.iterators.LoopingIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import java.util.Collection; +import org.apache.commons.collections4.ResettableIterator; + +public class LoopingIterator implements ResettableIterator +{ + protected LoopingIterator() {} + public E next(){ return null; } + public LoopingIterator(Collection p0){} + public boolean hasNext(){ return false; } + public int size(){ return 0; } + public void remove(){} + public void reset(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/LoopingListIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/LoopingListIterator.java new file mode 100644 index 00000000000..e44f67ec1d4 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/LoopingListIterator.java @@ -0,0 +1,23 @@ +// Generated automatically from org.apache.commons.collections4.iterators.LoopingListIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import java.util.List; +import org.apache.commons.collections4.ResettableListIterator; + +public class LoopingListIterator implements ResettableListIterator +{ + protected LoopingListIterator() {} + public E next(){ return null; } + public E previous(){ return null; } + public LoopingListIterator(List p0){} + public boolean hasNext(){ return false; } + public boolean hasPrevious(){ return false; } + public int nextIndex(){ return 0; } + public int previousIndex(){ return 0; } + public int size(){ return 0; } + public void add(E p0){} + public void remove(){} + public void reset(){} + public void set(E p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ObjectArrayIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ObjectArrayIterator.java new file mode 100644 index 00000000000..582a8dce796 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ObjectArrayIterator.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.commons.collections4.iterators.ObjectArrayIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import org.apache.commons.collections4.ResettableIterator; + +public class ObjectArrayIterator implements ResettableIterator +{ + protected ObjectArrayIterator() {} + public E next(){ return null; } + public E[] getArray(){ return null; } + public ObjectArrayIterator(E... p0){} + public ObjectArrayIterator(E[] p0, int p1){} + public ObjectArrayIterator(E[] p0, int p1, int p2){} + public boolean hasNext(){ return false; } + public int getEndIndex(){ return 0; } + public int getStartIndex(){ return 0; } + public void remove(){} + public void reset(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ObjectArrayListIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ObjectArrayListIterator.java new file mode 100644 index 00000000000..0dd15a8dd1a --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ObjectArrayListIterator.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.commons.collections4.iterators.ObjectArrayListIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import org.apache.commons.collections4.ResettableListIterator; +import org.apache.commons.collections4.iterators.ObjectArrayIterator; + +public class ObjectArrayListIterator extends ObjectArrayIterator implements ResettableListIterator +{ + protected ObjectArrayListIterator() {} + public E next(){ return null; } + public E previous(){ return null; } + public ObjectArrayListIterator(E... p0){} + public ObjectArrayListIterator(E[] p0, int p1){} + public ObjectArrayListIterator(E[] p0, int p1, int p2){} + public boolean hasPrevious(){ return false; } + public int nextIndex(){ return 0; } + public int previousIndex(){ return 0; } + public void add(E p0){} + public void reset(){} + public void set(E p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/PeekingIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/PeekingIterator.java new file mode 100644 index 00000000000..ad692178b32 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/PeekingIterator.java @@ -0,0 +1,17 @@ +// Generated automatically from org.apache.commons.collections4.iterators.PeekingIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import java.util.Iterator; + +public class PeekingIterator implements Iterator +{ + protected PeekingIterator() {} + public E element(){ return null; } + public E next(){ return null; } + public E peek(){ return null; } + public PeekingIterator(Iterator p0){} + public boolean hasNext(){ return false; } + public static PeekingIterator peekingIterator(Iterator p0){ return null; } + public void remove(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/PermutationIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/PermutationIterator.java new file mode 100644 index 00000000000..df9ae228595 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/PermutationIterator.java @@ -0,0 +1,16 @@ +// Generated automatically from org.apache.commons.collections4.iterators.PermutationIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +public class PermutationIterator implements Iterator> +{ + protected PermutationIterator() {} + public List next(){ return null; } + public PermutationIterator(Collection p0){} + public boolean hasNext(){ return false; } + public void remove(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/PushbackIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/PushbackIterator.java new file mode 100644 index 00000000000..d2979309396 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/PushbackIterator.java @@ -0,0 +1,16 @@ +// Generated automatically from org.apache.commons.collections4.iterators.PushbackIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import java.util.Iterator; + +public class PushbackIterator implements Iterator +{ + protected PushbackIterator() {} + public E next(){ return null; } + public PushbackIterator(Iterator p0){} + public boolean hasNext(){ return false; } + public static PushbackIterator pushbackIterator(Iterator p0){ return null; } + public void pushback(E p0){} + public void remove(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ReverseListIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ReverseListIterator.java new file mode 100644 index 00000000000..d20b3114bf9 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/ReverseListIterator.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.commons.collections4.iterators.ReverseListIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import java.util.List; +import org.apache.commons.collections4.ResettableListIterator; + +public class ReverseListIterator implements ResettableListIterator +{ + protected ReverseListIterator() {} + public E next(){ return null; } + public E previous(){ return null; } + public ReverseListIterator(List p0){} + public boolean hasNext(){ return false; } + public boolean hasPrevious(){ return false; } + public int nextIndex(){ return 0; } + public int previousIndex(){ return 0; } + public void add(E p0){} + public void remove(){} + public void reset(){} + public void set(E p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/SingletonIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/SingletonIterator.java new file mode 100644 index 00000000000..17a8100312c --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/SingletonIterator.java @@ -0,0 +1,16 @@ +// Generated automatically from org.apache.commons.collections4.iterators.SingletonIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import org.apache.commons.collections4.ResettableIterator; + +public class SingletonIterator implements ResettableIterator +{ + protected SingletonIterator() {} + public E next(){ return null; } + public SingletonIterator(E p0){} + public SingletonIterator(E p0, boolean p1){} + public boolean hasNext(){ return false; } + public void remove(){} + public void reset(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/SingletonListIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/SingletonListIterator.java new file mode 100644 index 00000000000..ce63beac141 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/SingletonListIterator.java @@ -0,0 +1,21 @@ +// Generated automatically from org.apache.commons.collections4.iterators.SingletonListIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import org.apache.commons.collections4.ResettableListIterator; + +public class SingletonListIterator implements ResettableListIterator +{ + protected SingletonListIterator() {} + public E next(){ return null; } + public E previous(){ return null; } + public SingletonListIterator(E p0){} + public boolean hasNext(){ return false; } + public boolean hasPrevious(){ return false; } + public int nextIndex(){ return 0; } + public int previousIndex(){ return 0; } + public void add(E p0){} + public void remove(){} + public void reset(){} + public void set(E p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/UniqueFilterIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/UniqueFilterIterator.java new file mode 100644 index 00000000000..6715ca9b068 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/UniqueFilterIterator.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.commons.collections4.iterators.UniqueFilterIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import java.util.Iterator; +import org.apache.commons.collections4.iterators.FilterIterator; + +public class UniqueFilterIterator extends FilterIterator +{ + protected UniqueFilterIterator() {} + public UniqueFilterIterator(Iterator p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/UnmodifiableIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/UnmodifiableIterator.java new file mode 100644 index 00000000000..bc654382d2c --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/UnmodifiableIterator.java @@ -0,0 +1,15 @@ +// Generated automatically from org.apache.commons.collections4.iterators.UnmodifiableIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import java.util.Iterator; +import org.apache.commons.collections4.Unmodifiable; + +public class UnmodifiableIterator implements Iterator, Unmodifiable +{ + protected UnmodifiableIterator() {} + public E next(){ return null; } + public boolean hasNext(){ return false; } + public static Iterator unmodifiableIterator(Iterator p0){ return null; } + public void remove(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/UnmodifiableListIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/UnmodifiableListIterator.java new file mode 100644 index 00000000000..f3ccd8d0801 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/UnmodifiableListIterator.java @@ -0,0 +1,21 @@ +// Generated automatically from org.apache.commons.collections4.iterators.UnmodifiableListIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import java.util.ListIterator; +import org.apache.commons.collections4.Unmodifiable; + +public class UnmodifiableListIterator implements ListIterator, Unmodifiable +{ + protected UnmodifiableListIterator() {} + public E next(){ return null; } + public E previous(){ return null; } + public boolean hasNext(){ return false; } + public boolean hasPrevious(){ return false; } + public int nextIndex(){ return 0; } + public int previousIndex(){ return 0; } + public static ListIterator umodifiableListIterator(ListIterator p0){ return null; } + public void add(E p0){} + public void remove(){} + public void set(E p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/UnmodifiableMapIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/UnmodifiableMapIterator.java new file mode 100644 index 00000000000..1bda0b91563 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/UnmodifiableMapIterator.java @@ -0,0 +1,18 @@ +// Generated automatically from org.apache.commons.collections4.iterators.UnmodifiableMapIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import org.apache.commons.collections4.MapIterator; +import org.apache.commons.collections4.Unmodifiable; + +public class UnmodifiableMapIterator implements MapIterator, Unmodifiable +{ + protected UnmodifiableMapIterator() {} + public K getKey(){ return null; } + public K next(){ return null; } + public V getValue(){ return null; } + public V setValue(V p0){ return null; } + public boolean hasNext(){ return false; } + public static MapIterator unmodifiableMapIterator(MapIterator p0){ return null; } + public void remove(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/UnmodifiableOrderedMapIterator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/UnmodifiableOrderedMapIterator.java new file mode 100644 index 00000000000..2ae7ea130b4 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/iterators/UnmodifiableOrderedMapIterator.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.commons.collections4.iterators.UnmodifiableOrderedMapIterator for testing purposes + +package org.apache.commons.collections4.iterators; + +import org.apache.commons.collections4.OrderedMapIterator; +import org.apache.commons.collections4.Unmodifiable; + +public class UnmodifiableOrderedMapIterator implements OrderedMapIterator, Unmodifiable +{ + protected UnmodifiableOrderedMapIterator() {} + public K getKey(){ return null; } + public K next(){ return null; } + public K previous(){ return null; } + public V getValue(){ return null; } + public V setValue(V p0){ return null; } + public boolean hasNext(){ return false; } + public boolean hasPrevious(){ return false; } + public static OrderedMapIterator unmodifiableOrderedMapIterator(OrderedMapIterator p0){ return null; } + public void remove(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/keyvalue/MultiKey.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/keyvalue/MultiKey.java new file mode 100644 index 00000000000..c9c8bdc94cf --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/keyvalue/MultiKey.java @@ -0,0 +1,23 @@ +// Generated automatically from org.apache.commons.collections4.keyvalue.MultiKey for testing purposes + +package org.apache.commons.collections4.keyvalue; + +import java.io.Serializable; + +public class MultiKey implements Serializable +{ + protected MultiKey() {} + protected Object readResolve(){ return null; } + public K getKey(int p0){ return null; } + public K[] getKeys(){ return null; } + public MultiKey(K p0, K p1){} + public MultiKey(K p0, K p1, K p2){} + public MultiKey(K p0, K p1, K p2, K p3){} + public MultiKey(K p0, K p1, K p2, K p3, K p4){} + public MultiKey(K[] p0){} + public MultiKey(K[] p0, boolean p1){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public int hashCode(){ return 0; } + public int size(){ return 0; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/AbstractLinkedList.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/AbstractLinkedList.java new file mode 100644 index 00000000000..309ba46990a --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/AbstractLinkedList.java @@ -0,0 +1,119 @@ +// Generated automatically from org.apache.commons.collections4.list.AbstractLinkedList for testing purposes + +package org.apache.commons.collections4.list; + +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.AbstractList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import org.apache.commons.collections4.OrderedIterator; + +abstract public class AbstractLinkedList implements List +{ + protected AbstractLinkedList(){} + protected AbstractLinkedList(Collection p0){} + protected AbstractLinkedList.Node createHeaderNode(){ return null; } + protected AbstractLinkedList.Node createNode(E p0){ return null; } + protected AbstractLinkedList.Node getNode(int p0, boolean p1){ return null; } + protected Iterator createSubListIterator(AbstractLinkedList.LinkedSubList p0){ return null; } + protected ListIterator createSubListListIterator(AbstractLinkedList.LinkedSubList p0, int p1){ return null; } + protected boolean isEqualValue(Object p0, Object p1){ return false; } + protected void addNode(AbstractLinkedList.Node p0, AbstractLinkedList.Node p1){} + protected void addNodeAfter(AbstractLinkedList.Node p0, E p1){} + protected void addNodeBefore(AbstractLinkedList.Node p0, E p1){} + protected void doReadObject(ObjectInputStream p0){} + protected void doWriteObject(ObjectOutputStream p0){} + protected void init(){} + protected void removeAllNodes(){} + protected void removeNode(AbstractLinkedList.Node p0){} + protected void updateNode(AbstractLinkedList.Node p0, E p1){} + public T[] toArray(T[] p0){ return null; } + public E get(int p0){ return null; } + public E getFirst(){ return null; } + public E getLast(){ return null; } + public E remove(int p0){ return null; } + public E removeFirst(){ return null; } + public E removeLast(){ return null; } + public E set(int p0, E p1){ return null; } + public Iterator iterator(){ return null; } + public List subList(int p0, int p1){ return null; } + public ListIterator listIterator(){ return null; } + public ListIterator listIterator(int p0){ return null; } + public Object[] toArray(){ return null; } + public String toString(){ return null; } + public boolean add(E p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean addAll(int p0, Collection p1){ return false; } + public boolean addFirst(E p0){ return false; } + public boolean addLast(E p0){ return false; } + public boolean contains(Object p0){ return false; } + public boolean containsAll(Collection p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public int hashCode(){ return 0; } + public int indexOf(Object p0){ return 0; } + public int lastIndexOf(Object p0){ return 0; } + public int size(){ return 0; } + public void add(int p0, E p1){} + public void clear(){} + static class LinkedListIterator implements ListIterator, OrderedIterator + { + protected LinkedListIterator() {} + protected AbstractLinkedList.Node current = null; + protected AbstractLinkedList.Node getLastNodeReturned(){ return null; } + protected AbstractLinkedList.Node next = null; + protected LinkedListIterator(AbstractLinkedList p0, int p1){} + protected final AbstractLinkedList parent = null; + protected int expectedModCount = 0; + protected int nextIndex = 0; + protected void checkModCount(){} + public E next(){ return null; } + public E previous(){ return null; } + public boolean hasNext(){ return false; } + public boolean hasPrevious(){ return false; } + public int nextIndex(){ return 0; } + public int previousIndex(){ return 0; } + public void add(E p0){} + public void remove(){} + public void set(E p0){} + } + static class LinkedSubList extends AbstractList + { + protected LinkedSubList() {} + protected LinkedSubList(AbstractLinkedList p0, int p1, int p2){} + protected void checkModCount(){} + protected void rangeCheck(int p0, int p1){} + public E get(int p0){ return null; } + public E remove(int p0){ return null; } + public E set(int p0, E p1){ return null; } + public Iterator iterator(){ return null; } + public List subList(int p0, int p1){ return null; } + public ListIterator listIterator(int p0){ return null; } + public boolean addAll(Collection p0){ return false; } + public boolean addAll(int p0, Collection p1){ return false; } + public int size(){ return 0; } + public void add(int p0, E p1){} + public void clear(){} + } + static class Node + { + protected AbstractLinkedList.Node getNextNode(){ return null; } + protected AbstractLinkedList.Node getPreviousNode(){ return null; } + protected AbstractLinkedList.Node next = null; + protected AbstractLinkedList.Node previous = null; + protected E getValue(){ return null; } + protected E value = null; + protected Node(){} + protected Node(AbstractLinkedList.Node p0, AbstractLinkedList.Node p1, E p2){} + protected Node(E p0){} + protected void setNextNode(AbstractLinkedList.Node p0){} + protected void setPreviousNode(AbstractLinkedList.Node p0){} + protected void setValue(E p0){} + } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/AbstractListDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/AbstractListDecorator.java new file mode 100644 index 00000000000..06363654141 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/AbstractListDecorator.java @@ -0,0 +1,27 @@ +// Generated automatically from org.apache.commons.collections4.list.AbstractListDecorator for testing purposes + +package org.apache.commons.collections4.list; + +import java.util.Collection; +import java.util.List; +import java.util.ListIterator; +import org.apache.commons.collections4.collection.AbstractCollectionDecorator; + +abstract public class AbstractListDecorator extends AbstractCollectionDecorator implements List +{ + protected AbstractListDecorator(){} + protected AbstractListDecorator(List p0){} + protected List decorated(){ return null; } + public E get(int p0){ return null; } + public E remove(int p0){ return null; } + public E set(int p0, E p1){ return null; } + public List subList(int p0, int p1){ return null; } + public ListIterator listIterator(){ return null; } + public ListIterator listIterator(int p0){ return null; } + public boolean addAll(int p0, Collection p1){ return false; } + public boolean equals(Object p0){ return false; } + public int hashCode(){ return 0; } + public int indexOf(Object p0){ return 0; } + public int lastIndexOf(Object p0){ return 0; } + public void add(int p0, E p1){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/AbstractSerializableListDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/AbstractSerializableListDecorator.java new file mode 100644 index 00000000000..c7359c695c2 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/AbstractSerializableListDecorator.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.commons.collections4.list.AbstractSerializableListDecorator for testing purposes + +package org.apache.commons.collections4.list; + +import java.util.List; +import org.apache.commons.collections4.list.AbstractListDecorator; + +abstract public class AbstractSerializableListDecorator extends AbstractListDecorator +{ + protected AbstractSerializableListDecorator() {} + protected AbstractSerializableListDecorator(List p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/CursorableLinkedList.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/CursorableLinkedList.java new file mode 100644 index 00000000000..aa6e30ac7ea --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/CursorableLinkedList.java @@ -0,0 +1,44 @@ +// Generated automatically from org.apache.commons.collections4.list.CursorableLinkedList for testing purposes + +package org.apache.commons.collections4.list; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Iterator; +import java.util.ListIterator; +import org.apache.commons.collections4.list.AbstractLinkedList; + +public class CursorableLinkedList extends AbstractLinkedList implements Serializable +{ + protected ListIterator createSubListListIterator(AbstractLinkedList.LinkedSubList p0, int p1){ return null; } + protected void addNode(AbstractLinkedList.Node p0, AbstractLinkedList.Node p1){} + protected void broadcastNodeChanged(AbstractLinkedList.Node p0){} + protected void broadcastNodeInserted(AbstractLinkedList.Node p0){} + protected void broadcastNodeRemoved(AbstractLinkedList.Node p0){} + protected void init(){} + protected void registerCursor(CursorableLinkedList.Cursor p0){} + protected void removeAllNodes(){} + protected void removeNode(AbstractLinkedList.Node p0){} + protected void unregisterCursor(CursorableLinkedList.Cursor p0){} + protected void updateNode(AbstractLinkedList.Node p0, E p1){} + public CursorableLinkedList(){} + public CursorableLinkedList(Collection p0){} + public CursorableLinkedList.Cursor cursor(){ return null; } + public CursorableLinkedList.Cursor cursor(int p0){ return null; } + public Iterator iterator(){ return null; } + public ListIterator listIterator(){ return null; } + public ListIterator listIterator(int p0){ return null; } + static public class Cursor extends AbstractLinkedList.LinkedListIterator + { + protected Cursor() {} + protected Cursor(CursorableLinkedList p0, int p1){} + protected void checkModCount(){} + protected void nodeChanged(AbstractLinkedList.Node p0){} + protected void nodeInserted(AbstractLinkedList.Node p0){} + protected void nodeRemoved(AbstractLinkedList.Node p0){} + public int nextIndex(){ return 0; } + public void add(E p0){} + public void close(){} + public void remove(){} + } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/FixedSizeList.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/FixedSizeList.java new file mode 100644 index 00000000000..3d343a44de2 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/FixedSizeList.java @@ -0,0 +1,38 @@ +// Generated automatically from org.apache.commons.collections4.list.FixedSizeList for testing purposes + +package org.apache.commons.collections4.list; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.function.Predicate; +import org.apache.commons.collections4.BoundedCollection; +import org.apache.commons.collections4.list.AbstractSerializableListDecorator; + +public class FixedSizeList extends AbstractSerializableListDecorator implements BoundedCollection +{ + protected FixedSizeList() {} + protected FixedSizeList(List p0){} + public E get(int p0){ return null; } + public E remove(int p0){ return null; } + public E set(int p0, E p1){ return null; } + public Iterator iterator(){ return null; } + public List subList(int p0, int p1){ return null; } + public ListIterator listIterator(){ return null; } + public ListIterator listIterator(int p0){ return null; } + public boolean add(E p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean addAll(int p0, Collection p1){ return false; } + public boolean isFull(){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public int indexOf(Object p0){ return 0; } + public int lastIndexOf(Object p0){ return 0; } + public int maxSize(){ return 0; } + public static FixedSizeList fixedSizeList(List p0){ return null; } + public void add(int p0, E p1){} + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/GrowthList.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/GrowthList.java new file mode 100644 index 00000000000..795e68cba6c --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/GrowthList.java @@ -0,0 +1,18 @@ +// Generated automatically from org.apache.commons.collections4.list.GrowthList for testing purposes + +package org.apache.commons.collections4.list; + +import java.util.Collection; +import java.util.List; +import org.apache.commons.collections4.list.AbstractSerializableListDecorator; + +public class GrowthList extends AbstractSerializableListDecorator +{ + protected GrowthList(List p0){} + public E set(int p0, E p1){ return null; } + public GrowthList(){} + public GrowthList(int p0){} + public boolean addAll(int p0, Collection p1){ return false; } + public static GrowthList growthList(List p0){ return null; } + public void add(int p0, E p1){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/LazyList.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/LazyList.java new file mode 100644 index 00000000000..08392dd78cd --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/LazyList.java @@ -0,0 +1,19 @@ +// Generated automatically from org.apache.commons.collections4.list.LazyList for testing purposes + +package org.apache.commons.collections4.list; + +import java.util.List; +import org.apache.commons.collections4.Factory; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.list.AbstractSerializableListDecorator; + +public class LazyList extends AbstractSerializableListDecorator +{ + protected LazyList() {} + protected LazyList(List p0, Factory p1){} + protected LazyList(List p0, Transformer p1){} + public E get(int p0){ return null; } + public List subList(int p0, int p1){ return null; } + public static LazyList lazyList(List p0, Factory p1){ return null; } + public static LazyList lazyList(List p0, Transformer p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/NodeCachingLinkedList.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/NodeCachingLinkedList.java new file mode 100644 index 00000000000..96bfda9e6f0 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/NodeCachingLinkedList.java @@ -0,0 +1,23 @@ +// Generated automatically from org.apache.commons.collections4.list.NodeCachingLinkedList for testing purposes + +package org.apache.commons.collections4.list; + +import java.io.Serializable; +import java.util.Collection; +import org.apache.commons.collections4.list.AbstractLinkedList; + +public class NodeCachingLinkedList extends AbstractLinkedList implements Serializable +{ + protected AbstractLinkedList.Node createNode(E p0){ return null; } + protected AbstractLinkedList.Node getNodeFromCache(){ return null; } + protected boolean isCacheFull(){ return false; } + protected int getMaximumCacheSize(){ return 0; } + protected void addNodeToCache(AbstractLinkedList.Node p0){} + protected void removeAllNodes(){} + protected void removeNode(AbstractLinkedList.Node p0){} + protected void setMaximumCacheSize(int p0){} + protected void shrinkCacheToMaximumSize(){} + public NodeCachingLinkedList(){} + public NodeCachingLinkedList(Collection p0){} + public NodeCachingLinkedList(int p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/PredicatedList.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/PredicatedList.java new file mode 100644 index 00000000000..624fd543e81 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/PredicatedList.java @@ -0,0 +1,29 @@ +// Generated automatically from org.apache.commons.collections4.list.PredicatedList for testing purposes + +package org.apache.commons.collections4.list; + +import java.util.Collection; +import java.util.List; +import java.util.ListIterator; +import org.apache.commons.collections4.Predicate; +import org.apache.commons.collections4.collection.PredicatedCollection; + +public class PredicatedList extends PredicatedCollection implements List +{ + protected PredicatedList() {} + protected List decorated(){ return null; } + protected PredicatedList(List p0, Predicate p1){} + public E get(int p0){ return null; } + public E remove(int p0){ return null; } + public E set(int p0, E p1){ return null; } + public List subList(int p0, int p1){ return null; } + public ListIterator listIterator(){ return null; } + public ListIterator listIterator(int p0){ return null; } + public boolean addAll(int p0, Collection p1){ return false; } + public boolean equals(Object p0){ return false; } + public int hashCode(){ return 0; } + public int indexOf(Object p0){ return 0; } + public int lastIndexOf(Object p0){ return 0; } + public static PredicatedList predicatedList(List p0, Predicate p1){ return null; } + public void add(int p0, E p1){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/SetUniqueList.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/SetUniqueList.java new file mode 100644 index 00000000000..0264c250aff --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/SetUniqueList.java @@ -0,0 +1,37 @@ +// Generated automatically from org.apache.commons.collections4.list.SetUniqueList for testing purposes + +package org.apache.commons.collections4.list; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Set; +import java.util.function.Predicate; +import org.apache.commons.collections4.list.AbstractSerializableListDecorator; + +public class SetUniqueList extends AbstractSerializableListDecorator +{ + protected SetUniqueList() {} + protected Set createSetBasedOnList(Set p0, List p1){ return null; } + protected SetUniqueList(List p0, Set p1){} + public E remove(int p0){ return null; } + public E set(int p0, E p1){ return null; } + public Iterator iterator(){ return null; } + public List subList(int p0, int p1){ return null; } + public ListIterator listIterator(){ return null; } + public ListIterator listIterator(int p0){ return null; } + public Set asSet(){ return null; } + public boolean add(E p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean addAll(int p0, Collection p1){ return false; } + public boolean contains(Object p0){ return false; } + public boolean containsAll(Collection p0){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public static SetUniqueList setUniqueList(List p0){ return null; } + public void add(int p0, E p1){} + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/TransformedList.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/TransformedList.java new file mode 100644 index 00000000000..d3bd9db0cbf --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/TransformedList.java @@ -0,0 +1,30 @@ +// Generated automatically from org.apache.commons.collections4.list.TransformedList for testing purposes + +package org.apache.commons.collections4.list; + +import java.util.Collection; +import java.util.List; +import java.util.ListIterator; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.collection.TransformedCollection; + +public class TransformedList extends TransformedCollection implements List +{ + protected TransformedList() {} + protected List getList(){ return null; } + protected TransformedList(List p0, Transformer p1){} + public E get(int p0){ return null; } + public E remove(int p0){ return null; } + public E set(int p0, E p1){ return null; } + public List subList(int p0, int p1){ return null; } + public ListIterator listIterator(){ return null; } + public ListIterator listIterator(int p0){ return null; } + public boolean addAll(int p0, Collection p1){ return false; } + public boolean equals(Object p0){ return false; } + public int hashCode(){ return 0; } + public int indexOf(Object p0){ return 0; } + public int lastIndexOf(Object p0){ return 0; } + public static TransformedList transformedList(List p0, Transformer p1){ return null; } + public static TransformedList transformingList(List p0, Transformer p1){ return null; } + public void add(int p0, E p1){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/TreeList.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/TreeList.java new file mode 100644 index 00000000000..7b9c600aba5 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/TreeList.java @@ -0,0 +1,27 @@ +// Generated automatically from org.apache.commons.collections4.list.TreeList for testing purposes + +package org.apache.commons.collections4.list; + +import java.util.AbstractList; +import java.util.Collection; +import java.util.Iterator; +import java.util.ListIterator; + +public class TreeList extends AbstractList +{ + public E get(int p0){ return null; } + public E remove(int p0){ return null; } + public E set(int p0, E p1){ return null; } + public Iterator iterator(){ return null; } + public ListIterator listIterator(){ return null; } + public ListIterator listIterator(int p0){ return null; } + public Object[] toArray(){ return null; } + public TreeList(){} + public TreeList(Collection p0){} + public boolean addAll(Collection p0){ return false; } + public boolean contains(Object p0){ return false; } + public int indexOf(Object p0){ return 0; } + public int size(){ return 0; } + public void add(int p0, E p1){} + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/UnmodifiableList.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/UnmodifiableList.java new file mode 100644 index 00000000000..cfe9c10d63f --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/list/UnmodifiableList.java @@ -0,0 +1,33 @@ +// Generated automatically from org.apache.commons.collections4.list.UnmodifiableList for testing purposes + +package org.apache.commons.collections4.list; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.function.Predicate; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.list.AbstractSerializableListDecorator; + +public class UnmodifiableList extends AbstractSerializableListDecorator implements Unmodifiable +{ + protected UnmodifiableList() {} + public E remove(int p0){ return null; } + public E set(int p0, E p1){ return null; } + public Iterator iterator(){ return null; } + public List subList(int p0, int p1){ return null; } + public ListIterator listIterator(){ return null; } + public ListIterator listIterator(int p0){ return null; } + public UnmodifiableList(List p0){} + public boolean add(Object p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean addAll(int p0, Collection p1){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public static List unmodifiableList(List p0){ return null; } + public void add(int p0, E p1){} + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractInputCheckedMapDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractInputCheckedMapDecorator.java new file mode 100644 index 00000000000..390e24d5dc0 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractInputCheckedMapDecorator.java @@ -0,0 +1,16 @@ +// Generated automatically from org.apache.commons.collections4.map.AbstractInputCheckedMapDecorator for testing purposes + +package org.apache.commons.collections4.map; + +import java.util.Map; +import java.util.Set; +import org.apache.commons.collections4.map.AbstractMapDecorator; + +abstract class AbstractInputCheckedMapDecorator extends AbstractMapDecorator +{ + protected AbstractInputCheckedMapDecorator(){} + protected AbstractInputCheckedMapDecorator(Map p0){} + protected abstract V checkSetValue(V p0); + protected boolean isSetValueChecking(){ return false; } + public Set> entrySet(){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractOrderedMapDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractOrderedMapDecorator.java new file mode 100644 index 00000000000..9780736b0a7 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractOrderedMapDecorator.java @@ -0,0 +1,19 @@ +// Generated automatically from org.apache.commons.collections4.map.AbstractOrderedMapDecorator for testing purposes + +package org.apache.commons.collections4.map; + +import org.apache.commons.collections4.OrderedMap; +import org.apache.commons.collections4.OrderedMapIterator; +import org.apache.commons.collections4.map.AbstractMapDecorator; + +abstract public class AbstractOrderedMapDecorator extends AbstractMapDecorator implements OrderedMap +{ + protected AbstractOrderedMapDecorator(){} + protected OrderedMap decorated(){ return null; } + public AbstractOrderedMapDecorator(OrderedMap p0){} + public K firstKey(){ return null; } + public K lastKey(){ return null; } + public K nextKey(K p0){ return null; } + public K previousKey(K p0){ return null; } + public OrderedMapIterator mapIterator(){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractSortedMapDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractSortedMapDecorator.java new file mode 100644 index 00000000000..7740bec5a9e --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractSortedMapDecorator.java @@ -0,0 +1,25 @@ +// Generated automatically from org.apache.commons.collections4.map.AbstractSortedMapDecorator for testing purposes + +package org.apache.commons.collections4.map; + +import java.util.Comparator; +import java.util.SortedMap; +import org.apache.commons.collections4.IterableSortedMap; +import org.apache.commons.collections4.OrderedMapIterator; +import org.apache.commons.collections4.map.AbstractMapDecorator; + +abstract public class AbstractSortedMapDecorator extends AbstractMapDecorator implements IterableSortedMap +{ + protected AbstractSortedMapDecorator(){} + protected SortedMap decorated(){ return null; } + public AbstractSortedMapDecorator(SortedMap p0){} + public Comparator comparator(){ return null; } + public K firstKey(){ return null; } + public K lastKey(){ return null; } + public K nextKey(K p0){ return null; } + public K previousKey(K p0){ return null; } + public OrderedMapIterator mapIterator(){ return null; } + public SortedMap headMap(K p0){ return null; } + public SortedMap subMap(K p0, K p1){ return null; } + public SortedMap tailMap(K p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/CaseInsensitiveMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/CaseInsensitiveMap.java new file mode 100644 index 00000000000..d231596467c --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/CaseInsensitiveMap.java @@ -0,0 +1,17 @@ +// Generated automatically from org.apache.commons.collections4.map.CaseInsensitiveMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.io.Serializable; +import java.util.Map; +import org.apache.commons.collections4.map.AbstractHashedMap; + +public class CaseInsensitiveMap extends AbstractHashedMap implements Cloneable, Serializable +{ + protected Object convertKey(Object p0){ return null; } + public CaseInsensitiveMap(){} + public CaseInsensitiveMap(Map p0){} + public CaseInsensitiveMap(int p0){} + public CaseInsensitiveMap(int p0, float p1){} + public CaseInsensitiveMap clone(){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/CompositeMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/CompositeMap.java new file mode 100644 index 00000000000..a92e8015f4a --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/CompositeMap.java @@ -0,0 +1,41 @@ +// Generated automatically from org.apache.commons.collections4.map.CompositeMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import org.apache.commons.collections4.map.AbstractIterableMap; + +public class CompositeMap extends AbstractIterableMap implements Serializable +{ + public Collection values(){ return null; } + public CompositeMap(){} + public CompositeMap(Map p0, Map p1){} + public CompositeMap(Map p0, Map p1, CompositeMap.MapMutator p2){} + public CompositeMap(Map... p0){} + public CompositeMap(Map[] p0, CompositeMap.MapMutator p1){} + public Map removeComposited(Map p0){ return null; } + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public V get(Object p0){ return null; } + public V put(K p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public boolean containsKey(Object p0){ return false; } + public boolean containsValue(Object p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public int hashCode(){ return 0; } + public int size(){ return 0; } + public void addComposited(Map p0){} + public void clear(){} + public void putAll(Map p0){} + public void setMutator(CompositeMap.MapMutator p0){} + static public interface MapMutator extends Serializable + { + V put(CompositeMap p0, Map[] p1, K p2, V p3); + void putAll(CompositeMap p0, Map[] p1, Map p2); + void resolveCollision(CompositeMap p0, Map p1, Map p2, Collection p3); + } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/DefaultedMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/DefaultedMap.java new file mode 100644 index 00000000000..d84a30be423 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/DefaultedMap.java @@ -0,0 +1,21 @@ +// Generated automatically from org.apache.commons.collections4.map.DefaultedMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.io.Serializable; +import java.util.Map; +import org.apache.commons.collections4.Factory; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.map.AbstractMapDecorator; + +public class DefaultedMap extends AbstractMapDecorator implements Serializable +{ + protected DefaultedMap() {} + protected DefaultedMap(Map p0, Transformer p1){} + public DefaultedMap(Transformer p0){} + public DefaultedMap(V p0){} + public V get(Object p0){ return null; } + public static DefaultedMap defaultedMap(Map p0, Factory p1){ return null; } + public static DefaultedMap defaultedMap(Map p0, V p1){ return null; } + public static Map defaultedMap(Map p0, Transformer p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/EntrySetToMapIteratorAdapter.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/EntrySetToMapIteratorAdapter.java new file mode 100644 index 00000000000..8820b293eba --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/EntrySetToMapIteratorAdapter.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.commons.collections4.map.EntrySetToMapIteratorAdapter for testing purposes + +package org.apache.commons.collections4.map; + +import java.util.Map; +import java.util.Set; +import org.apache.commons.collections4.MapIterator; +import org.apache.commons.collections4.ResettableIterator; + +public class EntrySetToMapIteratorAdapter implements MapIterator, ResettableIterator +{ + protected EntrySetToMapIteratorAdapter() {} + protected Map.Entry current(){ return null; } + public EntrySetToMapIteratorAdapter(Set> p0){} + public K getKey(){ return null; } + public K next(){ return null; } + public V getValue(){ return null; } + public V setValue(V p0){ return null; } + public boolean hasNext(){ return false; } + public void remove(){} + public void reset(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/FixedSizeMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/FixedSizeMap.java new file mode 100644 index 00000000000..de42da42414 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/FixedSizeMap.java @@ -0,0 +1,26 @@ +// Generated automatically from org.apache.commons.collections4.map.FixedSizeMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import org.apache.commons.collections4.BoundedMap; +import org.apache.commons.collections4.map.AbstractMapDecorator; + +public class FixedSizeMap extends AbstractMapDecorator implements BoundedMap, Serializable +{ + protected FixedSizeMap() {} + protected FixedSizeMap(Map p0){} + public Collection values(){ return null; } + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public V put(K p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public boolean isFull(){ return false; } + public int maxSize(){ return 0; } + public static FixedSizeMap fixedSizeMap(Map p0){ return null; } + public void clear(){} + public void putAll(Map p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/FixedSizeSortedMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/FixedSizeSortedMap.java new file mode 100644 index 00000000000..33c43e0cb8f --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/FixedSizeSortedMap.java @@ -0,0 +1,31 @@ +// Generated automatically from org.apache.commons.collections4.map.FixedSizeSortedMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import org.apache.commons.collections4.BoundedMap; +import org.apache.commons.collections4.map.AbstractSortedMapDecorator; + +public class FixedSizeSortedMap extends AbstractSortedMapDecorator implements BoundedMap, Serializable +{ + protected FixedSizeSortedMap() {} + protected FixedSizeSortedMap(SortedMap p0){} + protected SortedMap getSortedMap(){ return null; } + public Collection values(){ return null; } + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public SortedMap headMap(K p0){ return null; } + public SortedMap subMap(K p0, K p1){ return null; } + public SortedMap tailMap(K p0){ return null; } + public V put(K p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public boolean isFull(){ return false; } + public int maxSize(){ return 0; } + public static FixedSizeSortedMap fixedSizeSortedMap(SortedMap p0){ return null; } + public void clear(){} + public void putAll(Map p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/Flat3Map.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/Flat3Map.java new file mode 100644 index 00000000000..6c15d8d2482 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/Flat3Map.java @@ -0,0 +1,35 @@ +// Generated automatically from org.apache.commons.collections4.map.Flat3Map for testing purposes + +package org.apache.commons.collections4.map; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import org.apache.commons.collections4.IterableMap; +import org.apache.commons.collections4.MapIterator; +import org.apache.commons.collections4.map.AbstractHashedMap; + +public class Flat3Map implements Cloneable, IterableMap, Serializable +{ + protected AbstractHashedMap createDelegateMap(){ return null; } + public Collection values(){ return null; } + public Flat3Map(){} + public Flat3Map(Map p0){} + public Flat3Map clone(){ return null; } + public MapIterator mapIterator(){ return null; } + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public String toString(){ return null; } + public V get(Object p0){ return null; } + public V put(K p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public boolean containsKey(Object p0){ return false; } + public boolean containsValue(Object p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public int hashCode(){ return 0; } + public int size(){ return 0; } + public void clear(){} + public void putAll(Map p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/LRUMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/LRUMap.java new file mode 100644 index 00000000000..96f83ee7a68 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/LRUMap.java @@ -0,0 +1,39 @@ +// Generated automatically from org.apache.commons.collections4.map.LRUMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.Map; +import org.apache.commons.collections4.BoundedMap; +import org.apache.commons.collections4.map.AbstractHashedMap; +import org.apache.commons.collections4.map.AbstractLinkedMap; + +public class LRUMap extends AbstractLinkedMap implements BoundedMap, Cloneable, Serializable +{ + protected boolean removeLRU(AbstractLinkedMap.LinkEntry p0){ return false; } + protected static int DEFAULT_MAX_SIZE = 0; + protected void addMapping(int p0, int p1, K p2, V p3){} + protected void doReadObject(ObjectInputStream p0){} + protected void doWriteObject(ObjectOutputStream p0){} + protected void moveToMRU(AbstractLinkedMap.LinkEntry p0){} + protected void reuseMapping(AbstractLinkedMap.LinkEntry p0, int p1, int p2, K p3, V p4){} + protected void updateEntry(AbstractHashedMap.HashEntry p0, V p1){} + public LRUMap(){} + public LRUMap(Map p0){} + public LRUMap(Map p0, boolean p1){} + public LRUMap(int p0){} + public LRUMap(int p0, boolean p1){} + public LRUMap(int p0, float p1){} + public LRUMap(int p0, float p1, boolean p2){} + public LRUMap(int p0, int p1){} + public LRUMap(int p0, int p1, float p2){} + public LRUMap(int p0, int p1, float p2, boolean p3){} + public LRUMap clone(){ return null; } + public V get(Object p0){ return null; } + public V get(Object p0, boolean p1){ return null; } + public boolean isFull(){ return false; } + public boolean isScanUntilRemovable(){ return false; } + public int maxSize(){ return 0; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/LazyMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/LazyMap.java new file mode 100644 index 00000000000..cae911cd5d3 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/LazyMap.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.commons.collections4.map.LazyMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.io.Serializable; +import java.util.Map; +import org.apache.commons.collections4.Factory; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.map.AbstractMapDecorator; + +public class LazyMap extends AbstractMapDecorator implements Serializable +{ + protected LazyMap() {} + protected LazyMap(Map p0, Factory p1){} + protected LazyMap(Map p0, Transformer p1){} + protected final Transformer factory = null; + public V get(Object p0){ return null; } + public static LazyMap lazyMap(Map p0, Factory p1){ return null; } + public static LazyMap lazyMap(Map p0, Transformer p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/LazySortedMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/LazySortedMap.java new file mode 100644 index 00000000000..e04062eb23a --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/LazySortedMap.java @@ -0,0 +1,25 @@ +// Generated automatically from org.apache.commons.collections4.map.LazySortedMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.util.Comparator; +import java.util.SortedMap; +import org.apache.commons.collections4.Factory; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.map.LazyMap; + +public class LazySortedMap extends LazyMap implements SortedMap +{ + protected LazySortedMap() {} + protected LazySortedMap(SortedMap p0, Factory p1){} + protected LazySortedMap(SortedMap p0, Transformer p1){} + protected SortedMap getSortedMap(){ return null; } + public Comparator comparator(){ return null; } + public K firstKey(){ return null; } + public K lastKey(){ return null; } + public SortedMap headMap(K p0){ return null; } + public SortedMap subMap(K p0, K p1){ return null; } + public SortedMap tailMap(K p0){ return null; } + public static LazySortedMap lazySortedMap(SortedMap p0, Factory p1){ return null; } + public static LazySortedMap lazySortedMap(SortedMap p0, Transformer p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/ListOrderedMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/ListOrderedMap.java new file mode 100644 index 00000000000..45931bc8cd3 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/ListOrderedMap.java @@ -0,0 +1,42 @@ +// Generated automatically from org.apache.commons.collections4.map.ListOrderedMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.io.Serializable; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.apache.commons.collections4.OrderedMap; +import org.apache.commons.collections4.OrderedMapIterator; +import org.apache.commons.collections4.map.AbstractMapDecorator; + +public class ListOrderedMap extends AbstractMapDecorator implements OrderedMap, Serializable +{ + protected ListOrderedMap(Map p0){} + public Collection values(){ return null; } + public K firstKey(){ return null; } + public K get(int p0){ return null; } + public K lastKey(){ return null; } + public K nextKey(Object p0){ return null; } + public K previousKey(Object p0){ return null; } + public List asList(){ return null; } + public List keyList(){ return null; } + public List valueList(){ return null; } + public ListOrderedMap(){} + public OrderedMapIterator mapIterator(){ return null; } + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public String toString(){ return null; } + public V getValue(int p0){ return null; } + public V put(K p0, V p1){ return null; } + public V put(int p0, K p1, V p2){ return null; } + public V remove(Object p0){ return null; } + public V remove(int p0){ return null; } + public V setValue(int p0, V p1){ return null; } + public int indexOf(Object p0){ return 0; } + public static ListOrderedMap listOrderedMap(Map p0){ return null; } + public void clear(){} + public void putAll(Map p0){} + public void putAll(int p0, Map p1){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/MultiKeyMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/MultiKeyMap.java new file mode 100644 index 00000000000..284c4e12892 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/MultiKeyMap.java @@ -0,0 +1,51 @@ +// Generated automatically from org.apache.commons.collections4.map.MultiKeyMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.io.Serializable; +import java.util.Map; +import org.apache.commons.collections4.MapIterator; +import org.apache.commons.collections4.keyvalue.MultiKey; +import org.apache.commons.collections4.map.AbstractHashedMap; +import org.apache.commons.collections4.map.AbstractMapDecorator; + +public class MultiKeyMap extends AbstractMapDecorator, V> implements Cloneable, Serializable +{ + protected AbstractHashedMap, V> decorated(){ return null; } + protected MultiKeyMap(AbstractHashedMap, V> p0){} + protected boolean isEqualKey(AbstractHashedMap.HashEntry, V> p0, Object p1, Object p2){ return false; } + protected boolean isEqualKey(AbstractHashedMap.HashEntry, V> p0, Object p1, Object p2, Object p3){ return false; } + protected boolean isEqualKey(AbstractHashedMap.HashEntry, V> p0, Object p1, Object p2, Object p3, Object p4){ return false; } + protected boolean isEqualKey(AbstractHashedMap.HashEntry, V> p0, Object p1, Object p2, Object p3, Object p4, Object p5){ return false; } + protected int hash(Object p0, Object p1){ return 0; } + protected int hash(Object p0, Object p1, Object p2){ return 0; } + protected int hash(Object p0, Object p1, Object p2, Object p3){ return 0; } + protected int hash(Object p0, Object p1, Object p2, Object p3, Object p4){ return 0; } + protected void checkKey(MultiKey p0){} + public MapIterator, V> mapIterator(){ return null; } + public MultiKeyMap(){} + public MultiKeyMap clone(){ return null; } + public V get(Object p0, Object p1){ return null; } + public V get(Object p0, Object p1, Object p2){ return null; } + public V get(Object p0, Object p1, Object p2, Object p3){ return null; } + public V get(Object p0, Object p1, Object p2, Object p3, Object p4){ return null; } + public V put(K p0, K p1, K p2, K p3, K p4, V p5){ return null; } + public V put(K p0, K p1, K p2, K p3, V p4){ return null; } + public V put(K p0, K p1, K p2, V p3){ return null; } + public V put(K p0, K p1, V p2){ return null; } + public V put(MultiKey p0, V p1){ return null; } + public V removeMultiKey(Object p0, Object p1){ return null; } + public V removeMultiKey(Object p0, Object p1, Object p2){ return null; } + public V removeMultiKey(Object p0, Object p1, Object p2, Object p3){ return null; } + public V removeMultiKey(Object p0, Object p1, Object p2, Object p3, Object p4){ return null; } + public boolean containsKey(Object p0, Object p1){ return false; } + public boolean containsKey(Object p0, Object p1, Object p2){ return false; } + public boolean containsKey(Object p0, Object p1, Object p2, Object p3){ return false; } + public boolean containsKey(Object p0, Object p1, Object p2, Object p3, Object p4){ return false; } + public boolean removeAll(Object p0){ return false; } + public boolean removeAll(Object p0, Object p1){ return false; } + public boolean removeAll(Object p0, Object p1, Object p2){ return false; } + public boolean removeAll(Object p0, Object p1, Object p2, Object p3){ return false; } + public static MultiKeyMap multiKeyMap(AbstractHashedMap, V> p0){ return null; } + public void putAll(Map, ? extends V> p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/PassiveExpiringMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/PassiveExpiringMap.java new file mode 100644 index 00000000000..cd5b2fdd172 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/PassiveExpiringMap.java @@ -0,0 +1,38 @@ +// Generated automatically from org.apache.commons.collections4.map.PassiveExpiringMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import org.apache.commons.collections4.map.AbstractMapDecorator; + +public class PassiveExpiringMap extends AbstractMapDecorator implements Serializable +{ + public Collection values(){ return null; } + public PassiveExpiringMap(){} + public PassiveExpiringMap(Map p0){} + public PassiveExpiringMap(PassiveExpiringMap.ExpirationPolicy p0){} + public PassiveExpiringMap(PassiveExpiringMap.ExpirationPolicy p0, Map p1){} + public PassiveExpiringMap(long p0){} + public PassiveExpiringMap(long p0, Map p1){} + public PassiveExpiringMap(long p0, TimeUnit p1){} + public PassiveExpiringMap(long p0, TimeUnit p1, Map p2){} + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public V get(Object p0){ return null; } + public V put(K p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public boolean containsKey(Object p0){ return false; } + public boolean containsValue(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public int size(){ return 0; } + public void clear(){} + public void putAll(Map p0){} + static public interface ExpirationPolicy extends Serializable + { + long expirationTime(K p0, V p1); + } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/PredicatedMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/PredicatedMap.java new file mode 100644 index 00000000000..647266e8a4b --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/PredicatedMap.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.commons.collections4.map.PredicatedMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.io.Serializable; +import java.util.Map; +import org.apache.commons.collections4.Predicate; +import org.apache.commons.collections4.map.AbstractInputCheckedMapDecorator; + +public class PredicatedMap extends AbstractInputCheckedMapDecorator implements Serializable +{ + protected PredicatedMap() {} + protected PredicatedMap(Map p0, Predicate p1, Predicate p2){} + protected V checkSetValue(V p0){ return null; } + protected boolean isSetValueChecking(){ return false; } + protected final Predicate keyPredicate = null; + protected final Predicate valuePredicate = null; + protected void validate(K p0, V p1){} + public V put(K p0, V p1){ return null; } + public static PredicatedMap predicatedMap(Map p0, Predicate p1, Predicate p2){ return null; } + public void putAll(Map p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/PredicatedSortedMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/PredicatedSortedMap.java new file mode 100644 index 00000000000..5100e10860a --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/PredicatedSortedMap.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.commons.collections4.map.PredicatedSortedMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.util.Comparator; +import java.util.SortedMap; +import org.apache.commons.collections4.Predicate; +import org.apache.commons.collections4.map.PredicatedMap; + +public class PredicatedSortedMap extends PredicatedMap implements SortedMap +{ + protected PredicatedSortedMap() {} + protected PredicatedSortedMap(SortedMap p0, Predicate p1, Predicate p2){} + protected SortedMap getSortedMap(){ return null; } + public Comparator comparator(){ return null; } + public K firstKey(){ return null; } + public K lastKey(){ return null; } + public SortedMap headMap(K p0){ return null; } + public SortedMap subMap(K p0, K p1){ return null; } + public SortedMap tailMap(K p0){ return null; } + public static PredicatedSortedMap predicatedSortedMap(SortedMap p0, Predicate p1, Predicate p2){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/SingletonMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/SingletonMap.java new file mode 100644 index 00000000000..580b7f98d9c --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/SingletonMap.java @@ -0,0 +1,49 @@ +// Generated automatically from org.apache.commons.collections4.map.SingletonMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import org.apache.commons.collections4.BoundedMap; +import org.apache.commons.collections4.KeyValue; +import org.apache.commons.collections4.OrderedMap; +import org.apache.commons.collections4.OrderedMapIterator; + +public class SingletonMap implements BoundedMap, Cloneable, KeyValue, OrderedMap, Serializable +{ + protected boolean isEqualKey(Object p0){ return false; } + protected boolean isEqualValue(Object p0){ return false; } + public Collection values(){ return null; } + public K firstKey(){ return null; } + public K getKey(){ return null; } + public K lastKey(){ return null; } + public K nextKey(K p0){ return null; } + public K previousKey(K p0){ return null; } + public OrderedMapIterator mapIterator(){ return null; } + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public SingletonMap(){} + public SingletonMap(K p0, V p1){} + public SingletonMap(KeyValue p0){} + public SingletonMap(Map.Entry p0){} + public SingletonMap(Map p0){} + public SingletonMap clone(){ return null; } + public String toString(){ return null; } + public V get(Object p0){ return null; } + public V getValue(){ return null; } + public V put(K p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public V setValue(V p0){ return null; } + public boolean containsKey(Object p0){ return false; } + public boolean containsValue(Object p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public boolean isFull(){ return false; } + public int hashCode(){ return 0; } + public int maxSize(){ return 0; } + public int size(){ return 0; } + public void clear(){} + public void putAll(Map p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/TransformedMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/TransformedMap.java new file mode 100644 index 00000000000..1a1f5c584ab --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/TransformedMap.java @@ -0,0 +1,25 @@ +// Generated automatically from org.apache.commons.collections4.map.TransformedMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.io.Serializable; +import java.util.Map; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.map.AbstractInputCheckedMapDecorator; + +public class TransformedMap extends AbstractInputCheckedMapDecorator implements Serializable +{ + protected TransformedMap() {} + protected K transformKey(K p0){ return null; } + protected Map transformMap(Map p0){ return null; } + protected TransformedMap(Map p0, Transformer p1, Transformer p2){} + protected V checkSetValue(V p0){ return null; } + protected V transformValue(V p0){ return null; } + protected boolean isSetValueChecking(){ return false; } + protected final Transformer keyTransformer = null; + protected final Transformer valueTransformer = null; + public V put(K p0, V p1){ return null; } + public static TransformedMap transformedMap(Map p0, Transformer p1, Transformer p2){ return null; } + public static TransformedMap transformingMap(Map p0, Transformer p1, Transformer p2){ return null; } + public void putAll(Map p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/TransformedSortedMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/TransformedSortedMap.java new file mode 100644 index 00000000000..ad1ac90c54f --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/TransformedSortedMap.java @@ -0,0 +1,23 @@ +// Generated automatically from org.apache.commons.collections4.map.TransformedSortedMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.util.Comparator; +import java.util.SortedMap; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.map.TransformedMap; + +public class TransformedSortedMap extends TransformedMap implements SortedMap +{ + protected TransformedSortedMap() {} + protected SortedMap getSortedMap(){ return null; } + protected TransformedSortedMap(SortedMap p0, Transformer p1, Transformer p2){} + public Comparator comparator(){ return null; } + public K firstKey(){ return null; } + public K lastKey(){ return null; } + public SortedMap headMap(K p0){ return null; } + public SortedMap subMap(K p0, K p1){ return null; } + public SortedMap tailMap(K p0){ return null; } + public static TransformedSortedMap transformedSortedMap(SortedMap p0, Transformer p1, Transformer p2){ return null; } + public static TransformedSortedMap transformingSortedMap(SortedMap p0, Transformer p1, Transformer p2){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/UnmodifiableEntrySet.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/UnmodifiableEntrySet.java new file mode 100644 index 00000000000..1ce1d35f337 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/UnmodifiableEntrySet.java @@ -0,0 +1,27 @@ +// Generated automatically from org.apache.commons.collections4.map.UnmodifiableEntrySet for testing purposes + +package org.apache.commons.collections4.map; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.set.AbstractSetDecorator; + +public class UnmodifiableEntrySet extends AbstractSetDecorator> implements Unmodifiable +{ + protected UnmodifiableEntrySet() {} + public T[] toArray(T[] p0){ return null; } + public Iterator> iterator(){ return null; } + public Object[] toArray(){ return null; } + public boolean add(Map.Entry p0){ return false; } + public boolean addAll(Collection> p0){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate> p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public static Set> unmodifiableEntrySet(Set> p0){ return null; } + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/UnmodifiableMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/UnmodifiableMap.java new file mode 100644 index 00000000000..7e43b148a01 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/UnmodifiableMap.java @@ -0,0 +1,25 @@ +// Generated automatically from org.apache.commons.collections4.map.UnmodifiableMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import org.apache.commons.collections4.MapIterator; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.map.AbstractMapDecorator; + +public class UnmodifiableMap extends AbstractMapDecorator implements Serializable, Unmodifiable +{ + protected UnmodifiableMap() {} + public Collection values(){ return null; } + public MapIterator mapIterator(){ return null; } + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public V put(K p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public static Map unmodifiableMap(Map p0){ return null; } + public void clear(){} + public void putAll(Map p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/UnmodifiableOrderedMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/UnmodifiableOrderedMap.java new file mode 100644 index 00000000000..8cb8b0cca0c --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/UnmodifiableOrderedMap.java @@ -0,0 +1,26 @@ +// Generated automatically from org.apache.commons.collections4.map.UnmodifiableOrderedMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import org.apache.commons.collections4.OrderedMap; +import org.apache.commons.collections4.OrderedMapIterator; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.map.AbstractOrderedMapDecorator; + +public class UnmodifiableOrderedMap extends AbstractOrderedMapDecorator implements Serializable, Unmodifiable +{ + protected UnmodifiableOrderedMap() {} + public Collection values(){ return null; } + public OrderedMapIterator mapIterator(){ return null; } + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public V put(K p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public static OrderedMap unmodifiableOrderedMap(OrderedMap p0){ return null; } + public void clear(){} + public void putAll(Map p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/UnmodifiableSortedMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/UnmodifiableSortedMap.java new file mode 100644 index 00000000000..3deef9d0cc0 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/UnmodifiableSortedMap.java @@ -0,0 +1,31 @@ +// Generated automatically from org.apache.commons.collections4.map.UnmodifiableSortedMap for testing purposes + +package org.apache.commons.collections4.map; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Comparator; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.map.AbstractSortedMapDecorator; + +public class UnmodifiableSortedMap extends AbstractSortedMapDecorator implements Serializable, Unmodifiable +{ + protected UnmodifiableSortedMap() {} + public Collection values(){ return null; } + public Comparator comparator(){ return null; } + public K firstKey(){ return null; } + public K lastKey(){ return null; } + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public SortedMap headMap(K p0){ return null; } + public SortedMap subMap(K p0, K p1){ return null; } + public SortedMap tailMap(K p0){ return null; } + public V put(K p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public static SortedMap unmodifiableSortedMap(SortedMap p0){ return null; } + public void clear(){} + public void putAll(Map p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multimap/AbstractMultiValuedMapDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multimap/AbstractMultiValuedMapDecorator.java new file mode 100644 index 00000000000..1380d989fc2 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multimap/AbstractMultiValuedMapDecorator.java @@ -0,0 +1,40 @@ +// Generated automatically from org.apache.commons.collections4.multimap.AbstractMultiValuedMapDecorator for testing purposes + +package org.apache.commons.collections4.multimap; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import org.apache.commons.collections4.MapIterator; +import org.apache.commons.collections4.MultiSet; +import org.apache.commons.collections4.MultiValuedMap; + +abstract public class AbstractMultiValuedMapDecorator implements MultiValuedMap, Serializable +{ + protected AbstractMultiValuedMapDecorator() {} + protected AbstractMultiValuedMapDecorator(MultiValuedMap p0){} + protected MultiValuedMap decorated(){ return null; } + public Collection> entries(){ return null; } + public Collection get(K p0){ return null; } + public Collection remove(Object p0){ return null; } + public Collection values(){ return null; } + public Map> asMap(){ return null; } + public MapIterator mapIterator(){ return null; } + public MultiSet keys(){ return null; } + public Set keySet(){ return null; } + public String toString(){ return null; } + public boolean containsKey(Object p0){ return false; } + public boolean containsMapping(Object p0, Object p1){ return false; } + public boolean containsValue(Object p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public boolean put(K p0, V p1){ return false; } + public boolean putAll(K p0, Iterable p1){ return false; } + public boolean putAll(Map p0){ return false; } + public boolean putAll(MultiValuedMap p0){ return false; } + public boolean removeMapping(Object p0, Object p1){ return false; } + public int hashCode(){ return 0; } + public int size(){ return 0; } + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multimap/TransformedMultiValuedMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multimap/TransformedMultiValuedMap.java new file mode 100644 index 00000000000..a233ad02a95 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multimap/TransformedMultiValuedMap.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.commons.collections4.multimap.TransformedMultiValuedMap for testing purposes + +package org.apache.commons.collections4.multimap; + +import java.util.Map; +import org.apache.commons.collections4.MultiValuedMap; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.multimap.AbstractMultiValuedMapDecorator; + +public class TransformedMultiValuedMap extends AbstractMultiValuedMapDecorator +{ + protected TransformedMultiValuedMap() {} + protected K transformKey(K p0){ return null; } + protected TransformedMultiValuedMap(MultiValuedMap p0, Transformer p1, Transformer p2){} + protected V transformValue(V p0){ return null; } + public boolean put(K p0, V p1){ return false; } + public boolean putAll(K p0, Iterable p1){ return false; } + public boolean putAll(Map p0){ return false; } + public boolean putAll(MultiValuedMap p0){ return false; } + public static TransformedMultiValuedMap transformedMap(MultiValuedMap p0, Transformer p1, Transformer p2){ return null; } + public static TransformedMultiValuedMap transformingMap(MultiValuedMap p0, Transformer p1, Transformer p2){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multimap/UnmodifiableMultiValuedMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multimap/UnmodifiableMultiValuedMap.java new file mode 100644 index 00000000000..97968ec739c --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multimap/UnmodifiableMultiValuedMap.java @@ -0,0 +1,32 @@ +// Generated automatically from org.apache.commons.collections4.multimap.UnmodifiableMultiValuedMap for testing purposes + +package org.apache.commons.collections4.multimap; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import org.apache.commons.collections4.MapIterator; +import org.apache.commons.collections4.MultiSet; +import org.apache.commons.collections4.MultiValuedMap; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.multimap.AbstractMultiValuedMapDecorator; + +public class UnmodifiableMultiValuedMap extends AbstractMultiValuedMapDecorator implements Unmodifiable +{ + protected UnmodifiableMultiValuedMap() {} + public Collection> entries(){ return null; } + public Collection get(K p0){ return null; } + public Collection remove(Object p0){ return null; } + public Collection values(){ return null; } + public Map> asMap(){ return null; } + public MapIterator mapIterator(){ return null; } + public MultiSet keys(){ return null; } + public Set keySet(){ return null; } + public boolean put(K p0, V p1){ return false; } + public boolean putAll(K p0, Iterable p1){ return false; } + public boolean putAll(Map p0){ return false; } + public boolean putAll(MultiValuedMap p0){ return false; } + public boolean removeMapping(Object p0, Object p1){ return false; } + public static UnmodifiableMultiValuedMap unmodifiableMultiValuedMap(MultiValuedMap p0){ return null; } + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multiset/AbstractMultiSetDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multiset/AbstractMultiSetDecorator.java new file mode 100644 index 00000000000..3b9f76e9f60 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multiset/AbstractMultiSetDecorator.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.commons.collections4.multiset.AbstractMultiSetDecorator for testing purposes + +package org.apache.commons.collections4.multiset; + +import java.util.Set; +import org.apache.commons.collections4.MultiSet; +import org.apache.commons.collections4.collection.AbstractCollectionDecorator; + +abstract public class AbstractMultiSetDecorator extends AbstractCollectionDecorator implements MultiSet +{ + protected AbstractMultiSetDecorator(){} + protected AbstractMultiSetDecorator(MultiSet p0){} + protected MultiSet decorated(){ return null; } + public Set uniqueSet(){ return null; } + public Set> entrySet(){ return null; } + public boolean equals(Object p0){ return false; } + public int add(E p0, int p1){ return 0; } + public int getCount(Object p0){ return 0; } + public int hashCode(){ return 0; } + public int remove(Object p0, int p1){ return 0; } + public int setCount(E p0, int p1){ return 0; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multiset/PredicatedMultiSet.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multiset/PredicatedMultiSet.java new file mode 100644 index 00000000000..73331196a1f --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multiset/PredicatedMultiSet.java @@ -0,0 +1,24 @@ +// Generated automatically from org.apache.commons.collections4.multiset.PredicatedMultiSet for testing purposes + +package org.apache.commons.collections4.multiset; + +import java.util.Set; +import org.apache.commons.collections4.MultiSet; +import org.apache.commons.collections4.Predicate; +import org.apache.commons.collections4.collection.PredicatedCollection; + +public class PredicatedMultiSet extends PredicatedCollection implements MultiSet +{ + protected PredicatedMultiSet() {} + protected MultiSet decorated(){ return null; } + protected PredicatedMultiSet(MultiSet p0, Predicate p1){} + public Set uniqueSet(){ return null; } + public Set> entrySet(){ return null; } + public boolean equals(Object p0){ return false; } + public int add(E p0, int p1){ return 0; } + public int getCount(Object p0){ return 0; } + public int hashCode(){ return 0; } + public int remove(Object p0, int p1){ return 0; } + public int setCount(E p0, int p1){ return 0; } + public static PredicatedMultiSet predicatedMultiSet(MultiSet p0, Predicate p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multiset/SynchronizedMultiSet.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multiset/SynchronizedMultiSet.java new file mode 100644 index 00000000000..63bf44167f4 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multiset/SynchronizedMultiSet.java @@ -0,0 +1,24 @@ +// Generated automatically from org.apache.commons.collections4.multiset.SynchronizedMultiSet for testing purposes + +package org.apache.commons.collections4.multiset; + +import java.util.Set; +import org.apache.commons.collections4.MultiSet; +import org.apache.commons.collections4.collection.SynchronizedCollection; + +public class SynchronizedMultiSet extends SynchronizedCollection implements MultiSet +{ + protected SynchronizedMultiSet() {} + protected MultiSet decorated(){ return null; } + protected SynchronizedMultiSet(MultiSet p0){} + protected SynchronizedMultiSet(MultiSet p0, Object p1){} + public Set uniqueSet(){ return null; } + public Set> entrySet(){ return null; } + public boolean equals(Object p0){ return false; } + public int add(E p0, int p1){ return 0; } + public int getCount(Object p0){ return 0; } + public int hashCode(){ return 0; } + public int remove(Object p0, int p1){ return 0; } + public int setCount(E p0, int p1){ return 0; } + public static SynchronizedMultiSet synchronizedMultiSet(MultiSet p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multiset/UnmodifiableMultiSet.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multiset/UnmodifiableMultiSet.java new file mode 100644 index 00000000000..bbc88c25980 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/multiset/UnmodifiableMultiSet.java @@ -0,0 +1,30 @@ +// Generated automatically from org.apache.commons.collections4.multiset.UnmodifiableMultiSet for testing purposes + +package org.apache.commons.collections4.multiset; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; +import java.util.function.Predicate; +import org.apache.commons.collections4.MultiSet; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.multiset.AbstractMultiSetDecorator; + +public class UnmodifiableMultiSet extends AbstractMultiSetDecorator implements Unmodifiable +{ + protected UnmodifiableMultiSet() {} + public Iterator iterator(){ return null; } + public Set uniqueSet(){ return null; } + public Set> entrySet(){ return null; } + public boolean add(E p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public int add(E p0, int p1){ return 0; } + public int remove(Object p0, int p1){ return 0; } + public int setCount(E p0, int p1){ return 0; } + public static MultiSet unmodifiableMultiSet(MultiSet p0){ return null; } + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/properties/AbstractPropertiesFactory.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/properties/AbstractPropertiesFactory.java new file mode 100644 index 00000000000..022521fe923 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/properties/AbstractPropertiesFactory.java @@ -0,0 +1,25 @@ +// Generated automatically from org.apache.commons.collections4.properties.AbstractPropertiesFactory for testing purposes + +package org.apache.commons.collections4.properties; + +import java.io.File; +import java.io.InputStream; +import java.io.Reader; +import java.net.URI; +import java.net.URL; +import java.nio.file.Path; +import java.util.Properties; + +abstract public class AbstractPropertiesFactory +{ + protected AbstractPropertiesFactory(){} + protected abstract T createProperties(); + public T load(ClassLoader p0, String p1){ return null; } + public T load(File p0){ return null; } + public T load(InputStream p0){ return null; } + public T load(Path p0){ return null; } + public T load(Reader p0){ return null; } + public T load(String p0){ return null; } + public T load(URI p0){ return null; } + public T load(URL p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/AbstractQueueDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/AbstractQueueDecorator.java new file mode 100644 index 00000000000..effafa64f00 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/AbstractQueueDecorator.java @@ -0,0 +1,18 @@ +// Generated automatically from org.apache.commons.collections4.queue.AbstractQueueDecorator for testing purposes + +package org.apache.commons.collections4.queue; + +import java.util.Queue; +import org.apache.commons.collections4.collection.AbstractCollectionDecorator; + +abstract public class AbstractQueueDecorator extends AbstractCollectionDecorator implements Queue +{ + protected AbstractQueueDecorator(){} + protected AbstractQueueDecorator(Queue p0){} + protected Queue decorated(){ return null; } + public E element(){ return null; } + public E peek(){ return null; } + public E poll(){ return null; } + public E remove(){ return null; } + public boolean offer(E p0){ return false; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/CircularFifoQueue.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/CircularFifoQueue.java new file mode 100644 index 00000000000..9fcf239f945 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/CircularFifoQueue.java @@ -0,0 +1,31 @@ +// Generated automatically from org.apache.commons.collections4.queue.CircularFifoQueue for testing purposes + +package org.apache.commons.collections4.queue; + +import java.io.Serializable; +import java.util.AbstractCollection; +import java.util.Collection; +import java.util.Iterator; +import java.util.Queue; +import org.apache.commons.collections4.BoundedCollection; + +public class CircularFifoQueue extends AbstractCollection implements BoundedCollection, Queue, Serializable +{ + public CircularFifoQueue(){} + public CircularFifoQueue(Collection p0){} + public CircularFifoQueue(int p0){} + public E element(){ return null; } + public E get(int p0){ return null; } + public E peek(){ return null; } + public E poll(){ return null; } + public E remove(){ return null; } + public Iterator iterator(){ return null; } + public boolean add(E p0){ return false; } + public boolean isAtFullCapacity(){ return false; } + public boolean isEmpty(){ return false; } + public boolean isFull(){ return false; } + public boolean offer(E p0){ return false; } + public int maxSize(){ return 0; } + public int size(){ return 0; } + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/PredicatedQueue.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/PredicatedQueue.java new file mode 100644 index 00000000000..849cd890317 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/PredicatedQueue.java @@ -0,0 +1,20 @@ +// Generated automatically from org.apache.commons.collections4.queue.PredicatedQueue for testing purposes + +package org.apache.commons.collections4.queue; + +import java.util.Queue; +import org.apache.commons.collections4.Predicate; +import org.apache.commons.collections4.collection.PredicatedCollection; + +public class PredicatedQueue extends PredicatedCollection implements Queue +{ + protected PredicatedQueue() {} + protected PredicatedQueue(Queue p0, Predicate p1){} + protected Queue decorated(){ return null; } + public E element(){ return null; } + public E peek(){ return null; } + public E poll(){ return null; } + public E remove(){ return null; } + public boolean offer(E p0){ return false; } + public static PredicatedQueue predicatedQueue(Queue p0, Predicate p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/SynchronizedQueue.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/SynchronizedQueue.java new file mode 100644 index 00000000000..bd3d11053e8 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/SynchronizedQueue.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.commons.collections4.queue.SynchronizedQueue for testing purposes + +package org.apache.commons.collections4.queue; + +import java.util.Queue; +import org.apache.commons.collections4.collection.SynchronizedCollection; + +public class SynchronizedQueue extends SynchronizedCollection implements Queue +{ + protected SynchronizedQueue() {} + protected Queue decorated(){ return null; } + protected SynchronizedQueue(Queue p0){} + protected SynchronizedQueue(Queue p0, Object p1){} + public E element(){ return null; } + public E peek(){ return null; } + public E poll(){ return null; } + public E remove(){ return null; } + public boolean equals(Object p0){ return false; } + public boolean offer(E p0){ return false; } + public int hashCode(){ return 0; } + public static SynchronizedQueue synchronizedQueue(Queue p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/TransformedQueue.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/TransformedQueue.java new file mode 100644 index 00000000000..85ebb1aeac5 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/TransformedQueue.java @@ -0,0 +1,21 @@ +// Generated automatically from org.apache.commons.collections4.queue.TransformedQueue for testing purposes + +package org.apache.commons.collections4.queue; + +import java.util.Queue; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.collection.TransformedCollection; + +public class TransformedQueue extends TransformedCollection implements Queue +{ + protected TransformedQueue() {} + protected Queue getQueue(){ return null; } + protected TransformedQueue(Queue p0, Transformer p1){} + public E element(){ return null; } + public E peek(){ return null; } + public E poll(){ return null; } + public E remove(){ return null; } + public boolean offer(E p0){ return false; } + public static TransformedQueue transformedQueue(Queue p0, Transformer p1){ return null; } + public static TransformedQueue transformingQueue(Queue p0, Transformer p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/UnmodifiableQueue.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/UnmodifiableQueue.java new file mode 100644 index 00000000000..b119393e0c5 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/queue/UnmodifiableQueue.java @@ -0,0 +1,27 @@ +// Generated automatically from org.apache.commons.collections4.queue.UnmodifiableQueue for testing purposes + +package org.apache.commons.collections4.queue; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Queue; +import java.util.function.Predicate; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.queue.AbstractQueueDecorator; + +public class UnmodifiableQueue extends AbstractQueueDecorator implements Unmodifiable +{ + protected UnmodifiableQueue() {} + public E poll(){ return null; } + public E remove(){ return null; } + public Iterator iterator(){ return null; } + public boolean add(Object p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean offer(E p0){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public static Queue unmodifiableQueue(Queue p0){ return null; } + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/AbstractNavigableSetDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/AbstractNavigableSetDecorator.java new file mode 100644 index 00000000000..57c88ffd917 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/AbstractNavigableSetDecorator.java @@ -0,0 +1,25 @@ +// Generated automatically from org.apache.commons.collections4.set.AbstractNavigableSetDecorator for testing purposes + +package org.apache.commons.collections4.set; + +import java.util.Iterator; +import java.util.NavigableSet; +import org.apache.commons.collections4.set.AbstractSortedSetDecorator; + +abstract public class AbstractNavigableSetDecorator extends AbstractSortedSetDecorator implements NavigableSet +{ + protected AbstractNavigableSetDecorator(){} + protected AbstractNavigableSetDecorator(NavigableSet p0){} + protected NavigableSet decorated(){ return null; } + public E ceiling(E p0){ return null; } + public E floor(E p0){ return null; } + public E higher(E p0){ return null; } + public E lower(E p0){ return null; } + public E pollFirst(){ return null; } + public E pollLast(){ return null; } + public Iterator descendingIterator(){ return null; } + public NavigableSet descendingSet(){ return null; } + public NavigableSet headSet(E p0, boolean p1){ return null; } + public NavigableSet subSet(E p0, boolean p1, E p2, boolean p3){ return null; } + public NavigableSet tailSet(E p0, boolean p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/AbstractSerializableSetDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/AbstractSerializableSetDecorator.java new file mode 100644 index 00000000000..f2176a7d15a --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/AbstractSerializableSetDecorator.java @@ -0,0 +1,12 @@ +// Generated automatically from org.apache.commons.collections4.set.AbstractSerializableSetDecorator for testing purposes + +package org.apache.commons.collections4.set; + +import java.util.Set; +import org.apache.commons.collections4.set.AbstractSetDecorator; + +abstract public class AbstractSerializableSetDecorator extends AbstractSetDecorator +{ + protected AbstractSerializableSetDecorator() {} + protected AbstractSerializableSetDecorator(Set p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/AbstractSetDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/AbstractSetDecorator.java new file mode 100644 index 00000000000..57567c3079c --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/AbstractSetDecorator.java @@ -0,0 +1,15 @@ +// Generated automatically from org.apache.commons.collections4.set.AbstractSetDecorator for testing purposes + +package org.apache.commons.collections4.set; + +import java.util.Set; +import org.apache.commons.collections4.collection.AbstractCollectionDecorator; + +abstract public class AbstractSetDecorator extends AbstractCollectionDecorator implements Set +{ + protected AbstractSetDecorator(){} + protected AbstractSetDecorator(Set p0){} + protected Set decorated(){ return null; } + public boolean equals(Object p0){ return false; } + public int hashCode(){ return 0; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/AbstractSortedSetDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/AbstractSortedSetDecorator.java new file mode 100644 index 00000000000..e7d86052184 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/AbstractSortedSetDecorator.java @@ -0,0 +1,21 @@ +// Generated automatically from org.apache.commons.collections4.set.AbstractSortedSetDecorator for testing purposes + +package org.apache.commons.collections4.set; + +import java.util.Comparator; +import java.util.Set; +import java.util.SortedSet; +import org.apache.commons.collections4.set.AbstractSetDecorator; + +abstract public class AbstractSortedSetDecorator extends AbstractSetDecorator implements SortedSet +{ + protected AbstractSortedSetDecorator(){} + protected AbstractSortedSetDecorator(Set p0){} + protected SortedSet decorated(){ return null; } + public Comparator comparator(){ return null; } + public E first(){ return null; } + public E last(){ return null; } + public SortedSet headSet(E p0){ return null; } + public SortedSet subSet(E p0, E p1){ return null; } + public SortedSet tailSet(E p0){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/CompositeSet.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/CompositeSet.java new file mode 100644 index 00000000000..f315ea6f2c1 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/CompositeSet.java @@ -0,0 +1,47 @@ +// Generated automatically from org.apache.commons.collections4.set.CompositeSet for testing purposes + +package org.apache.commons.collections4.set; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; + +public class CompositeSet implements Serializable, Set +{ + protected CompositeSet.SetMutator getMutator(){ return null; } + public T[] toArray(T[] p0){ return null; } + public CompositeSet(){} + public CompositeSet(Set p0){} + public CompositeSet(Set... p0){} + public Iterator iterator(){ return null; } + public List> getSets(){ return null; } + public Object[] toArray(){ return null; } + public Set toSet(){ return null; } + public boolean add(E p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean contains(Object p0){ return false; } + public boolean containsAll(Collection p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public int hashCode(){ return 0; } + public int size(){ return 0; } + public void addComposited(Set p0){} + public void addComposited(Set p0, Set p1){} + public void addComposited(Set... p0){} + public void clear(){} + public void removeComposited(Set p0){} + public void setMutator(CompositeSet.SetMutator p0){} + static public interface SetMutator extends Serializable + { + boolean add(CompositeSet p0, List> p1, E p2); + boolean addAll(CompositeSet p0, List> p1, Collection p2); + void resolveCollision(CompositeSet p0, Set p1, Set p2, Collection p3); + } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/ListOrderedSet.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/ListOrderedSet.java new file mode 100644 index 00000000000..1bb18f7e2f4 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/ListOrderedSet.java @@ -0,0 +1,37 @@ +// Generated automatically from org.apache.commons.collections4.set.ListOrderedSet for testing purposes + +package org.apache.commons.collections4.set; + +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; +import org.apache.commons.collections4.OrderedIterator; +import org.apache.commons.collections4.set.AbstractSerializableSetDecorator; + +public class ListOrderedSet extends AbstractSerializableSetDecorator +{ + protected ListOrderedSet(Set p0){} + protected ListOrderedSet(Set p0, List p1){} + public T[] toArray(T[] p0){ return null; } + public E get(int p0){ return null; } + public E remove(int p0){ return null; } + public List asList(){ return null; } + public ListOrderedSet(){} + public Object[] toArray(){ return null; } + public OrderedIterator iterator(){ return null; } + public String toString(){ return null; } + public boolean add(E p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean addAll(int p0, Collection p1){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public int indexOf(Object p0){ return 0; } + public static ListOrderedSet listOrderedSet(List p0){ return null; } + public static ListOrderedSet listOrderedSet(Set p0){ return null; } + public static ListOrderedSet listOrderedSet(Set p0, List p1){ return null; } + public void add(int p0, E p1){} + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/MapBackedSet.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/MapBackedSet.java new file mode 100644 index 00000000000..50fb143966d --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/MapBackedSet.java @@ -0,0 +1,33 @@ +// Generated automatically from org.apache.commons.collections4.set.MapBackedSet for testing purposes + +package org.apache.commons.collections4.set; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; + +public class MapBackedSet implements Serializable, Set +{ + protected MapBackedSet() {} + public T[] toArray(T[] p0){ return null; } + public Iterator iterator(){ return null; } + public Object[] toArray(){ return null; } + public boolean add(E p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean contains(Object p0){ return false; } + public boolean containsAll(Collection p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public int hashCode(){ return 0; } + public int size(){ return 0; } + public static MapBackedSet mapBackedSet(Map p0){ return null; } + public static MapBackedSet mapBackedSet(Map p0, V p1){ return null; } + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/PredicatedNavigableSet.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/PredicatedNavigableSet.java new file mode 100644 index 00000000000..46248977046 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/PredicatedNavigableSet.java @@ -0,0 +1,27 @@ +// Generated automatically from org.apache.commons.collections4.set.PredicatedNavigableSet for testing purposes + +package org.apache.commons.collections4.set; + +import java.util.Iterator; +import java.util.NavigableSet; +import org.apache.commons.collections4.Predicate; +import org.apache.commons.collections4.set.PredicatedSortedSet; + +public class PredicatedNavigableSet extends PredicatedSortedSet implements NavigableSet +{ + protected PredicatedNavigableSet() {} + protected NavigableSet decorated(){ return null; } + protected PredicatedNavigableSet(NavigableSet p0, Predicate p1){} + public E ceiling(E p0){ return null; } + public E floor(E p0){ return null; } + public E higher(E p0){ return null; } + public E lower(E p0){ return null; } + public E pollFirst(){ return null; } + public E pollLast(){ return null; } + public Iterator descendingIterator(){ return null; } + public NavigableSet descendingSet(){ return null; } + public NavigableSet headSet(E p0, boolean p1){ return null; } + public NavigableSet subSet(E p0, boolean p1, E p2, boolean p3){ return null; } + public NavigableSet tailSet(E p0, boolean p1){ return null; } + public static PredicatedNavigableSet predicatedNavigableSet(NavigableSet p0, Predicate p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/PredicatedSet.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/PredicatedSet.java new file mode 100644 index 00000000000..98d3e7bb48c --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/PredicatedSet.java @@ -0,0 +1,17 @@ +// Generated automatically from org.apache.commons.collections4.set.PredicatedSet for testing purposes + +package org.apache.commons.collections4.set; + +import java.util.Set; +import org.apache.commons.collections4.Predicate; +import org.apache.commons.collections4.collection.PredicatedCollection; + +public class PredicatedSet extends PredicatedCollection implements Set +{ + protected PredicatedSet() {} + protected PredicatedSet(Set p0, Predicate p1){} + protected Set decorated(){ return null; } + public boolean equals(Object p0){ return false; } + public int hashCode(){ return 0; } + public static PredicatedSet predicatedSet(Set p0, Predicate p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/PredicatedSortedSet.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/PredicatedSortedSet.java new file mode 100644 index 00000000000..4eefa083a8b --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/PredicatedSortedSet.java @@ -0,0 +1,22 @@ +// Generated automatically from org.apache.commons.collections4.set.PredicatedSortedSet for testing purposes + +package org.apache.commons.collections4.set; + +import java.util.Comparator; +import java.util.SortedSet; +import org.apache.commons.collections4.Predicate; +import org.apache.commons.collections4.set.PredicatedSet; + +public class PredicatedSortedSet extends PredicatedSet implements SortedSet +{ + protected PredicatedSortedSet() {} + protected PredicatedSortedSet(SortedSet p0, Predicate p1){} + protected SortedSet decorated(){ return null; } + public Comparator comparator(){ return null; } + public E first(){ return null; } + public E last(){ return null; } + public SortedSet headSet(E p0){ return null; } + public SortedSet subSet(E p0, E p1){ return null; } + public SortedSet tailSet(E p0){ return null; } + public static PredicatedSortedSet predicatedSortedSet(SortedSet p0, Predicate p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/TransformedNavigableSet.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/TransformedNavigableSet.java new file mode 100644 index 00000000000..22afceeebf6 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/TransformedNavigableSet.java @@ -0,0 +1,28 @@ +// Generated automatically from org.apache.commons.collections4.set.TransformedNavigableSet for testing purposes + +package org.apache.commons.collections4.set; + +import java.util.Iterator; +import java.util.NavigableSet; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.set.TransformedSortedSet; + +public class TransformedNavigableSet extends TransformedSortedSet implements NavigableSet +{ + protected TransformedNavigableSet() {} + protected NavigableSet decorated(){ return null; } + protected TransformedNavigableSet(NavigableSet p0, Transformer p1){} + public E ceiling(E p0){ return null; } + public E floor(E p0){ return null; } + public E higher(E p0){ return null; } + public E lower(E p0){ return null; } + public E pollFirst(){ return null; } + public E pollLast(){ return null; } + public Iterator descendingIterator(){ return null; } + public NavigableSet descendingSet(){ return null; } + public NavigableSet headSet(E p0, boolean p1){ return null; } + public NavigableSet subSet(E p0, boolean p1, E p2, boolean p3){ return null; } + public NavigableSet tailSet(E p0, boolean p1){ return null; } + public static TransformedNavigableSet transformedNavigableSet(NavigableSet p0, Transformer p1){ return null; } + public static TransformedNavigableSet transformingNavigableSet(NavigableSet p0, Transformer p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/TransformedSet.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/TransformedSet.java new file mode 100644 index 00000000000..48f89ba97d9 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/TransformedSet.java @@ -0,0 +1,17 @@ +// Generated automatically from org.apache.commons.collections4.set.TransformedSet for testing purposes + +package org.apache.commons.collections4.set; + +import java.util.Set; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.collection.TransformedCollection; + +public class TransformedSet extends TransformedCollection implements Set +{ + protected TransformedSet() {} + protected TransformedSet(Set p0, Transformer p1){} + public boolean equals(Object p0){ return false; } + public int hashCode(){ return 0; } + public static Set transformedSet(Set p0, Transformer p1){ return null; } + public static TransformedSet transformingSet(Set p0, Transformer p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/TransformedSortedSet.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/TransformedSortedSet.java new file mode 100644 index 00000000000..d2af58ae7b9 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/TransformedSortedSet.java @@ -0,0 +1,23 @@ +// Generated automatically from org.apache.commons.collections4.set.TransformedSortedSet for testing purposes + +package org.apache.commons.collections4.set; + +import java.util.Comparator; +import java.util.SortedSet; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.set.TransformedSet; + +public class TransformedSortedSet extends TransformedSet implements SortedSet +{ + protected TransformedSortedSet() {} + protected SortedSet getSortedSet(){ return null; } + protected TransformedSortedSet(SortedSet p0, Transformer p1){} + public Comparator comparator(){ return null; } + public E first(){ return null; } + public E last(){ return null; } + public SortedSet headSet(E p0){ return null; } + public SortedSet subSet(E p0, E p1){ return null; } + public SortedSet tailSet(E p0){ return null; } + public static TransformedSortedSet transformedSortedSet(SortedSet p0, Transformer p1){ return null; } + public static TransformedSortedSet transformingSortedSet(SortedSet p0, Transformer p1){ return null; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/UnmodifiableNavigableSet.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/UnmodifiableNavigableSet.java new file mode 100644 index 00000000000..c8713196dcd --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/UnmodifiableNavigableSet.java @@ -0,0 +1,33 @@ +// Generated automatically from org.apache.commons.collections4.set.UnmodifiableNavigableSet for testing purposes + +package org.apache.commons.collections4.set; + +import java.util.Collection; +import java.util.Iterator; +import java.util.NavigableSet; +import java.util.SortedSet; +import java.util.function.Predicate; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.set.AbstractNavigableSetDecorator; + +public class UnmodifiableNavigableSet extends AbstractNavigableSetDecorator implements Unmodifiable +{ + protected UnmodifiableNavigableSet() {} + public Iterator descendingIterator(){ return null; } + public Iterator iterator(){ return null; } + public NavigableSet descendingSet(){ return null; } + public NavigableSet headSet(E p0, boolean p1){ return null; } + public NavigableSet subSet(E p0, boolean p1, E p2, boolean p3){ return null; } + public NavigableSet tailSet(E p0, boolean p1){ return null; } + public SortedSet headSet(E p0){ return null; } + public SortedSet subSet(E p0, E p1){ return null; } + public SortedSet tailSet(E p0){ return null; } + public boolean add(E p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public static NavigableSet unmodifiableNavigableSet(NavigableSet p0){ return null; } + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/UnmodifiableSet.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/UnmodifiableSet.java new file mode 100644 index 00000000000..f34de16e11d --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/UnmodifiableSet.java @@ -0,0 +1,24 @@ +// Generated automatically from org.apache.commons.collections4.set.UnmodifiableSet for testing purposes + +package org.apache.commons.collections4.set; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; +import java.util.function.Predicate; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.set.AbstractSerializableSetDecorator; + +public class UnmodifiableSet extends AbstractSerializableSetDecorator implements Unmodifiable +{ + protected UnmodifiableSet() {} + public Iterator iterator(){ return null; } + public boolean add(E p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public static Set unmodifiableSet(Set p0){ return null; } + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/UnmodifiableSortedSet.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/UnmodifiableSortedSet.java new file mode 100644 index 00000000000..7a70770cbd1 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/set/UnmodifiableSortedSet.java @@ -0,0 +1,27 @@ +// Generated automatically from org.apache.commons.collections4.set.UnmodifiableSortedSet for testing purposes + +package org.apache.commons.collections4.set; + +import java.util.Collection; +import java.util.Iterator; +import java.util.SortedSet; +import java.util.function.Predicate; +import org.apache.commons.collections4.Unmodifiable; +import org.apache.commons.collections4.set.AbstractSortedSetDecorator; + +public class UnmodifiableSortedSet extends AbstractSortedSetDecorator implements Unmodifiable +{ + protected UnmodifiableSortedSet() {} + public Iterator iterator(){ return null; } + public SortedSet headSet(E p0){ return null; } + public SortedSet subSet(E p0, E p1){ return null; } + public SortedSet tailSet(E p0){ return null; } + public boolean add(E p0){ return false; } + public boolean addAll(Collection p0){ return false; } + public boolean remove(Object p0){ return false; } + public boolean removeAll(Collection p0){ return false; } + public boolean removeIf(Predicate p0){ return false; } + public boolean retainAll(Collection p0){ return false; } + public static SortedSet unmodifiableSortedSet(SortedSet p0){ return null; } + public void clear(){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/splitmap/AbstractIterableGetMapDecorator.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/splitmap/AbstractIterableGetMapDecorator.java new file mode 100644 index 00000000000..fba230bba07 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/splitmap/AbstractIterableGetMapDecorator.java @@ -0,0 +1,29 @@ +// Generated automatically from org.apache.commons.collections4.splitmap.AbstractIterableGetMapDecorator for testing purposes + +package org.apache.commons.collections4.splitmap; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import org.apache.commons.collections4.IterableGet; +import org.apache.commons.collections4.MapIterator; + +public class AbstractIterableGetMapDecorator implements IterableGet +{ + protected AbstractIterableGetMapDecorator(){} + protected Map decorated(){ return null; } + public AbstractIterableGetMapDecorator(Map p0){} + public Collection values(){ return null; } + public MapIterator mapIterator(){ return null; } + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public String toString(){ return null; } + public V get(Object p0){ return null; } + public V remove(Object p0){ return null; } + public boolean containsKey(Object p0){ return false; } + public boolean containsValue(Object p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public int hashCode(){ return 0; } + public int size(){ return 0; } +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/splitmap/TransformedSplitMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/splitmap/TransformedSplitMap.java new file mode 100644 index 00000000000..4285142a482 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/splitmap/TransformedSplitMap.java @@ -0,0 +1,23 @@ +// Generated automatically from org.apache.commons.collections4.splitmap.TransformedSplitMap for testing purposes + +package org.apache.commons.collections4.splitmap; + +import java.io.Serializable; +import java.util.Map; +import org.apache.commons.collections4.Put; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.splitmap.AbstractIterableGetMapDecorator; + +public class TransformedSplitMap extends AbstractIterableGetMapDecorator implements Put, Serializable +{ + protected TransformedSplitMap() {} + protected K transformKey(J p0){ return null; } + protected Map transformMap(Map p0){ return null; } + protected TransformedSplitMap(Map p0, Transformer p1, Transformer p2){} + protected V checkSetValue(U p0){ return null; } + protected V transformValue(U p0){ return null; } + public V put(J p0, U p1){ return null; } + public static TransformedSplitMap transformingMap(Map p0, Transformer p1, Transformer p2){ return null; } + public void clear(){} + public void putAll(Map p0){} +} diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/trie/UnmodifiableTrie.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/trie/UnmodifiableTrie.java new file mode 100644 index 00000000000..829628ee63b --- /dev/null +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/trie/UnmodifiableTrie.java @@ -0,0 +1,45 @@ +// Generated automatically from org.apache.commons.collections4.trie.UnmodifiableTrie for testing purposes + +package org.apache.commons.collections4.trie; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Comparator; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import org.apache.commons.collections4.OrderedMapIterator; +import org.apache.commons.collections4.Trie; +import org.apache.commons.collections4.Unmodifiable; + +public class UnmodifiableTrie implements Serializable, Trie, Unmodifiable +{ + protected UnmodifiableTrie() {} + public Collection values(){ return null; } + public Comparator comparator(){ return null; } + public K firstKey(){ return null; } + public K lastKey(){ return null; } + public K nextKey(K p0){ return null; } + public K previousKey(K p0){ return null; } + public OrderedMapIterator mapIterator(){ return null; } + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public SortedMap headMap(K p0){ return null; } + public SortedMap prefixMap(K p0){ return null; } + public SortedMap subMap(K p0, K p1){ return null; } + public SortedMap tailMap(K p0){ return null; } + public String toString(){ return null; } + public UnmodifiableTrie(Trie p0){} + public V get(Object p0){ return null; } + public V put(K p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public boolean containsKey(Object p0){ return false; } + public boolean containsValue(Object p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public int hashCode(){ return 0; } + public int size(){ return 0; } + public static Trie unmodifiableTrie(Trie p0){ return null; } + public void clear(){} + public void putAll(Map p0){} +} diff --git a/java/ql/test/stubs/apache-commons-digester3-3.2/org/apache/commons/digester3/Digester.java b/java/ql/test/stubs/apache-commons-digester3-3.2/org/apache/commons/digester3/Digester.java new file mode 100644 index 00000000000..546aecbe521 --- /dev/null +++ b/java/ql/test/stubs/apache-commons-digester3-3.2/org/apache/commons/digester3/Digester.java @@ -0,0 +1,50 @@ +package org.apache.commons.digester3; + +import java.io.File; +import org.xml.sax.InputSource; +import java.io.Reader; +import java.net.URL; +import java.io.InputStream; +import java.io.IOException; +import org.xml.sax.SAXException; +import javax.xml.parsers.SAXParser; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.DefaultHandler; +import javax.xml.parsers.ParserConfigurationException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; + +public class Digester extends DefaultHandler { + + public Digester() { } + + public Digester(SAXParser parser) { } + + public Digester(XMLReader reader) { } + + public T parse(InputStream input) throws IOException, SAXException { + return null; + } + + public T parse(File file) throws IOException, SAXException { + return null; + } + + public T parse(InputSource input) throws IOException, SAXException { + return null; + } + + public T parse(Reader reader) throws IOException, SAXException { + return null; + } + + public T parse(String uri) throws IOException, SAXException { + return null; + } + + public T parse(URL url) throws IOException, SAXException { + return null; + } + + public void setFeature(String feature, boolean value) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException { } +} \ No newline at end of file diff --git a/java/ql/test/stubs/azure-sdk-for-java/com/azure/core/credential/TokenCredential.java b/java/ql/test/stubs/azure-sdk-for-java/com/azure/core/credential/TokenCredential.java new file mode 100644 index 00000000000..bacaa46a251 --- /dev/null +++ b/java/ql/test/stubs/azure-sdk-for-java/com/azure/core/credential/TokenCredential.java @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.core.credential; + +/** + * The interface for credentials that can provide a token. + */ +public interface TokenCredential { +} \ No newline at end of file diff --git a/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/AadCredentialBuilderBase.java b/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/AadCredentialBuilderBase.java new file mode 100644 index 00000000000..bedaab87e69 --- /dev/null +++ b/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/AadCredentialBuilderBase.java @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.identity; + +/** + * The base class for credential builders that allow specifying a client ID and tenant ID for an Azure Active Directory. + * @param the type of the credential builder + */ +public abstract class AadCredentialBuilderBase> extends CredentialBuilderBase { + + /** + * Specifies the Azure Active Directory endpoint to acquire tokens. + * @param authorityHost the Azure Active Directory endpoint + * @return An updated instance of this builder with the authority host set as specified. + */ + @SuppressWarnings("unchecked") + public T authorityHost(String authorityHost) { + return null; + } + + /** + * Sets the client ID of the application. + * + * @param clientId the client ID of the application. + * @return An updated instance of this builder with the client id set as specified. + */ + @SuppressWarnings("unchecked") + public T clientId(String clientId) { + return null; + } + + /** + * Sets the tenant ID of the application. + * + * @param tenantId the tenant ID of the application. + * @return An updated instance of this builder with the tenant id set as specified. + */ + @SuppressWarnings("unchecked") + public T tenantId(String tenantId) { + return null; + } +} \ No newline at end of file diff --git a/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/ClientSecretCredential.java b/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/ClientSecretCredential.java new file mode 100644 index 00000000000..9b8182451b8 --- /dev/null +++ b/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/ClientSecretCredential.java @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.identity; + +import com.azure.core.credential.TokenCredential; + +/** + * An AAD credential that acquires a token with a client secret for an AAD application. + * + *

    Sample: Construct a simple ClientSecretCredential

    + * {@codesnippet com.azure.identity.credential.clientsecretcredential.construct} + * + *

    Sample: Construct a ClientSecretCredential behind a proxy

    + * {@codesnippet com.azure.identity.credential.clientsecretcredential.constructwithproxy} + */ +public class ClientSecretCredential implements TokenCredential { +} diff --git a/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/ClientSecretCredentialBuilder.java b/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/ClientSecretCredentialBuilder.java new file mode 100644 index 00000000000..85ab73c3060 --- /dev/null +++ b/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/ClientSecretCredentialBuilder.java @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.identity; + +/** + * Fluent credential builder for instantiating a {@link ClientSecretCredential}. + * + * @see ClientSecretCredential + */ +public class ClientSecretCredentialBuilder extends AadCredentialBuilderBase { + /** + * Sets the client secret for the authentication. + * @param clientSecret the secret value of the AAD application. + * @return An updated instance of this builder. + */ + public ClientSecretCredentialBuilder clientSecret(String clientSecret) { + return null; + } + + /** + * Enables the shared token cache which is disabled by default. If enabled, the credential will store tokens + * in a cache persisted to the machine, protected to the current user, which can be shared by other credentials + * and processes. + * + * @return An updated instance of this builder. + */ + ClientSecretCredentialBuilder enablePersistentCache() { + return null; + } + + /** + * Allows to use an unprotected file specified by cacheFileLocation() instead of + * Gnome keyring on Linux. This is restricted by default. + * + * @return An updated instance of this builder. + */ + ClientSecretCredentialBuilder allowUnencryptedCache() { + return null; + } + + /** + * Configures the persistent shared token cache options and enables the persistent token cache which is disabled + * by default. If configured, the credential will store tokens in a cache persisted to the machine, protected to + * the current user, which can be shared by other credentials and processes. + * + * @param tokenCachePersistenceOptions the token cache configuration options + * @return An updated instance of this builder with the token cache options configured. + */ + public ClientSecretCredentialBuilder tokenCachePersistenceOptions(TokenCachePersistenceOptions + tokenCachePersistenceOptions) { + return null; + } + + /** + * Creates a new {@link ClientCertificateCredential} with the current configurations. + * + * @return a {@link ClientSecretCredentialBuilder} with the current configurations. + */ + public ClientSecretCredential build() { + return null; + } +} diff --git a/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/CredentialBuilderBase.java b/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/CredentialBuilderBase.java new file mode 100644 index 00000000000..c1210942ea0 --- /dev/null +++ b/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/CredentialBuilderBase.java @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.identity; + +/** + * The base class for all the credential builders. + * @param the type of the credential builder + */ +public abstract class CredentialBuilderBase> { + CredentialBuilderBase() { + } +} \ No newline at end of file diff --git a/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/TokenCachePersistenceOptions.java b/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/TokenCachePersistenceOptions.java new file mode 100644 index 00000000000..d5580fb05f6 --- /dev/null +++ b/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/TokenCachePersistenceOptions.java @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.identity; + +/** + * Represents the Persistence Token Cache options used to setup the persistent access token cache. + */ +public final class TokenCachePersistenceOptions { + + /** + * Allows to use an unprotected file specified by cacheFileLocation() instead of + * Gnome keyring on Linux. This is restricted by default. For other platforms this setting currently doesn't apply. + * + * @param unencryptedStorageAllowed The flag indicating if unencrypted storage is allowed for the cache or not. + * @return An updated instance of the options bag. + */ + public TokenCachePersistenceOptions setUnencryptedStorageAllowed(boolean unencryptedStorageAllowed) { + return null; + } + + /** + * Gets the status whether unencrypted storage is allowed for the persistent token cache. + * + * @return The status indicating if unencrypted storage is allowed for the persistent token cache. + */ + public boolean isUnencryptedStorageAllowed() { + return false; + } + + /** + * Set the name uniquely identifying the cache. + * + * @param name the name of the cache + * @return the updated instance of the cache. + */ + public TokenCachePersistenceOptions setName(String name) { + return null; + } + + /** + * Get the name uniquely identifying the cache. + * + * @return the name of the cache. + */ + public String getName() { + return null; + } +} diff --git a/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/UsernamePasswordCredential.java b/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/UsernamePasswordCredential.java new file mode 100644 index 00000000000..5cb9463eb95 --- /dev/null +++ b/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/UsernamePasswordCredential.java @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.identity; + +import com.azure.core.credential.TokenCredential; + +/** + * An AAD credential that acquires a token with a username and a password. Users with 2FA/MFA (Multi-factored auth) + * turned on will not be able to use this credential. Please use {@link DeviceCodeCredential} or {@link + * InteractiveBrowserCredential} instead, or create a service principal if you want to authenticate silently. + */ +public class UsernamePasswordCredential implements TokenCredential { +} diff --git a/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/UsernamePasswordCredentialBuilder.java b/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/UsernamePasswordCredentialBuilder.java new file mode 100644 index 00000000000..b6aa411ed84 --- /dev/null +++ b/java/ql/test/stubs/azure-sdk-for-java/com/azure/identity/UsernamePasswordCredentialBuilder.java @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.identity; + +import com.azure.security.keyvault.secrets.SecretClient; + +/** + * Fluent credential builder for instantiating a {@link UsernamePasswordCredential}. + * + * @see UsernamePasswordCredential + */ +public class UsernamePasswordCredentialBuilder extends AadCredentialBuilderBase { + /** + * Sets the username of the user. + * @param username the username of the user + * @return the UserCredentialBuilder itself + */ + public UsernamePasswordCredentialBuilder username(String username) { + return null; + } + + /** + * Sets the password of the user. + * @param password the password of the user + * @return the UserCredentialBuilder itself + */ + public UsernamePasswordCredentialBuilder password(String password) { + return null; + } + + /** + * Configures the persistent shared token cache options and enables the persistent token cache which is disabled + * by default. If configured, the credential will store tokens in a cache persisted to the machine, protected to + * the current user, which can be shared by other credentials and processes. + * + * @param tokenCachePersistenceOptions the token cache configuration options + * @return An updated instance of this builder with the token cache options configured. + */ + public UsernamePasswordCredentialBuilder tokenCachePersistenceOptions(TokenCachePersistenceOptions + tokenCachePersistenceOptions) { + return null; + } + + /** + * Allows to use an unprotected file specified by cacheFileLocation() instead of + * Gnome keyring on Linux. This is restricted by default. + * + * @return An updated instance of this builder. + */ + UsernamePasswordCredentialBuilder allowUnencryptedCache() { + return null; + } + + /** + * Enables the shared token cache which is disabled by default. If enabled, the credential will store tokens + * in a cache persisted to the machine, protected to the current user, which can be shared by other credentials + * and processes. + * + * @return An updated instance of this builder with if the shared token cache enabled specified. + */ + UsernamePasswordCredentialBuilder enablePersistentCache() { + return null; + } + + /** + * Creates a new {@link UsernamePasswordCredential} with the current configurations. + * + * @return a {@link UsernamePasswordCredential} with the current configurations. + */ + public UsernamePasswordCredential build() { + return null; + } +} diff --git a/java/ql/test/stubs/azure-sdk-for-java/com/azure/security/keyvault/secrets/SecretClient.java b/java/ql/test/stubs/azure-sdk-for-java/com/azure/security/keyvault/secrets/SecretClient.java new file mode 100644 index 00000000000..94cdc7d1be7 --- /dev/null +++ b/java/ql/test/stubs/azure-sdk-for-java/com/azure/security/keyvault/secrets/SecretClient.java @@ -0,0 +1,155 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.security.keyvault.secrets; + +import com.azure.security.keyvault.secrets.models.KeyVaultSecret; +import com.azure.security.keyvault.secrets.models.SecretProperties; + +/** + * The SecretClient provides synchronous methods to manage {@link KeyVaultSecret secrets} in the Azure Key Vault. The client + * supports creating, retrieving, updating, deleting, purging, backing up, restoring, and listing the {@link KeyVaultSecret + * secrets}. The client also supports listing {@link DeletedSecret deleted secrets} for a soft-delete enabled Azure Key + * Vault. + * + *

    Construct the sync client

    + * {@codesnippet com.azure.security.keyvault.secretclient.sync.construct} + * + * @see SecretClientBuilder + * @see PagedIterable + */ +public final class SecretClient { + + /** + * Gets the vault endpoint url to which service requests are sent to. + * @return the vault endpoint url. + */ + public String getVaultUrl() { + return null; + } + + /** + * Adds a secret to the key vault if it does not exist. If the named secret exists, a new version of the secret is + * created. This operation requires the {@code secrets/set} permission. + * + *

    The {@link SecretProperties#getExpiresOn() expires}, {@link SecretProperties#getContentType() contentType}, + * and {@link SecretProperties#getNotBefore() notBefore} values in {@code secret} are optional. + * If not specified, {@link SecretProperties#isEnabled() enabled} is set to true by key vault.

    + * + *

    Code sample

    + *

    Creates a new secret in the key vault. Prints out the details of the newly created secret returned in the + * response.

    + * {@codesnippet com.azure.security.keyvault.secretclient.setSecret#secret} + * + * @param secret The Secret object containing information about the secret and its properties. The properties + * {@link KeyVaultSecret#getName() secret.name} and {@link KeyVaultSecret#getValue() secret.value} cannot be + * null. + * @return The {@link KeyVaultSecret created secret}. + * @throws NullPointerException if {@code secret} is {@code null}. + * @throws ResourceModifiedException if {@code secret} is malformed. + * @throws HttpResponseException if {@link KeyVaultSecret#getName() name} or {@link KeyVaultSecret#getValue() value} + * is an empty string. + */ + public KeyVaultSecret setSecret(KeyVaultSecret secret) { + return null; + } + + /** + * Adds a secret to the key vault if it does not exist. If the named secret exists, a new version of the secret is + * created. This operation requires the {@code secrets/set} permission. + * + *

    Code sample

    + *

    Creates a new secret in the key vault. Prints out the details of the newly created secret returned in the + * response.

    + * {@codesnippet com.azure.security.keyvault.secretclient.setSecret#string-string} + * + * @param name The name of the secret. It is required and cannot be null. + * @param value The value of the secret. It is required and cannot be null. + * @return The {@link KeyVaultSecret created secret}. + * @throws ResourceModifiedException if invalid {@code name} or {@code value} is specified. + * @throws HttpResponseException if {@code name} or {@code value} is empty string. + */ + public KeyVaultSecret setSecret(String name, String value) { + return null; + } + + /** + * Gets the specified secret with specified version from the key vault. This operation requires the + * {@code secrets/get} permission. + * + *

    Code sample

    + *

    Gets a specific version of the secret in the key vault. Prints out the details of the returned secret.

    + * {@codesnippet com.azure.security.keyvault.secretclient.getSecret#string-string} + * + * @param name The name of the secret, cannot be null. + * @param version The version of the secret to retrieve. If this is an empty string or null, this call is + * equivalent to calling {@link #getSecret(String)}, with the latest version being retrieved. + * @return The requested {@link KeyVaultSecret secret}. + * @throws ResourceNotFoundException when a secret with {@code name} and {@code version} doesn't exist in the + * key vault. + * @throws HttpResponseException if {@code name} or {@code version} is empty string. + */ + public KeyVaultSecret getSecret(String name, String version) { + return null; + } + + /** + * Gets the latest version of the specified secret from the key vault. + * This operation requires the {@code secrets/get} permission. + * + *

    Code sample

    + *

    Gets the latest version of the secret in the key vault. Prints out the details of the returned secret.

    + * {@codesnippet com.azure.security.keyvault.secretclient.getSecret#string} + * + * @param name The name of the secret. + * @return The requested {@link KeyVaultSecret}. + * @throws ResourceNotFoundException when a secret with {@code name} doesn't exist in the key vault. + * @throws HttpResponseException if {@code name} is empty string. + */ + public KeyVaultSecret getSecret(String name) { + return null; + } + + /** + * Updates the attributes associated with the secret. The value of the secret in the key vault cannot be changed. + * Only attributes populated in {@code secretProperties} are changed. Attributes not specified in the request are + * not changed. This operation requires the {@code secrets/set} permission. + * + *

    The {@code secret} is required and its fields {@link SecretProperties#getName() name} and + * {@link SecretProperties#getVersion() version} cannot be null.

    + * + *

    Code sample

    + *

    Gets the latest version of the secret, changes its expiry time, and the updates the secret in the key + * vault.

    + * {@codesnippet com.azure.security.keyvault.secretclient.updateSecretProperties#secretProperties} + * + * @param secretProperties The {@link SecretProperties secret properties} object with updated properties. + * @return The {@link SecretProperties updated secret}. + * @throws NullPointerException if {@code secret} is {@code null}. + * @throws ResourceNotFoundException when a secret with {@link SecretProperties#getName() name} and {@link + * SecretProperties#getVersion() version} doesn't exist in the key vault. + * @throws HttpResponseException if {@link SecretProperties#getName() name} or {@link SecretProperties#getVersion() version} is + * empty string. + */ + public SecretProperties updateSecretProperties(SecretProperties secretProperties) { + return null; + } + + /** + * Requests a backup of the secret be downloaded to the client. All versions of the secret will be downloaded. + * This operation requires the {@code secrets/backup} permission. + * + *

    Code sample

    + *

    Backs up the secret from the key vault and prints out the length of the secret's backup byte array returned in + * the response

    + * {@codesnippet com.azure.security.keyvault.secretclient.backupSecret#string} + * + * @param name The name of the secret. + * @return A {@link Response} whose {@link Response#getValue() value} contains the backed up secret blob. + * @throws ResourceNotFoundException when a secret with {@code name} doesn't exist in the key vault. + * @throws HttpResponseException when a secret with {@code name} is empty string. + */ + public byte[] backupSecret(String name) { + return null; + } +} diff --git a/java/ql/test/stubs/azure-sdk-for-java/com/azure/security/keyvault/secrets/SecretClientBuilder.java b/java/ql/test/stubs/azure-sdk-for-java/com/azure/security/keyvault/secrets/SecretClientBuilder.java new file mode 100644 index 00000000000..0a90f44f8dd --- /dev/null +++ b/java/ql/test/stubs/azure-sdk-for-java/com/azure/security/keyvault/secrets/SecretClientBuilder.java @@ -0,0 +1,92 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.security.keyvault.secrets; + +import com.azure.core.credential.TokenCredential; + +/** + * This class provides a fluent builder API to help aid the configuration and instantiation of the {@link + * SecretAsyncClient secret async client} and {@link SecretClient secret client}, + * by calling {@link SecretClientBuilder#buildAsyncClient() buildAsyncClient} and {@link + * SecretClientBuilder#buildClient() buildClient} respectively. + * It constructs an instance of the desired client. + * + *

    The minimal configuration options required by {@link SecretClientBuilder secretClientBuilder} to build + * {@link SecretAsyncClient} are {@link String vaultUrl} and {@link TokenCredential credential}.

    + * + * {@codesnippet com.azure.security.keyvault.secrets.async.secretclient.construct} + * + *

    Samples to construct the sync client

    + * {@codesnippet com.azure.security.keyvault.secretclient.sync.construct} + * + *

    The {@link HttpLogDetailLevel log detail level}, multiple custom {@link HttpLoggingPolicy policies} and custom + * {@link HttpClient http client} can be optionally configured in the {@link SecretClientBuilder}.

    + * + * {@codesnippet com.azure.security.keyvault.secrets.async.secretclient.withhttpclient.instantiation} + * + *

    Alternatively, custom {@link HttpPipeline http pipeline} with custom {@link HttpPipelinePolicy} policies and + * {@link String vaultUrl} + * can be specified. It provides finer control over the construction of {@link SecretAsyncClient client}

    + * + * {@codesnippet com.azure.security.keyvault.secrets.async.secretclient.pipeline.instantiation} + * + * @see SecretClient + * @see SecretAsyncClient + */ +public final class SecretClientBuilder { + /** + * The constructor with defaults. + */ + public SecretClientBuilder() { + } + + /** + * Creates a {@link SecretClient} based on options set in the builder. + * Every time {@code buildClient()} is called, a new instance of {@link SecretClient} is created. + * + *

    If {@link SecretClientBuilder#pipeline(HttpPipeline) pipeline} is set, then the {@code pipeline} and + * {@link SecretClientBuilder#vaultUrl(String) serviceEndpoint} are used to create the + * {@link SecretClientBuilder client}. All other builder settings are ignored. If {@code pipeline} is not set, + * then {@link SecretClientBuilder#credential(TokenCredential) key vault credential}, and + * {@link SecretClientBuilder#vaultUrl(String)} key vault url are required to build the {@link SecretClient + * client}.

    + * + * @return A {@link SecretClient} with the options set from the builder. + * + * @throws IllegalStateException If {@link SecretClientBuilder#credential(TokenCredential)} or + * {@link SecretClientBuilder#vaultUrl(String)} have not been set. + */ + public SecretClient buildClient() { + return null; + } + + /** + * Sets the vault URL to send HTTP requests to. + * + * @param vaultUrl The vault url is used as destination on Azure to send requests to. If you have a secret + * identifier, create a new {@link KeyVaultSecretIdentifier} to parse it and obtain the {@code vaultUrl} and + * other information. + * + * @return The updated {@link SecretClientBuilder} object. + * + * @throws IllegalArgumentException If {@code vaultUrl} is null or it cannot be parsed into a valid URL. + * @throws NullPointerException If {@code vaultUrl} is {@code null}. + */ + public SecretClientBuilder vaultUrl(String vaultUrl) { + return null; + } + + /** + * Sets the credential to use when authenticating HTTP requests. + * + * @param credential The credential to use for authenticating HTTP requests. + * + * @return The updated {@link SecretClientBuilder} object. + * + * @throws NullPointerException If {@code credential} is {@code null}. + */ + public SecretClientBuilder credential(TokenCredential credential) { + return null; + } +} diff --git a/java/ql/test/stubs/azure-sdk-for-java/com/azure/security/keyvault/secrets/models/KeyVaultSecret.java b/java/ql/test/stubs/azure-sdk-for-java/com/azure/security/keyvault/secrets/models/KeyVaultSecret.java new file mode 100644 index 00000000000..1f2f252a323 --- /dev/null +++ b/java/ql/test/stubs/azure-sdk-for-java/com/azure/security/keyvault/secrets/models/KeyVaultSecret.java @@ -0,0 +1,78 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.security.keyvault.secrets.models; + +import com.azure.security.keyvault.secrets.SecretClient; + +import java.util.Map; +import java.util.Objects; + +/** + * Secret is the resource consisting of name, value and its attributes specified in {@link SecretProperties}. + * It is managed by Secret Service. + * + * @see SecretClient + * @see SecretAsyncClient + */ +public class KeyVaultSecret { + /** + * Creates an empty instance of the Secret. + */ + KeyVaultSecret() { + } + + /** + * Creates a Secret with {@code name} and {@code value}. + * + * @param name The name of the secret. + * @param value the value of the secret. + */ + public KeyVaultSecret(String name, String value) { + } + + /** + * Get the value of the secret. + * + * @return the secret value + */ + public String getValue() { + return null; + } + + /** + * Get the secret identifier. + * + * @return the secret identifier. + */ + public String getId() { + return null; + } + + /** + * Get the secret name. + * + * @return the secret name. + */ + public String getName() { + return null; + } + + /** + * Get the secret properties + * @return the Secret properties + */ + public SecretProperties getProperties() { + return null; + } + + /** + * Set the secret properties + * @param properties The Secret properties + * @throws NullPointerException if {@code properties} is null. + * @return the updated secret object + */ + public KeyVaultSecret setProperties(SecretProperties properties) { + return null; + } +} diff --git a/java/ql/test/stubs/azure-sdk-for-java/com/azure/security/keyvault/secrets/models/SecretProperties.java b/java/ql/test/stubs/azure-sdk-for-java/com/azure/security/keyvault/secrets/models/SecretProperties.java new file mode 100644 index 00000000000..750db3ff177 --- /dev/null +++ b/java/ql/test/stubs/azure-sdk-for-java/com/azure/security/keyvault/secrets/models/SecretProperties.java @@ -0,0 +1,145 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.security.keyvault.secrets.models; + +import java.util.Map; + +import com.azure.security.keyvault.secrets.SecretClient; + +/** + * SecretProperties is the resource containing all the properties of the secret except its value. + * It is managed by the Secret Service. + * + * @see SecretClient + * @see SecretAsyncClient + */ +public class SecretProperties { + SecretProperties(String secretName) { + } + + /** + * Creates empty instance of SecretProperties. + */ + public SecretProperties() { } + + /** + * Get the secret name. + * + * @return the name of the secret. + */ + public String getName() { + return null; + } + + /** + * Get the recovery level of the secret. + + * @return the recoveryLevel of the secret. + */ + public String getRecoveryLevel() { + return null; + } + + /** + * Get the enabled value. + * + * @return the enabled value + */ + public Boolean isEnabled() { + return false; + } + + /** + * Set the enabled value. + * + * @param enabled The enabled value to set + * @throws NullPointerException if {@code enabled} is null. + * @return the SecretProperties object itself. + */ + public SecretProperties setEnabled(Boolean enabled) { + return null; + } + + /** + * Get the secret identifier. + * + * @return the secret identifier. + */ + public String getId() { + return null; + } + + /** + * Get the content type. + * + * @return the content type. + */ + public String getContentType() { + return null; + } + + /** + * Set the contentType. + * + * @param contentType The contentType to set + * @return the updated SecretProperties object itself. + */ + public SecretProperties setContentType(String contentType) { + return null; + } + + /** + * Get the tags associated with the secret. + * + * @return the value of the tags. + */ + public Map getTags() { + return null; + } + + /** + * Set the tags to be associated with the secret. + * + * @param tags The tags to set + * @return the updated SecretProperties object itself. + */ + public SecretProperties setTags(Map tags) { + return null; + } + + /** + * Get the keyId identifier. + * + * @return the keyId identifier. + */ + public String getKeyId() { + return null; + } + + /** + * Get the managed value. + * + * @return the managed value + */ + public Boolean isManaged() { + return null; + } + + /** + * Get the version of the secret. + * + * @return the version of the secret. + */ + public String getVersion() { + return null; + } + + /** + * Gets the number of days a secret is retained before being deleted for a soft delete-enabled Key Vault. + * @return the recoverable days. + */ + public Integer getRecoverableDays() { + return null; + } +} diff --git a/java/ql/test/stubs/dom4j-2.1.1/org/dom4j/DocumentException.java b/java/ql/test/stubs/dom4j-2.1.1/org/dom4j/DocumentException.java new file mode 100644 index 00000000000..2afcfe6e3cd --- /dev/null +++ b/java/ql/test/stubs/dom4j-2.1.1/org/dom4j/DocumentException.java @@ -0,0 +1,24 @@ +package org.dom4j; + +public class DocumentException extends Exception { + public DocumentException() { + } + + public DocumentException(String message) { + super(message); + } + + public DocumentException(String message, Throwable cause) { + super(message, cause); + } + + public DocumentException(Throwable cause) { + super(cause); + } + + /** @deprecated */ + @Deprecated + public Throwable getNestedException() { + return null; + } +} diff --git a/java/ql/test/stubs/dom4j-2.1.1/org/dom4j/DocumentHelper.java b/java/ql/test/stubs/dom4j-2.1.1/org/dom4j/DocumentHelper.java index 669dbfa9e9b..65254265774 100644 --- a/java/ql/test/stubs/dom4j-2.1.1/org/dom4j/DocumentHelper.java +++ b/java/ql/test/stubs/dom4j-2.1.1/org/dom4j/DocumentHelper.java @@ -69,6 +69,9 @@ public final class DocumentHelper { return null; } + public static Document parseText(String text) throws DocumentException { + return null; + } } /* diff --git a/java/ql/test/stubs/flexjson-2.1/flexjson/JSONDeserializer.java b/java/ql/test/stubs/flexjson-2.1/flexjson/JSONDeserializer.java new file mode 100644 index 00000000000..f165b51bd49 --- /dev/null +++ b/java/ql/test/stubs/flexjson-2.1/flexjson/JSONDeserializer.java @@ -0,0 +1,121 @@ +package flexjson; + +import java.io.Reader; + +public class JSONDeserializer { + + public JSONDeserializer() { + } + + /** + * Deserialize the given json formatted input into a Java object. + * + * @param input a json formatted string. + * @return an Java instance deserialized from the json input. + */ + public T deserialize( String input ) { + return null; + } + + /** + * Same as {@link #deserialize(String)}, but uses an instance of + * java.io.Reader as json input. + * + * @param input the stream where the json input is coming from. + * @return an Java instance deserialized from the java.io.Reader's input. + */ + public T deserialize( Reader input ) { + return null; + } + + /** + * Deserialize the given json input, and use the given Class as + * the type of the initial object to deserialize into. This object + * must implement a no-arg constructor. + * + * @param input a json formatted string. + * @param root a Class used to create the initial object. + * @return the object created from the given json input. + */ + public T deserialize( String input, Class root ) { + return null; + } + + /** + * Same as {@link #deserialize(java.io.Reader, Class)}, but uses an instance of + * java.io.Reader as json input. + * + * @param input the stream where the json input is coming from. + * @param root a Class used to create the initial object. + * @return an Java instance deserialized from the java.io.Reader's input. + */ + public T deserialize( Reader input, Class root ) { + return null; + } + + /** + * Deserialize the given json input, and use the given ObjectFactory to + * create the initial object to deserialize into. + * + * @param input a json formatted string. + * @param factory an ObjectFactory used to create the initial object. + * @return the object created from the given json input. + */ + public T deserialize( String input, ObjectFactory factory ) { + return null; + } + + /** + * Same as {@link #deserialize(String, ObjectFactory)}, but uses an instance of + * java.io.Reader as json input. + * + * @param input the stream where the json input is coming from. + * @param factory an ObjectFactory used to create the initial object. + * @return an Java instance deserialized from the java.io.Reader's input. + */ + public T deserialize( Reader input, ObjectFactory factory ) { + return null; + } + + /** + * Deserialize the given input into the existing object target. + * Values in the json input will overwrite values in the + * target object. This means if a value is included in json + * a new object will be created and set into the existing object. + * + * @param input a json formatted string. + * @param target an instance to set values into from the json string. + * @return will return a reference to target. + */ + public T deserializeInto( String input, T target ) { + return null; + } + + /** + * Same as {@link #deserializeInto(String, Object)}, but uses an instance of + * java.io.Reader as json input. + * + * @param input the stream where the json input is coming from. + * @param target an instance to set values into from the json string. + * @return will return a reference to target. + */ + public T deserializeInto( Reader input, T target ) { + return null; + } + + public JSONDeserializer use( String path, Class clazz ) { + return null; + } + + public JSONDeserializer use( Class clazz, ObjectFactory factory ) { + return null; + } + + public JSONDeserializer use( String path, ObjectFactory factory ) { + return null; + } + + public JSONDeserializer use(ObjectFactory factory, String... paths) { + return null; + } +} diff --git a/java/ql/test/stubs/flexjson-2.1/flexjson/ObjectBinder.java b/java/ql/test/stubs/flexjson-2.1/flexjson/ObjectBinder.java new file mode 100644 index 00000000000..efb648971dc --- /dev/null +++ b/java/ql/test/stubs/flexjson-2.1/flexjson/ObjectBinder.java @@ -0,0 +1,40 @@ +package flexjson; + +import java.lang.reflect.Type; + +import java.util.Map; +import java.util.Collection; + +public class ObjectBinder { + + public ObjectBinder() { + } + + public ObjectBinder use(Class clazz, ObjectFactory factory) { + return null; + } + + public Object bind( Object input ) { + return null; + } + + public Object bind( Object source, Object target ) { + return null; + } + + public Object bind( Object input, Type targetType ) { + return null; + } + + public > T bindIntoCollection(Collection value, T target, Type targetType) { + return null; + } + + public Object bindIntoMap(Map input, Map result, Type keyType, Type valueType) { + return null; + } + + public Object bindIntoObject(Map jsonOwner, Object target, Type targetType) { + return null; + } +} diff --git a/java/ql/test/stubs/flexjson-2.1/flexjson/ObjectFactory.java b/java/ql/test/stubs/flexjson-2.1/flexjson/ObjectFactory.java new file mode 100644 index 00000000000..87989d29947 --- /dev/null +++ b/java/ql/test/stubs/flexjson-2.1/flexjson/ObjectFactory.java @@ -0,0 +1,26 @@ +package flexjson; + +import java.lang.reflect.Type; + +/** + * ObjectFactory allows you to instantiate specific types of objects on path or class types. This interface allows + * you to override the default rules. + */ +public interface ObjectFactory { + /** + * This method is called by the deserializer to construct and bind an object. At the end of this method + * the object should be fully constructed. {@link flexjson.ObjectBinder} can be used to bind values into + * the object according to default rules. For simple implementations you won't need to use this, but + * for more complex or generic objects reusing methods like {@link flexjson.ObjectBinder#bind(Object, java.lang.reflect.Type)} + * and {@link flexjson.ObjectBinder#bindIntoCollection(java.util.Collection, java.util.Collection, java.lang.reflect.Type)}. + * + * @param context the object binding context to keep track of where we are in the object graph + * and used for binding into objects. + * @param value This is the value from the json object at the current path. + * @param targetType This is the type pulled from the object introspector. Used for Collections and generic types. + * @param targetClass concrete class pulled from the configuration of the deserializer. + * + * @return the fully bound object. At the end of this method the object should be fully constructed. + */ + public Object instantiate(ObjectBinder context, Object value, Type targetType, Class targetClass); +} diff --git a/java/ql/test/stubs/flexjson-2.1/flexjson/factories/ExistingObjectFactory.java b/java/ql/test/stubs/flexjson-2.1/flexjson/factories/ExistingObjectFactory.java new file mode 100644 index 00000000000..eab94681557 --- /dev/null +++ b/java/ql/test/stubs/flexjson-2.1/flexjson/factories/ExistingObjectFactory.java @@ -0,0 +1,17 @@ +package flexjson.factories; + +import flexjson.ObjectBinder; +import flexjson.ObjectFactory; + +import java.lang.reflect.Type; + +public class ExistingObjectFactory implements ObjectFactory { + + public ExistingObjectFactory(Object source) { + } + + @Override + public Object instantiate(ObjectBinder context, Object value, Type targetType, Class targetClass) { + return null; + } +} \ No newline at end of file diff --git a/java/ql/test/stubs/google-android-9.0.0/android/annotation/Nullable.java b/java/ql/test/stubs/google-android-9.0.0/android/annotation/Nullable.java new file mode 100644 index 00000000000..95b4a1cf9dc --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/annotation/Nullable.java @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package android.annotation; + +public @interface Nullable { +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/app/Activity.java b/java/ql/test/stubs/google-android-9.0.0/android/app/Activity.java index e04f68a203d..99b797fb2a8 100644 --- a/java/ql/test/stubs/google-android-9.0.0/android/app/Activity.java +++ b/java/ql/test/stubs/google-android-9.0.0/android/app/Activity.java @@ -15,6 +15,8 @@ */ package android.app; +import android.content.Context; +import android.content.ContextWrapper; import android.content.Intent; import android.os.Bundle; import android.view.View; @@ -675,7 +677,16 @@ import android.view.View; * upload, independent of whether the original activity is paused, stopped, or * finished. */ -public class Activity { +public class Activity extends ContextWrapper { + /** Standard activity result: operation canceled. */ + public static final int RESULT_CANCELED = 0; + + /** Standard activity result: operation succeeded. */ + public static final int RESULT_OK = -1; + + /** Start of user-defined activity results. */ + public static final int RESULT_FIRST_USER = 1; + /** Return the intent that started this activity. */ public Intent getIntent() { return null; @@ -1142,4 +1153,37 @@ public class Activity { */ public void startActivities(Intent[] intents, Bundle options) { } + + /** + * Called when an activity you launched exits, giving you the requestCode + * you started it with, the resultCode it returned, and any additional + * data from it. The resultCode will be + * {@link #RESULT_CANCELED} if the activity explicitly returned that, + * didn't return any result, or crashed during its operation. + * + *

    An activity can never receive a result in the resumed state. You can count on + * {@link #onResume} being called after this method, though not necessarily immediately after. + * If the activity was resumed, it will be paused and the result will be delivered, followed + * by {@link #onResume}. If the activity wasn't in the resumed state, then the result will + * be delivered, with {@link #onResume} called sometime later when the activity becomes active + * again. + * + *

    This method is never invoked if your activity sets + * {@link android.R.styleable#AndroidManifestActivity_noHistory noHistory} to + * true. + * + * @param requestCode The integer request code originally supplied to + * startActivityForResult(), allowing you to identify who this + * result came from. + * @param resultCode The integer result code returned by the child activity + * through its setResult(). + * @param data An Intent, which can return result data to the caller + * (various data can be attached to Intent "extras"). + * + * @see #startActivityForResult + * @see #createPendingResult + * @see #setResult(int) + */ + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + } } diff --git a/java/ql/test/stubs/google-android-9.0.0/android/app/Service.java b/java/ql/test/stubs/google-android-9.0.0/android/app/Service.java new file mode 100644 index 00000000000..370d7c5e4fe --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/app/Service.java @@ -0,0 +1,344 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.app; + +import android.content.Intent; +import android.content.ContextWrapper; + +/** + * A Service is an application component representing either an application's desire + * to perform a longer-running operation while not interacting with the user + * or to supply functionality for other applications to use. Each service + * class must have a corresponding + * {@link android.R.styleable#AndroidManifestService <service>} + * declaration in its package's AndroidManifest.xml. Services + * can be started with + * {@link android.content.Context#startService Context.startService()} and + * {@link android.content.Context#bindService Context.bindService()}. + * + *

    Note that services, like other application objects, run in the main + * thread of their hosting process. This means that, if your service is going + * to do any CPU intensive (such as MP3 playback) or blocking (such as + * networking) operations, it should spawn its own thread in which to do that + * work. More information on this can be found in + * Processes and + * Threads. The {@link IntentService} class is available + * as a standard implementation of Service that has its own thread where it + * schedules its work to be done.

    + * + *

    Topics covered here: + *

      + *
    1. What is a Service? + *
    2. Service Lifecycle + *
    3. Permissions + *
    4. Process Lifecycle + *
    5. Local Service Sample + *
    6. Remote Messenger Service Sample + *
    + * + *
    + *

    Developer Guides

    + *

    For a detailed discussion about how to create services, read the + * Services developer guide.

    + *
    + * + * + *

    What is a Service?

    + * + *

    Most confusion about the Service class actually revolves around what + * it is not:

    + * + *
      + *
    • A Service is not a separate process. The Service object itself + * does not imply it is running in its own process; unless otherwise specified, + * it runs in the same process as the application it is part of. + *
    • A Service is not a thread. It is not a means itself to do work off + * of the main thread (to avoid Application Not Responding errors). + *
    + * + *

    Thus a Service itself is actually very simple, providing two main features:

    + * + *
      + *
    • A facility for the application to tell the system about + * something it wants to be doing in the background (even when the user is not + * directly interacting with the application). This corresponds to calls to + * {@link android.content.Context#startService Context.startService()}, which + * ask the system to schedule work for the service, to be run until the service + * or someone else explicitly stop it. + *
    • A facility for an application to expose some of its functionality to + * other applications. This corresponds to calls to + * {@link android.content.Context#bindService Context.bindService()}, which + * allows a long-standing connection to be made to the service in order to + * interact with it. + *
    + * + *

    When a Service component is actually created, for either of these reasons, + * all that the system actually does is instantiate the component + * and call its {@link #onCreate} and any other appropriate callbacks on the + * main thread. It is up to the Service to implement these with the appropriate + * behavior, such as creating a secondary thread in which it does its work.

    + * + *

    Note that because Service itself is so simple, you can make your + * interaction with it as simple or complicated as you want: from treating it + * as a local Java object that you make direct method calls on (as illustrated + * by Local Service Sample), to providing + * a full remoteable interface using AIDL.

    + * + * + *

    Service Lifecycle

    + * + *

    There are two reasons that a service can be run by the system. If someone + * calls {@link android.content.Context#startService Context.startService()} then the system will + * retrieve the service (creating it and calling its {@link #onCreate} method + * if needed) and then call its {@link #onStartCommand} method with the + * arguments supplied by the client. The service will at this point continue + * running until {@link android.content.Context#stopService Context.stopService()} or + * {@link #stopSelf()} is called. Note that multiple calls to + * Context.startService() do not nest (though they do result in multiple corresponding + * calls to onStartCommand()), so no matter how many times it is started a service + * will be stopped once Context.stopService() or stopSelf() is called; however, + * services can use their {@link #stopSelf(int)} method to ensure the service is + * not stopped until started intents have been processed. + * + *

    For started services, there are two additional major modes of operation + * they can decide to run in, depending on the value they return from + * onStartCommand(): {@link #START_STICKY} is used for services that are + * explicitly started and stopped as needed, while {@link #START_NOT_STICKY} + * or {@link #START_REDELIVER_INTENT} are used for services that should only + * remain running while processing any commands sent to them. See the linked + * documentation for more detail on the semantics. + * + *

    Clients can also use {@link android.content.Context#bindService Context.bindService()} to + * obtain a persistent connection to a service. This likewise creates the + * service if it is not already running (calling {@link #onCreate} while + * doing so), but does not call onStartCommand(). The client will receive the + * {@link android.os.IBinder} object that the service returns from its + * {@link #onBind} method, allowing the client to then make calls back + * to the service. The service will remain running as long as the connection + * is established (whether or not the client retains a reference on the + * service's IBinder). Usually the IBinder returned is for a complex + * interface that has been written + * in aidl. + * + *

    A service can be both started and have connections bound to it. In such + * a case, the system will keep the service running as long as either it is + * started or there are one or more connections to it with the + * {@link android.content.Context#BIND_AUTO_CREATE Context.BIND_AUTO_CREATE} + * flag. Once neither + * of these situations hold, the service's {@link #onDestroy} method is called + * and the service is effectively terminated. All cleanup (stopping threads, + * unregistering receivers) should be complete upon returning from onDestroy(). + * + * + *

    Permissions

    + * + *

    Global access to a service can be enforced when it is declared in its + * manifest's {@link android.R.styleable#AndroidManifestService <service>} + * tag. By doing so, other applications will need to declare a corresponding + * {@link android.R.styleable#AndroidManifestUsesPermission <uses-permission>} + * element in their own manifest to be able to start, stop, or bind to + * the service. + * + *

    As of {@link android.os.Build.VERSION_CODES#GINGERBREAD}, when using + * {@link Context#startService(Intent) Context.startService(Intent)}, you can + * also set {@link Intent#FLAG_GRANT_READ_URI_PERMISSION + * Intent.FLAG_GRANT_READ_URI_PERMISSION} and/or {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION + * Intent.FLAG_GRANT_WRITE_URI_PERMISSION} on the Intent. This will grant the + * Service temporary access to the specific URIs in the Intent. Access will + * remain until the Service has called {@link #stopSelf(int)} for that start + * command or a later one, or until the Service has been completely stopped. + * This works for granting access to the other apps that have not requested + * the permission protecting the Service, or even when the Service is not + * exported at all. + * + *

    In addition, a service can protect individual IPC calls into it with + * permissions, by calling the + * {@link #checkCallingPermission} + * method before executing the implementation of that call. + * + *

    See the Security and Permissions + * document for more information on permissions and security in general. + * + * + *

    Process Lifecycle

    + * + *

    The Android system will attempt to keep the process hosting a service + * around as long as the service has been started or has clients bound to it. + * When running low on memory and needing to kill existing processes, the + * priority of a process hosting the service will be the higher of the + * following possibilities: + * + *

      + *
    • If the service is currently executing code in its + * {@link #onCreate onCreate()}, {@link #onStartCommand onStartCommand()}, + * or {@link #onDestroy onDestroy()} methods, then the hosting process will + * be a foreground process to ensure this code can execute without + * being killed. + *

    • If the service has been started, then its hosting process is considered + * to be less important than any processes that are currently visible to the + * user on-screen, but more important than any process not visible. Because + * only a few processes are generally visible to the user, this means that + * the service should not be killed except in low memory conditions. However, since + * the user is not directly aware of a background service, in that state it is + * considered a valid candidate to kill, and you should be prepared for this to + * happen. In particular, long-running services will be increasingly likely to + * kill and are guaranteed to be killed (and restarted if appropriate) if they + * remain started long enough. + *

    • If there are clients bound to the service, then the service's hosting + * process is never less important than the most important client. That is, + * if one of its clients is visible to the user, then the service itself is + * considered to be visible. The way a client's importance impacts the service's + * importance can be adjusted through {@link Context#BIND_ABOVE_CLIENT}, + * {@link Context#BIND_ALLOW_OOM_MANAGEMENT}, {@link Context#BIND_WAIVE_PRIORITY}, + * {@link Context#BIND_IMPORTANT}, and {@link Context#BIND_ADJUST_WITH_ACTIVITY}. + *

    • A started service can use the {@link #startForeground(int, Notification)} + * API to put the service in a foreground state, where the system considers + * it to be something the user is actively aware of and thus not a candidate + * for killing when low on memory. (It is still theoretically possible for + * the service to be killed under extreme memory pressure from the current + * foreground application, but in practice this should not be a concern.) + *

    + * + *

    Note this means that most of the time your service is running, it may + * be killed by the system if it is under heavy memory pressure. If this + * happens, the system will later try to restart the service. An important + * consequence of this is that if you implement {@link #onStartCommand onStartCommand()} + * to schedule work to be done asynchronously or in another thread, then you + * may want to use {@link #START_FLAG_REDELIVERY} to have the system + * re-deliver an Intent for you so that it does not get lost if your service + * is killed while processing it. + * + *

    Other application components running in the same process as the service + * (such as an {@link android.app.Activity}) can, of course, increase the + * importance of the overall + * process beyond just the importance of the service itself. + * + * + *

    Local Service Sample

    + * + *

    One of the most common uses of a Service is as a secondary component + * running alongside other parts of an application, in the same process as + * the rest of the components. All components of an .apk run in the same + * process unless explicitly stated otherwise, so this is a typical situation. + * + *

    When used in this way, by assuming the + * components are in the same process, you can greatly simplify the interaction + * between them: clients of the service can simply cast the IBinder they + * receive from it to a concrete class published by the service. + * + *

    An example of this use of a Service is shown here. First is the Service + * itself, publishing a custom class when bound: + * + * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/LocalService.java + * service} + * + *

    With that done, one can now write client code that directly accesses the + * running service, such as: + * + * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceActivities.java + * bind} + * + * + *

    Remote Messenger Service Sample

    + * + *

    If you need to be able to write a Service that can perform complicated + * communication with clients in remote processes (beyond simply the use of + * {@link Context#startService(Intent) Context.startService} to send + * commands to it), then you can use the {@link android.os.Messenger} class + * instead of writing full AIDL files. + * + *

    An example of a Service that uses Messenger as its client interface + * is shown here. First is the Service itself, publishing a Messenger to + * an internal Handler when bound: + * + * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.java + * service} + * + *

    If we want to make this service run in a remote process (instead of the + * standard one for its .apk), we can use android:process in its + * manifest tag to specify one: + * + * {@sample development/samples/ApiDemos/AndroidManifest.xml remote_service_declaration} + * + *

    Note that the name "remote" chosen here is arbitrary, and you can use + * other names if you want additional processes. The ':' prefix appends the + * name to your package's standard process name. + * + *

    With that done, clients can now bind to the service and send messages + * to it. Note that this allows clients to register with it to receive + * messages back as well: + * + * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/MessengerServiceActivities.java + * bind} + */ +public abstract class Service extends ContextWrapper { + /** + * Called by the system when the service is first created. Do not call this method directly. + */ + public void onCreate() { + } + + /** + * @deprecated Implement {@link #onStartCommand(Intent, int, int)} instead. + */ + @Deprecated + public void onStart(Intent intent, int startId) { + } + + /** + * Called by the system every time a client explicitly starts the service by calling + * {@link android.content.Context#startService}, providing the arguments it supplied and a + * unique integer token representing the start request. Do not call this method directly. + * + *

    For backwards compatibility, the default implementation calls + * {@link #onStart} and returns either {@link #START_STICKY} + * or {@link #START_STICKY_COMPATIBILITY}. + * + *

    Note that the system calls this on your + * service's main thread. A service's main thread is the same + * thread where UI operations take place for Activities running in the + * same process. You should always avoid stalling the main + * thread's event loop. When doing long-running operations, + * network calls, or heavy disk I/O, you should kick off a new + * thread, or use {@link android.os.AsyncTask}.

    + * + * @param intent The Intent supplied to {@link android.content.Context#startService}, + * as given. This may be null if the service is being restarted after + * its process has gone away, and it had previously returned anything + * except {@link #START_STICKY_COMPATIBILITY}. + * @param flags Additional data about this start request. + * @param startId A unique integer representing this specific request to + * start. Use with {@link #stopSelfResult(int)}. + * + * @return The return value indicates what semantics the system should + * use for the service's current started state. It may be one of the + * constants associated with the {@link #START_CONTINUATION_MASK} bits. + * + * @see #stopSelfResult(int) + */ + public int onStartCommand(Intent intent, int flags, int startId) { + return -1; + } + + /** + * Called by the system to notify a Service that it is no longer used and is being removed. The + * service should clean up any resources it holds (threads, registered + * receivers, etc) at this point. Upon return, there will be no more calls + * in to this Service object and it is effectively dead. Do not call this method directly. + */ + public void onDestroy() { + } +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/content/ComponentName.java b/java/ql/test/stubs/google-android-9.0.0/android/content/ComponentName.java new file mode 100644 index 00000000000..adb50343ca4 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/content/ComponentName.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.content; + +/** + * Identifier for a specific application component + * ({@link android.app.Activity}, {@link android.app.Service}, + * {@link android.content.BroadcastReceiver}, or + * {@link android.content.ContentProvider}) that is available. Two + * pieces of information, encapsulated here, are required to identify + * a component: the package (a String) it exists in, and the class (a String) + * name inside of that package. + * + */ +public final class ComponentName { +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/content/ContentInterface.java b/java/ql/test/stubs/google-android-9.0.0/android/content/ContentInterface.java new file mode 100644 index 00000000000..705f51ca5d0 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/content/ContentInterface.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.content; + +import androidx.annotation.NonNull; +import android.annotation.Nullable; +import android.content.res.AssetFileDescriptor; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.os.CancellationSignal; +import android.os.ParcelFileDescriptor; +import android.os.RemoteException; +import java.io.FileNotFoundException; + +public interface ContentInterface { + public @Nullable Cursor query(@NonNull Uri uri, @Nullable String[] projection, + @Nullable Bundle queryArgs, @Nullable CancellationSignal cancellationSignal) + throws RemoteException; + + public @Nullable String getType(@NonNull Uri uri) throws RemoteException; + + public @Nullable String[] getStreamTypes(@NonNull Uri uri, @NonNull String mimeTypeFilter) + throws RemoteException; + + public @Nullable Uri canonicalize(@NonNull Uri uri) throws RemoteException; + + public @Nullable Uri uncanonicalize(@NonNull Uri uri) throws RemoteException; + + public boolean refresh(@NonNull Uri uri, @Nullable Bundle extras, + @Nullable CancellationSignal cancellationSignal) throws RemoteException; + + public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues initialValues, + @Nullable Bundle extras) throws RemoteException; + + public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] initialValues) + throws RemoteException; + + public int delete(@NonNull Uri uri, @Nullable Bundle extras) throws RemoteException; + + public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable Bundle extras) + throws RemoteException; + + public @Nullable ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode, + @Nullable CancellationSignal signal) + throws RemoteException, FileNotFoundException; + + public @Nullable AssetFileDescriptor openAssetFile(@NonNull Uri uri, @NonNull String mode, + @Nullable CancellationSignal signal) + throws RemoteException, FileNotFoundException; + + public @Nullable AssetFileDescriptor openTypedAssetFile(@NonNull Uri uri, + @NonNull String mimeTypeFilter, @Nullable Bundle opts, + @Nullable CancellationSignal signal) + throws RemoteException, FileNotFoundException; + + public @Nullable Bundle call(@NonNull String authority, @NonNull String method, + @Nullable String arg, @Nullable Bundle extras) throws RemoteException; + +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/content/ContentProvider.java b/java/ql/test/stubs/google-android-9.0.0/android/content/ContentProvider.java new file mode 100644 index 00000000000..e897d18500b --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/content/ContentProvider.java @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.content; + +import androidx.annotation.NonNull; +import android.annotation.Nullable; +import android.content.pm.PathPermission; +import android.content.res.AssetFileDescriptor; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.os.CancellationSignal; +import android.os.ParcelFileDescriptor; +import android.util.Pair; +import java.io.FileNotFoundException; + +public abstract class ContentProvider implements ContentInterface { + public ContentProvider() {} + + public ContentProvider(Context context, String readPermission, String writePermission, + PathPermission[] pathPermissions) {} + + public final @Nullable Context getContext() { + return null; + } + + public final Context requireContext() { + return null; + } + + public final @Nullable String getCallingPackage() { + return null; + } + + public final @Nullable String getCallingAttributionTag() { + return null; + } + + public final @Nullable String getCallingFeatureId() { + return null; + } + + public final @Nullable String getCallingPackageUnchecked() { + return null; + } + + public void onCallingPackageChanged() {} + + public final class CallingIdentity { + public CallingIdentity(long binderToken, Pair callingPackage) {} + + } + + public final @NonNull CallingIdentity clearCallingIdentity() { + return null; + } + + public final void restoreCallingIdentity(@NonNull CallingIdentity identity) {} + + public final @Nullable String getReadPermission() { + return null; + } + + public final @Nullable String getWritePermission() { + return null; + } + + public final @Nullable PathPermission[] getPathPermissions() { + return null; + } + + public final void setAppOps(int readOp, int writeOp) {} + + public final void setTransportLoggingEnabled(boolean enabled) {} + + public abstract boolean onCreate(); + + public abstract @Nullable Cursor query(@NonNull Uri uri, @Nullable String[] projection, + @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder); + + public @Nullable Cursor query(@NonNull Uri uri, @Nullable String[] projection, + @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder, + @Nullable CancellationSignal cancellationSignal) { + return null; + } + + @Override + public @Nullable Cursor query(@NonNull Uri uri, @Nullable String[] projection, + @Nullable Bundle queryArgs, @Nullable CancellationSignal cancellationSignal) { + return null; + } + + @Override + public abstract @Nullable String getType(@NonNull Uri uri); + + @Override + public @Nullable Uri canonicalize(@NonNull Uri url) { + return null; + } + + @Override + public @Nullable Uri uncanonicalize(@NonNull Uri url) { + return null; + } + + @Override + public boolean refresh(Uri uri, @Nullable Bundle extras, + @Nullable CancellationSignal cancellationSignal) { + return false; + } + + public Uri rejectInsert(Uri uri, ContentValues values) { + return null; + } + + public abstract @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues values); + + @Override + public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues values, + @Nullable Bundle extras) { + return null; + } + + @Override + public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] values) { + return 0; + } + + public abstract int delete(@NonNull Uri uri, @Nullable String selection, + @Nullable String[] selectionArgs); + + @Override + public int delete(@NonNull Uri uri, @Nullable Bundle extras) { + return 0; + } + + public abstract int update(@NonNull Uri uri, @Nullable ContentValues values, + @Nullable String selection, @Nullable String[] selectionArgs); + + @Override + public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable Bundle extras) { + return 0; + } + + public @Nullable ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode) + throws FileNotFoundException { + return null; + } + + @Override + public @Nullable ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode, + @Nullable CancellationSignal signal) throws FileNotFoundException { + return null; + } + + public @Nullable AssetFileDescriptor openAssetFile(@NonNull Uri uri, @NonNull String mode) + throws FileNotFoundException { + return null; + } + + @Override + public @Nullable AssetFileDescriptor openAssetFile(@NonNull Uri uri, @NonNull String mode, + @Nullable CancellationSignal signal) throws FileNotFoundException { + return null; + } + + @Override + public @Nullable String[] getStreamTypes(@NonNull Uri uri, @NonNull String mimeTypeFilter) { + return null; + } + + public @Nullable AssetFileDescriptor openTypedAssetFile(@NonNull Uri uri, + @NonNull String mimeTypeFilter, @Nullable Bundle opts) throws FileNotFoundException { + return null; + } + + public static int getUserIdFromAuthority(String auth, int defaultUserId) { + return 0; + } + + public static int getUserIdFromAuthority(String auth) { + return 0; + } + + public static int getUserIdFromUri(Uri uri, int defaultUserId) { + return 0; + } + + public static int getUserIdFromUri(Uri uri) { + return 0; + } + + public static String getAuthorityWithoutUserId(String auth) { + return null; + } + + public static Uri getUriWithoutUserId(Uri uri) { + return null; + } + + public static boolean uriHasUserId(Uri uri) { + return false; + } + + public static Uri maybeAddUserId(Uri uri, int userId) { + return null; + } + + public @Nullable Bundle call(@NonNull String method, @Nullable String arg, + @Nullable Bundle extras) { + return null; + } + +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/content/ContentValues.java b/java/ql/test/stubs/google-android-9.0.0/android/content/ContentValues.java new file mode 100644 index 00000000000..d5ef0db4f8b --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/content/ContentValues.java @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.content; + +import android.annotation.Nullable; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.ArrayMap; +import java.util.ArrayList; +import java.util.Map; +import java.util.Set; + +public final class ContentValues implements Parcelable { + public ContentValues() {} + + public ContentValues(int size) {} + + public ContentValues(ContentValues from) {} + + @Override + public boolean equals(Object object) { + return false; + } + + public ArrayMap getValues() { + return null; + } + + @Override + public int hashCode() { + return 0; + } + + public void put(String key, String value) {} + + public void putAll(ContentValues other) {} + + public void put(String key, Byte value) {} + + public void put(String key, Short value) {} + + public void put(String key, Integer value) {} + + public void put(String key, Long value) {} + + public void put(String key, Float value) {} + + public void put(String key, Double value) {} + + public void put(String key, Boolean value) {} + + public void put(String key, byte[] value) {} + + public void putNull(String key) {} + + public void putObject(@Nullable String key, @Nullable Object value) {} + + public int size() { + return 0; + } + + public boolean isEmpty() { + return false; + } + + public void remove(String key) {} + + public void clear() {} + + public boolean containsKey(String key) { + return false; + } + + public Object get(String key) { + return null; + } + + public String getAsString(String key) { + return null; + } + + public Long getAsLong(String key) { + return null; + } + + public Integer getAsInteger(String key) { + return null; + } + + public Short getAsShort(String key) { + return null; + } + + public Byte getAsByte(String key) { + return null; + } + + public Double getAsDouble(String key) { + return null; + } + + public Float getAsFloat(String key) { + return null; + } + + public Boolean getAsBoolean(String key) { + return null; + } + + public byte[] getAsByteArray(String key) { + return null; + } + + public Set> valueSet() { + return null; + } + + public Set keySet() { + return null; + } + + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int flags) {} + + public void putStringArrayList(String key, ArrayList value) {} + + public ArrayList getStringArrayList(String key) { + return null; + } + + @Override + public String toString() { + return null; + } + + public static boolean isSupportedValue(Object value) { + return false; + } + +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/content/Context.java b/java/ql/test/stubs/google-android-9.0.0/android/content/Context.java index 6507cbd371d..8ddd1f2c8ef 100644 --- a/java/ql/test/stubs/google-android-9.0.0/android/content/Context.java +++ b/java/ql/test/stubs/google-android-9.0.0/android/content/Context.java @@ -961,4 +961,91 @@ public abstract class Context { * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle) */ public abstract void sendOrderedBroadcast(Intent intent, String receiverPermission); -} \ No newline at end of file + + /** + * Request that a given application service be started. The Intent + * should either contain the complete class name of a specific service + * implementation to start, or a specific package name to target. If the + * Intent is less specified, it logs a warning about this. In this case any of the + * multiple matching services may be used. If this service + * is not already running, it will be instantiated and started (creating a + * process for it if needed); if it is running then it remains running. + * + *

    Every call to this method will result in a corresponding call to + * the target service's {@link android.app.Service#onStartCommand} method, + * with the intent given here. This provides a convenient way + * to submit jobs to a service without having to bind and call on to its + * interface. + * + *

    Using startService() overrides the default service lifetime that is + * managed by {@link #bindService}: it requires the service to remain + * running until {@link #stopService} is called, regardless of whether + * any clients are connected to it. Note that calls to startService() + * do not nest: no matter how many times you call startService(), + * a single call to {@link #stopService} will stop it. + * + *

    The system attempts to keep running services around as much as + * possible. The only time they should be stopped is if the current + * foreground application is using so many resources that the service needs + * to be killed. If any errors happen in the service's process, it will + * automatically be restarted. + * + *

    This function will throw {@link SecurityException} if you do not + * have permission to start the given service. + * + *

    Note: Each call to startService() + * results in significant work done by the system to manage service + * lifecycle surrounding the processing of the intent, which can take + * multiple milliseconds of CPU time. Due to this cost, startService() + * should not be used for frequent intent delivery to a service, and only + * for scheduling significant work. Use {@link #bindService bound services} + * for high frequency calls. + *

    + * + * @param service Identifies the service to be started. The Intent must be + * fully explicit (supplying a component name). Additional values + * may be included in the Intent extras to supply arguments along with + * this specific start call. + * + * @return If the service is being started or is already running, the + * {@link ComponentName} of the actual service that was started is + * returned; else if the service does not exist null is returned. + * + * @throws SecurityException If the caller does not have permission to access the service + * or the service can not be found. + * @throws IllegalStateException If the application is in a state where the service + * can not be started (such as not in the foreground in a state when services are allowed). + * + * @see #stopService + * @see #bindService + */ + public abstract ComponentName startService(Intent service); + + /** + * Similar to {@link #startService(Intent)}, but with an implicit promise that the + * Service will call {@link android.app.Service#startForeground(int, android.app.Notification) + * startForeground(int, android.app.Notification)} once it begins running. The service is given + * an amount of time comparable to the ANR interval to do this, otherwise the system + * will automatically stop the service and declare the app ANR. + * + *

    Unlike the ordinary {@link #startService(Intent)}, this method can be used + * at any time, regardless of whether the app hosting the service is in a foreground + * state. + * + * @param service Identifies the service to be started. The Intent must be + * fully explicit (supplying a component name). Additional values + * may be included in the Intent extras to supply arguments along with + * this specific start call. + * + * @return If the service is being started or is already running, the + * {@link ComponentName} of the actual service that was started is + * returned; else if the service does not exist null is returned. + * + * @throws SecurityException If the caller does not have permission to access the service + * or the service can not be found. + * + * @see #stopService + * @see android.app.Service#startForeground(int, android.app.Notification) + */ + public abstract ComponentName startForegroundService(Intent service); +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/content/ContextWrapper.java b/java/ql/test/stubs/google-android-9.0.0/android/content/ContextWrapper.java new file mode 100644 index 00000000000..d3e23384cbd --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/content/ContextWrapper.java @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.content; + +import java.io.File; +import android.os.Bundle; + +/** + * Proxying implementation of Context that simply delegates all of its calls to + * another Context. Can be subclassed to modify behavior without changing + * the original Context. + */ +public class ContextWrapper extends Context { + public ContextWrapper() { + } + + public ContextWrapper(Context base) { + } + + @Override + public Context getApplicationContext() { + return null; + } + + @Override + public File getFileStreamPath(String name) { + return null; + } + + @Override + public SharedPreferences getSharedPreferences(String name, int mode) { + return null; + } + + @Override + public File getSharedPrefsFile(String name) { + return null; + } + + @Override + public String[] fileList() { + return null; + } + + @Override + public File getDataDir() { + return null; + } + + @Override + public File getFilesDir() { + return null; + } + + @Override + public File getNoBackupFilesDir() { + return null; + } + + @Override + public File getExternalFilesDir(String type) { + return null; + } + + @Override + public File[] getExternalFilesDirs(String type) { + return null; + } + + @Override + public File getObbDir() { + return null; + } + + @Override + public File[] getObbDirs() { + return null; + } + + @Override + public File getCacheDir() { + return null; + } + + @Override + public File getCodeCacheDir() { + return null; + } + + @Override + public File getExternalCacheDir() { + return null; + } + + @Override + public File[] getExternalCacheDirs() { + return null; + } + + @Override + public File[] getExternalMediaDirs() { + return null; + } + + @Override + public File getDir(String name, int mode) { + return null; + } + + /** @hide **/ + @Override + public File getPreloadsFileCache() { + return null; + } + + @Override + public void startActivity(Intent intent) { + } + + /** @hide **/ + public void startActivityForResult( + String who, Intent intent, int requestCode, Bundle options) { + } + + /** @hide **/ + public boolean canStartActivityForResult() { + return false; + } + @Override + + public void startActivity(Intent intent, Bundle options) { + } + + @Override + public void startActivities(Intent[] intents) { + } + + @Override + public void startActivities(Intent[] intents, Bundle options) { + } + + @Override + public void sendBroadcast(Intent intent) { + } + + @Override + public void sendBroadcast(Intent intent, String receiverPermission) { + } + + @Override + public void sendBroadcastWithMultiplePermissions(Intent intent, String[] receiverPermissions) { + } + + /** @hide */ + @Override + public void sendBroadcast(Intent intent, String receiverPermission, int appOp) { + } + + @Override + public void sendOrderedBroadcast(Intent intent, + String receiverPermission) { + } + + @Override + public ComponentName startService(Intent service) { + return null; + } + + @Override + public ComponentName startForegroundService(Intent service) { + return null; + } +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/content/Intent.java b/java/ql/test/stubs/google-android-9.0.0/android/content/Intent.java index 09422c7a48a..03004b437d2 100644 --- a/java/ql/test/stubs/google-android-9.0.0/android/content/Intent.java +++ b/java/ql/test/stubs/google-android-9.0.0/android/content/Intent.java @@ -723,6 +723,511 @@ import java.util.Set; */ public class Intent implements Parcelable, Cloneable { + /** + * Activity Action: Start as a main entry point, does not expect to + * receive data. + *

    Input: nothing + *

    Output: nothing + */ + public static final String ACTION_MAIN = "android.intent.action.MAIN"; + + /** + * Activity Action: Display the data to the user. This is the most common + * action performed on data -- it is the generic action you can use on + * a piece of data to get the most reasonable thing to occur. For example, + * when used on a contacts entry it will view the entry; when used on a + * mailto: URI it will bring up a compose window filled with the information + * supplied by the URI; when used with a tel: URI it will invoke the + * dialer. + *

    Input: {@link #getData} is URI from which to retrieve data. + *

    Output: nothing. + */ + public static final String ACTION_VIEW = "android.intent.action.VIEW"; + + /** + * A synonym for {@link #ACTION_VIEW}, the "standard" action that is + * performed on a piece of data. + */ + public static final String ACTION_DEFAULT = ACTION_VIEW; + + /** + * Used to indicate that some piece of data should be attached to some other + * place. For example, image data could be attached to a contact. It is up + * to the recipient to decide where the data should be attached; the intent + * does not specify the ultimate destination. + *

    Input: {@link #getData} is URI of data to be attached. + *

    Output: nothing. + */ + public static final String ACTION_ATTACH_DATA = "android.intent.action.ATTACH_DATA"; + + /** + * Activity Action: Provide explicit editable access to the given data. + *

    Input: {@link #getData} is URI of data to be edited. + *

    Output: nothing. + */ + public static final String ACTION_EDIT = "android.intent.action.EDIT"; + + /** + * Activity Action: Pick an existing item, or insert a new item, and then edit it. + *

    Input: {@link #getType} is the desired MIME type of the item to create or edit. + * The extras can contain type specific data to pass through to the editing/creating + * activity. + *

    Output: The URI of the item that was picked. This must be a content: + * URI so that any receiver can access it. + */ + public static final String ACTION_INSERT_OR_EDIT = "android.intent.action.INSERT_OR_EDIT"; + + /** + * Activity Action: Pick an item from the data, returning what was selected. + *

    Input: {@link #getData} is URI containing a directory of data + * (vnd.android.cursor.dir/*) from which to pick an item. + *

    Output: The URI of the item that was picked. + */ + public static final String ACTION_PICK = "android.intent.action.PICK"; + + /** + * Activity Action: Creates a shortcut. + *

    Input: Nothing.

    + *

    Output: An Intent representing the shortcut. The intent must contain three + * extras: SHORTCUT_INTENT (value: Intent), SHORTCUT_NAME (value: String), + * and SHORTCUT_ICON (value: Bitmap) or SHORTCUT_ICON_RESOURCE + * (value: ShortcutIconResource).

    + * + * @see #EXTRA_SHORTCUT_INTENT + * @see #EXTRA_SHORTCUT_NAME + * @see #EXTRA_SHORTCUT_ICON + * @see #EXTRA_SHORTCUT_ICON_RESOURCE + * @see android.content.Intent.ShortcutIconResource + */ + public static final String ACTION_CREATE_SHORTCUT = "android.intent.action.CREATE_SHORTCUT"; + + /** + * Activity Action: Display an activity chooser, allowing the user to pick + * what they want to before proceeding. This can be used as an alternative + * to the standard activity picker that is displayed by the system when + * you try to start an activity with multiple possible matches, with these + * differences in behavior: + *
      + *
    • You can specify the title that will appear in the activity chooser. + *
    • The user does not have the option to make one of the matching + * activities a preferred activity, and all possible activities will + * always be shown even if one of them is currently marked as the + * preferred activity. + *
    + *

    + * This action should be used when the user will naturally expect to + * select an activity in order to proceed. An example if when not to use + * it is when the user clicks on a "mailto:" link. They would naturally + * expect to go directly to their mail app, so startActivity() should be + * called directly: it will + * either launch the current preferred app, or put up a dialog allowing the + * user to pick an app to use and optionally marking that as preferred. + *

    + * In contrast, if the user is selecting a menu item to send a picture + * they are viewing to someone else, there are many different things they + * may want to do at this point: send it through e-mail, upload it to a + * web service, etc. In this case the CHOOSER action should be used, to + * always present to the user a list of the things they can do, with a + * nice title given by the caller such as "Send this photo with:". + *

    + * As a convenience, an Intent of this form can be created with the + * {@link #createChooser} function. + *

    Input: No data should be specified. get*Extra must have + * a {@link #EXTRA_INTENT} field containing the Intent being executed, + * and can optionally have a {@link #EXTRA_TITLE} field containing the + * title text to display in the chooser. + *

    Output: Depends on the protocol of {@link #EXTRA_INTENT}. + */ + public static final String ACTION_CHOOSER = "android.intent.action.CHOOSER"; + + /** + * Convenience function for creating a {@link #ACTION_CHOOSER} Intent. + * + * @param target The Intent that the user will be selecting an activity + * to perform. + * @param title Optional title that will be displayed in the chooser. + * @return Return a new Intent object that you can hand to + * {@link Context#startActivity(Intent) Context.startActivity()} and + * related methods. + */ + public static Intent createChooser(Intent target, CharSequence title) { + return null; + } + + /** + * Activity Action: Allow the user to select a particular kind of data and + * return it. This is different than {@link #ACTION_PICK} in that here we + * just say what kind of data is desired, not a URI of existing data from + * which the user can pick. A ACTION_GET_CONTENT could allow the user to + * create the data as it runs (for example taking a picture or recording a + * sound), let them browse over the web and download the desired data, + * etc. + *

    + * There are two main ways to use this action: if you want a specific kind + * of data, such as a person contact, you set the MIME type to the kind of + * data you want and launch it with {@link Context#startActivity(Intent)}. + * The system will then launch the best application to select that kind + * of data for you. + *

    + * You may also be interested in any of a set of types of content the user + * can pick. For example, an e-mail application that wants to allow the + * user to add an attachment to an e-mail message can use this action to + * bring up a list of all of the types of content the user can attach. + *

    + * In this case, you should wrap the GET_CONTENT intent with a chooser + * (through {@link #createChooser}), which will give the proper interface + * for the user to pick how to send your data and allow you to specify + * a prompt indicating what they are doing. You will usually specify a + * broad MIME type (such as image/* or {@literal *}/*), resulting in a + * broad range of content types the user can select from. + *

    + * When using such a broad GET_CONTENT action, it is often desirable to + * only pick from data that can be represented as a stream. This is + * accomplished by requiring the {@link #CATEGORY_OPENABLE} in the Intent. + *

    + * Callers can optionally specify {@link #EXTRA_LOCAL_ONLY} to request that + * the launched content chooser only returns results representing data that + * is locally available on the device. For example, if this extra is set + * to true then an image picker should not show any pictures that are available + * from a remote server but not already on the local device (thus requiring + * they be downloaded when opened). + *

    + * Input: {@link #getType} is the desired MIME type to retrieve. Note + * that no URI is supplied in the intent, as there are no constraints on + * where the returned data originally comes from. You may also include the + * {@link #CATEGORY_OPENABLE} if you can only accept data that can be + * opened as a stream. You may use {@link #EXTRA_LOCAL_ONLY} to limit content + * selection to local data. + *

    + * Output: The URI of the item that was picked. This must be a content: + * URI so that any receiver can access it. + */ + public static final String ACTION_GET_CONTENT = "android.intent.action.GET_CONTENT"; + + /** + * Activity Action: Dial a number as specified by the data. This shows a + * UI with the number being dialed, allowing the user to explicitly + * initiate the call. + *

    Input: If nothing, an empty dialer is started; else {@link #getData} + * is URI of a phone number to be dialed or a tel: URI of an explicit phone + * number. + *

    Output: nothing. + */ + public static final String ACTION_DIAL = "android.intent.action.DIAL"; + + /** + * Activity Action: Perform a call to someone specified by the data. + *

    Input: If nothing, an empty dialer is started; else {@link #getData} + * is URI of a phone number to be dialed or a tel: URI of an explicit phone + * number. + *

    Output: nothing. + * + *

    Note: there will be restrictions on which applications can initiate a + * call; most applications should use the {@link #ACTION_DIAL}. + *

    Note: this Intent cannot be used to call emergency + * numbers. Applications can dial emergency numbers using + * {@link #ACTION_DIAL}, however. + */ + public static final String ACTION_CALL = "android.intent.action.CALL"; + + /** + * Activity Action: Perform a call to an emergency number specified by the + * data. + *

    Input: {@link #getData} is URI of a phone number to be dialed or a + * tel: URI of an explicit phone number. + *

    Output: nothing. + * @hide + */ + public static final String ACTION_CALL_EMERGENCY = "android.intent.action.CALL_EMERGENCY"; + + /** + * Activity action: Perform a call to any number (emergency or not) + * specified by the data. + *

    Input: {@link #getData} is URI of a phone number to be dialed or a + * tel: URI of an explicit phone number. + *

    Output: nothing. + * @hide + */ + public static final String ACTION_CALL_PRIVILEGED = "android.intent.action.CALL_PRIVILEGED"; + + /** + * Activity Action: Send a message to someone specified by the data. + *

    Input: {@link #getData} is URI describing the target. + *

    Output: nothing. + */ + public static final String ACTION_SENDTO = "android.intent.action.SENDTO"; + + /** + * Activity Action: Deliver some data to someone else. Who the data is + * being delivered to is not specified; it is up to the receiver of this + * action to ask the user where the data should be sent. + *

    + * When launching a SEND intent, you should usually wrap it in a chooser + * (through {@link #createChooser}), which will give the proper interface + * for the user to pick how to send your data and allow you to specify + * a prompt indicating what they are doing. + *

    + * Input: {@link #getType} is the MIME type of the data being sent. + * get*Extra can have either a {@link #EXTRA_TEXT} + * or {@link #EXTRA_STREAM} field, containing the data to be sent. If + * using EXTRA_TEXT, the MIME type should be "text/plain"; otherwise it + * should be the MIME type of the data in EXTRA_STREAM. Use {@literal *}/* + * if the MIME type is unknown (this will only allow senders that can + * handle generic data streams). + *

    + * Optional standard extras, which may be interpreted by some recipients as + * appropriate, are: {@link #EXTRA_EMAIL}, {@link #EXTRA_CC}, + * {@link #EXTRA_BCC}, {@link #EXTRA_SUBJECT}. + *

    + * Output: nothing. + */ + public static final String ACTION_SEND = "android.intent.action.SEND"; + + /** + * Activity Action: Deliver multiple data to someone else. + *

    + * Like ACTION_SEND, except the data is multiple. + *

    + * Input: {@link #getType} is the MIME type of the data being sent. + * get*ArrayListExtra can have either a {@link #EXTRA_TEXT} or {@link + * #EXTRA_STREAM} field, containing the data to be sent. + *

    + * Multiple types are supported, and receivers should handle mixed types + * whenever possible. The right way for the receiver to check them is to + * use the content resolver on each URI. The intent sender should try to + * put the most concrete mime type in the intent type, but it can fall + * back to {@literal /*} or {@literal *}/* as needed. + *

    + * e.g. if you are sending image/jpg and image/jpg, the intent's type can + * be image/jpg, but if you are sending image/jpg and image/png, then the + * intent's type should be image/*. + *

    + * Optional standard extras, which may be interpreted by some recipients as + * appropriate, are: {@link #EXTRA_EMAIL}, {@link #EXTRA_CC}, + * {@link #EXTRA_BCC}, {@link #EXTRA_SUBJECT}. + *

    + * Output: nothing. + */ + public static final String ACTION_SEND_MULTIPLE = "android.intent.action.SEND_MULTIPLE"; + + /** + * Activity Action: Handle an incoming phone call. + *

    Input: nothing. + *

    Output: nothing. + */ + public static final String ACTION_ANSWER = "android.intent.action.ANSWER"; + + /** + * Activity Action: Insert an empty item into the given container. + *

    Input: {@link #getData} is URI of the directory (vnd.android.cursor.dir/*) + * in which to place the data. + *

    Output: URI of the new data that was created. + */ + public static final String ACTION_INSERT = "android.intent.action.INSERT"; + + /** + * Activity Action: Create a new item in the given container, initializing it + * from the current contents of the clipboard. + *

    Input: {@link #getData} is URI of the directory (vnd.android.cursor.dir/*) + * in which to place the data. + *

    Output: URI of the new data that was created. + */ + public static final String ACTION_PASTE = "android.intent.action.PASTE"; + + /** + * Activity Action: Delete the given data from its container. + *

    Input: {@link #getData} is URI of data to be deleted. + *

    Output: nothing. + */ + public static final String ACTION_DELETE = "android.intent.action.DELETE"; + /** + * Activity Action: Run the data, whatever that means. + *

    Input: ? (Note: this is currently specific to the test harness.) + *

    Output: nothing. + */ + public static final String ACTION_RUN = "android.intent.action.RUN"; + + /** + * Activity Action: Perform a data synchronization. + *

    Input: ? + *

    Output: ? + */ + public static final String ACTION_SYNC = "android.intent.action.SYNC"; + + /** + * Activity Action: Pick an activity given an intent, returning the class + * selected. + *

    Input: get*Extra field {@link #EXTRA_INTENT} is an Intent + * used with {@link PackageManager#queryIntentActivities} to determine the + * set of activities from which to pick. + *

    Output: Class name of the activity that was selected. + */ + public static final String ACTION_PICK_ACTIVITY = "android.intent.action.PICK_ACTIVITY"; + + /** + * Activity Action: Perform a search. + *

    Input: {@link android.app.SearchManager#QUERY getStringExtra(SearchManager.QUERY)} + * is the text to search for. If empty, simply + * enter your search results Activity with the search UI activated. + *

    Output: nothing. + */ + public static final String ACTION_SEARCH = "android.intent.action.SEARCH"; + + /** + * Activity Action: Start the platform-defined tutorial + *

    Input: {@link android.app.SearchManager#QUERY getStringExtra(SearchManager.QUERY)} + * is the text to search for. If empty, simply + * enter your search results Activity with the search UI activated. + *

    Output: nothing. + */ + public static final String ACTION_SYSTEM_TUTORIAL = "android.intent.action.SYSTEM_TUTORIAL"; + + /** + * Activity Action: Perform a web search. + *

    + * Input: {@link android.app.SearchManager#QUERY + * getStringExtra(SearchManager.QUERY)} is the text to search for. If it is + * a url starts with http or https, the site will be opened. If it is plain + * text, Google search will be applied. + *

    + * Output: nothing. + */ + public static final String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH"; + + /** + * Activity Action: List all available applications + *

    Input: Nothing. + *

    Output: nothing. + */ + public static final String ACTION_ALL_APPS = "android.intent.action.ALL_APPS"; + + /** + * Activity Action: Show settings for choosing wallpaper + *

    Input: Nothing. + *

    Output: Nothing. + */ + public static final String ACTION_SET_WALLPAPER = "android.intent.action.SET_WALLPAPER"; + + /** + * Activity Action: Show activity for reporting a bug. + *

    Input: Nothing. + *

    Output: Nothing. + */ + public static final String ACTION_BUG_REPORT = "android.intent.action.BUG_REPORT"; + + /** + * Activity Action: Main entry point for factory tests. Only used when + * the device is booting in factory test node. The implementing package + * must be installed in the system image. + *

    Input: nothing + *

    Output: nothing + */ + public static final String ACTION_FACTORY_TEST = "android.intent.action.FACTORY_TEST"; + + /** + * Activity Action: The user pressed the "call" button to go to the dialer + * or other appropriate UI for placing a call. + *

    Input: Nothing. + *

    Output: Nothing. + */ + public static final String ACTION_CALL_BUTTON = "android.intent.action.CALL_BUTTON"; + + /** + * Activity Action: Start Voice Command. + *

    Input: Nothing. + *

    Output: Nothing. + */ + public static final String ACTION_VOICE_COMMAND = "android.intent.action.VOICE_COMMAND"; + + /** + * Activity Action: Start action associated with long pressing on the + * search key. + *

    Input: Nothing. + *

    Output: Nothing. + */ + public static final String ACTION_SEARCH_LONG_PRESS = "android.intent.action.SEARCH_LONG_PRESS"; + + /** + * Activity Action: The user pressed the "Report" button in the crash/ANR dialog. + * This intent is delivered to the package which installed the application, usually + * Google Play. + *

    Input: No data is specified. The bug report is passed in using + * an {@link #EXTRA_BUG_REPORT} field. + *

    Output: Nothing. + * + * @see #EXTRA_BUG_REPORT + */ + public static final String ACTION_APP_ERROR = "android.intent.action.APP_ERROR"; + + /** + * Activity Action: Show power usage information to the user. + *

    Input: Nothing. + *

    Output: Nothing. + */ + public static final String ACTION_POWER_USAGE_SUMMARY = "android.intent.action.POWER_USAGE_SUMMARY"; + + /** + * Activity Action: Setup wizard to launch after a platform update. This + * activity should have a string meta-data field associated with it, + * {@link #METADATA_SETUP_VERSION}, which defines the current version of + * the platform for setup. The activity will be launched only if + * {@link android.provider.Settings.Secure#LAST_SETUP_SHOWN} is not the + * same value. + *

    Input: Nothing. + *

    Output: Nothing. + * @hide + */ + public static final String ACTION_UPGRADE_SETUP = "android.intent.action.UPGRADE_SETUP"; + + /** + * Activity Action: Show settings for managing network data usage of a + * specific application. Applications should define an activity that offers + * options to control data usage. + */ + public static final String ACTION_MANAGE_NETWORK_USAGE = + "android.intent.action.MANAGE_NETWORK_USAGE"; + + /** + * Activity Action: Launch application installer. + *

    + * Input: The data must be a content: or file: URI at which the application + * can be retrieved. You can optionally supply + * {@link #EXTRA_INSTALLER_PACKAGE_NAME}, {@link #EXTRA_NOT_UNKNOWN_SOURCE}, + * {@link #EXTRA_ALLOW_REPLACE}, and {@link #EXTRA_RETURN_RESULT}. + *

    + * Output: If {@link #EXTRA_RETURN_RESULT}, returns whether the install + * succeeded. + * + * @see #EXTRA_INSTALLER_PACKAGE_NAME + * @see #EXTRA_NOT_UNKNOWN_SOURCE + * @see #EXTRA_RETURN_RESULT + */ + public static final String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE"; + + /** + * Used as a boolean extra field with {@link #ACTION_INSTALL_PACKAGE} to install a + * package. Tells the installer UI to skip the confirmation with the user + * if the .apk is replacing an existing one. + */ + public static final String EXTRA_ALLOW_REPLACE + = "android.intent.extra.ALLOW_REPLACE"; + + /** + * Extra used to indicate that an intent can allow the user to select and return multiple items. + * This is a boolean extra; the default is false. If true, an implementation is allowed to present + * the user with a UI where they can pick multiple items that are all returned to the caller. + * When this happens, they should be returned as the getClipData() part of the result Intent. + */ + public static final String EXTRA_ALLOW_MULTIPLE + = "android.intent.extra.ALLOW_MULTIPLE"; + + /** + * Used to indicate that a GET_CONTENT intent only wants URIs that can be opened with + * ContentResolver.openInputStream. Openable URIs must support the columns in OpenableColumns + * when queried, though it is allowable for those columns to be blank. + */ + public static final String CATEGORY_OPENABLE = "android.intent.category.OPENABLE"; + /** * Create an empty intent. */ @@ -1407,6 +1912,35 @@ public class Intent implements Parcelable, Cloneable { return null; } + /** + * Set an explicit MIME data type. + * + *

    This is used to create intents that only specify a type and not data, + * for example to indicate the type of data to return. + * + *

    This method automatically clears any data that was + * previously set (for example by {@link #setData}). + * + *

    Note: MIME type matching in the Android framework is + * case-sensitive, unlike formal RFC MIME types. As a result, + * you should always write your MIME types with lower case letters, + * or use {@link #normalizeMimeType} or {@link #setTypeAndNormalize} + * to ensure that it is converted to lower case. + * + * @param type The MIME type of the data being handled by this intent. + * + * @return Returns the same Intent object, for chaining multiple calls + * into a single statement. + * + * @see #getType + * @see #setTypeAndNormalize + * @see #setDataAndType + * @see #normalizeMimeType + */ + public Intent setType(String type) { + return null; + } + /** * Add extended data to the intent. The name must include a package prefix, for * example the app com.android.contacts would use names like @@ -2071,4 +2605,23 @@ public class Intent implements Parcelable, Cloneable { return null; } + /** + * Add a new category to the intent. Categories provide additional detail + * about the action the intent performs. When resolving an intent, only + * activities that provide all of the requested categories will be + * used. + * + * @param category The desired category. This can be either one of the + * predefined Intent categories, or a custom category in your own + * namespace. + * + * @return Returns the same Intent object, for chaining multiple calls + * into a single statement. + * + * @see #hasCategory + * @see #removeCategory + */ + public Intent addCategory(String category) { + return null; + } } diff --git a/java/ql/test/stubs/google-android-9.0.0/android/content/pm/PathPermission.java b/java/ql/test/stubs/google-android-9.0.0/android/content/pm/PathPermission.java new file mode 100644 index 00000000000..fdb19186c81 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/content/pm/PathPermission.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.content.pm; + +import android.os.Parcel; +import android.os.PatternMatcher; + +public class PathPermission extends PatternMatcher { + public PathPermission(String pattern, int type, String readPermission, String writePermission) { + super(null); + } + + public PathPermission(Parcel src) { + super(null); + } + + public String getReadPermission() { + return null; + } + + public String getWritePermission() { + return null; + } + + public void writeToParcel(Parcel dest, int flags) {} + +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/content/res/AssetFileDescriptor.java b/java/ql/test/stubs/google-android-9.0.0/android/content/res/AssetFileDescriptor.java new file mode 100644 index 00000000000..beaa53e4449 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/content/res/AssetFileDescriptor.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.content.res; + +import android.os.Bundle; +import android.os.Parcel; +import android.os.ParcelFileDescriptor; +import android.os.Parcelable; +import java.io.Closeable; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +public class AssetFileDescriptor implements Parcelable, Closeable { + public AssetFileDescriptor(ParcelFileDescriptor fd, long startOffset, long length) {} + + public AssetFileDescriptor(ParcelFileDescriptor fd, long startOffset, long length, + Bundle extras) {} + + public ParcelFileDescriptor getParcelFileDescriptor() { + return null; + } + + public FileDescriptor getFileDescriptor() { + return null; + } + + public long getStartOffset() { + return 0; + } + + public Bundle getExtras() { + return null; + } + + public long getLength() { + return 0; + } + + public long getDeclaredLength() { + return 0; + } + + @Override + public void close() throws IOException {} + + public FileInputStream createInputStream() throws IOException { + return null; + } + + public FileOutputStream createOutputStream() throws IOException { + return null; + } + + @Override + public String toString() { + return null; + } + + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) {} + +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/database/Cursor.java b/java/ql/test/stubs/google-android-9.0.0/android/database/Cursor.java new file mode 100644 index 00000000000..cc432b1ad06 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/database/Cursor.java @@ -0,0 +1,5 @@ +package android.database; + +public interface Cursor { + +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/net/Uri.java b/java/ql/test/stubs/google-android-9.0.0/android/net/Uri.java index d5352f0f7ea..2b63354b8f2 100644 --- a/java/ql/test/stubs/google-android-9.0.0/android/net/Uri.java +++ b/java/ql/test/stubs/google-android-9.0.0/android/net/Uri.java @@ -541,4 +541,152 @@ public abstract class Uri implements Parcelable, Comparable { public boolean isPathPrefixMatch(Uri prefix) { return false; } + + public Builder buildUpon() { return null; } + + /** + * Helper class for building or manipulating URI references. Not safe for + * concurrent use. + * + *

    An absolute hierarchical URI reference follows the pattern: + * {@code ://?#} + * + *

    Relative URI references (which are always hierarchical) follow one + * of two patterns: {@code ?#} + * or {@code //?#} + * + *

    An opaque URI follows this pattern: + * {@code :#} + * + *

    Use {@link Uri#buildUpon()} to obtain a builder representing an existing URI. + */ + public static final class Builder { + /** + * Constructs a new Builder. + */ + public Builder() {} + /** + * Sets the scheme. + * + * @param scheme name or {@code null} if this is a relative Uri + */ + public Builder scheme(String scheme) { + return null; + } + /** + * Encodes and sets the given opaque scheme-specific-part. + * + * @param opaquePart decoded opaque part + */ + public Builder opaquePart(String opaquePart) { + return null; + } + /** + * Sets the previously encoded opaque scheme-specific-part. + * + * @param opaquePart encoded opaque part + */ + public Builder encodedOpaquePart(String opaquePart) { + return null; + } + /** + * Encodes and sets the authority. + */ + public Builder authority(String authority) { + return null; + } + /** + * Sets the previously encoded authority. + */ + public Builder encodedAuthority(String authority) { + return null; + } + /** + * Sets the path. Leaves '/' characters intact but encodes others as + * necessary. + * + *

    If the path is not null and doesn't start with a '/', and if + * you specify a scheme and/or authority, the builder will prepend the + * given path with a '/'. + */ + public Builder path(String path) { + return null; + } + /** + * Sets the previously encoded path. + * + *

    If the path is not null and doesn't start with a '/', and if + * you specify a scheme and/or authority, the builder will prepend the + * given path with a '/'. + */ + public Builder encodedPath(String path) { + return null; + } + /** + * Encodes the given segment and appends it to the path. + */ + public Builder appendPath(String newSegment) { + return null; + } + /** + * Appends the given segment to the path. + */ + public Builder appendEncodedPath(String newSegment) { + return null; + } + /** + * Encodes and sets the query. + */ + public Builder query(String query) { + return null; + } + /** + * Sets the previously encoded query. + */ + public Builder encodedQuery(String query) { + return null; + } + /** + * Encodes and sets the fragment. + */ + public Builder fragment(String fragment) { + return null; + } + /** + * Sets the previously encoded fragment. + */ + public Builder encodedFragment(String fragment) { + return null; + } + /** + * Encodes the key and value and then appends the parameter to the + * query string. + * + * @param key which will be encoded + * @param value which will be encoded + */ + public Builder appendQueryParameter(String key, String value) { + return null; + } + /** + * Clears the the previously set query. + */ + public Builder clearQuery() { + return null; + } + /** + * Constructs a Uri with the current attributes. + * + * @throws UnsupportedOperationException if the URI is opaque and the + * scheme is null + */ + public Uri build() { + return null; + } + @Override + public String toString() { + return null; + } + } + } diff --git a/java/ql/test/stubs/google-android-9.0.0/android/os/AsyncTask.java b/java/ql/test/stubs/google-android-9.0.0/android/os/AsyncTask.java new file mode 100644 index 00000000000..23ca3179bbc --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/os/AsyncTask.java @@ -0,0 +1,406 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.os; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; + +/** + *

    AsyncTask enables proper and easy use of the UI thread. This class allows you + * to perform background operations and publish results on the UI thread without + * having to manipulate threads and/or handlers.

    + * + *

    AsyncTask is designed to be a helper class around {@link Thread} and {@link Handler} + * and does not constitute a generic threading framework. AsyncTasks should ideally be + * used for short operations (a few seconds at the most.) If you need to keep threads + * running for long periods of time, it is highly recommended you use the various APIs + * provided by the java.util.concurrent package such as {@link Executor}, + * {@link ThreadPoolExecutor} and {@link FutureTask}.

    + * + *

    An asynchronous task is defined by a computation that runs on a background thread and + * whose result is published on the UI thread. An asynchronous task is defined by 3 generic + * types, called Params, Progress and Result, + * and 4 steps, called onPreExecute, doInBackground, + * onProgressUpdate and onPostExecute.

    + * + *
    + *

    Developer Guides

    + *

    For more information about using tasks and threads, read the + * Processes and + * Threads developer guide.

    + *
    + * + *

    Usage

    + *

    AsyncTask must be subclassed to be used. The subclass will override at least + * one method ({@link #doInBackground}), and most often will override a + * second one ({@link #onPostExecute}.)

    + * + *

    Here is an example of subclassing:

    + *
    + * private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
    + *     protected Long doInBackground(URL... urls) {
    + *         int count = urls.length;
    + *         long totalSize = 0;
    + *         for (int i = 0; i < count; i++) {
    + *             totalSize += Downloader.downloadFile(urls[i]);
    + *             publishProgress((int) ((i / (float) count) * 100));
    + *             // Escape early if cancel() is called
    + *             if (isCancelled()) break;
    + *         }
    + *         return totalSize;
    + *     }
    + *
    + *     protected void onProgressUpdate(Integer... progress) {
    + *         setProgressPercent(progress[0]);
    + *     }
    + *
    + *     protected void onPostExecute(Long result) {
    + *         showDialog("Downloaded " + result + " bytes");
    + *     }
    + * }
    + * 
    + * + *

    Once created, a task is executed very simply:

    + *
    + * new DownloadFilesTask().execute(url1, url2, url3);
    + * 
    + * + *

    AsyncTask's generic types

    + *

    The three types used by an asynchronous task are the following:

    + *
      + *
    1. Params, the type of the parameters sent to the task upon + * execution.
    2. + *
    3. Progress, the type of the progress units published during + * the background computation.
    4. + *
    5. Result, the type of the result of the background + * computation.
    6. + *
    + *

    Not all types are always used by an asynchronous task. To mark a type as unused, + * simply use the type {@link Void}:

    + *
    + * private class MyTask extends AsyncTask<Void, Void, Void> { ... }
    + * 
    + * + *

    The 4 steps

    + *

    When an asynchronous task is executed, the task goes through 4 steps:

    + *
      + *
    1. {@link #onPreExecute()}, invoked on the UI thread before the task + * is executed. This step is normally used to setup the task, for instance by + * showing a progress bar in the user interface.
    2. + *
    3. {@link #doInBackground}, invoked on the background thread + * immediately after {@link #onPreExecute()} finishes executing. This step is used + * to perform background computation that can take a long time. The parameters + * of the asynchronous task are passed to this step. The result of the computation must + * be returned by this step and will be passed back to the last step. This step + * can also use {@link #publishProgress} to publish one or more units + * of progress. These values are published on the UI thread, in the + * {@link #onProgressUpdate} step.
    4. + *
    5. {@link #onProgressUpdate}, invoked on the UI thread after a + * call to {@link #publishProgress}. The timing of the execution is + * undefined. This method is used to display any form of progress in the user + * interface while the background computation is still executing. For instance, + * it can be used to animate a progress bar or show logs in a text field.
    6. + *
    7. {@link #onPostExecute}, invoked on the UI thread after the background + * computation finishes. The result of the background computation is passed to + * this step as a parameter.
    8. + *
    + * + *

    Cancelling a task

    + *

    A task can be cancelled at any time by invoking {@link #cancel(boolean)}. Invoking + * this method will cause subsequent calls to {@link #isCancelled()} to return true. + * After invoking this method, {@link #onCancelled(Object)}, instead of + * {@link #onPostExecute(Object)} will be invoked after {@link #doInBackground(Object[])} + * returns. To ensure that a task is cancelled as quickly as possible, you should always + * check the return value of {@link #isCancelled()} periodically from + * {@link #doInBackground(Object[])}, if possible (inside a loop for instance.)

    + * + *

    Threading rules

    + *

    There are a few threading rules that must be followed for this class to + * work properly:

    + *
      + *
    • The AsyncTask class must be loaded on the UI thread. This is done + * automatically as of {@link android.os.Build.VERSION_CODES#JELLY_BEAN}.
    • + *
    • The task instance must be created on the UI thread.
    • + *
    • {@link #execute} must be invoked on the UI thread.
    • + *
    • Do not call {@link #onPreExecute()}, {@link #onPostExecute}, + * {@link #doInBackground}, {@link #onProgressUpdate} manually.
    • + *
    • The task can be executed only once (an exception will be thrown if + * a second execution is attempted.)
    • + *
    + * + *

    Memory observability

    + *

    AsyncTask guarantees that all callback calls are synchronized in such a way that the following + * operations are safe without explicit synchronizations.

    + *
      + *
    • Set member fields in the constructor or {@link #onPreExecute}, and refer to them + * in {@link #doInBackground}. + *
    • Set member fields in {@link #doInBackground}, and refer to them in + * {@link #onProgressUpdate} and {@link #onPostExecute}. + *
    + * + *

    Order of execution

    + *

    When first introduced, AsyncTasks were executed serially on a single background + * thread. Starting with {@link android.os.Build.VERSION_CODES#DONUT}, this was changed + * to a pool of threads allowing multiple tasks to operate in parallel. Starting with + * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, tasks are executed on a single + * thread to avoid common application errors caused by parallel execution.

    + *

    If you truly want parallel execution, you can invoke + * {@link #executeOnExecutor(java.util.concurrent.Executor, Object[])} with + * {@link #THREAD_POOL_EXECUTOR}.

    + */ +public abstract class AsyncTask { + /** + * Creates a new asynchronous task. This constructor must be invoked on the UI thread. + */ + public AsyncTask() { + } + + /** + * Override this method to perform a computation on a background thread. The + * specified parameters are the parameters passed to {@link #execute} + * by the caller of this task. + * + * This method can call {@link #publishProgress} to publish updates + * on the UI thread. + * + * @param params The parameters of the task. + * + * @return A result, defined by the subclass of this task. + * + * @see #onPreExecute() + * @see #onPostExecute + * @see #publishProgress + */ + protected abstract Result doInBackground(Params... params); + + /** + * Runs on the UI thread before {@link #doInBackground}. + * + * @see #onPostExecute + * @see #doInBackground + */ + protected void onPreExecute() { + } + + /** + *

    Runs on the UI thread after {@link #doInBackground}. The + * specified result is the value returned by {@link #doInBackground}.

    + * + *

    This method won't be invoked if the task was cancelled.

    + * + * @param result The result of the operation computed by {@link #doInBackground}. + * + * @see #onPreExecute + * @see #doInBackground + * @see #onCancelled(Object) + */ + protected void onPostExecute(Result result) { + } + + /** + * Runs on the UI thread after {@link #publishProgress} is invoked. + * The specified values are the values passed to {@link #publishProgress}. + * + * @param values The values indicating progress. + * + * @see #publishProgress + * @see #doInBackground + */ + protected void onProgressUpdate(Progress... values) { + } + + /** + *

    Runs on the UI thread after {@link #cancel(boolean)} is invoked and + * {@link #doInBackground(Object[])} has finished.

    + * + *

    The default implementation simply invokes {@link #onCancelled()} and + * ignores the result. If you write your own implementation, do not call + * super.onCancelled(result).

    + * + * @param result The result, if any, computed in + * {@link #doInBackground(Object[])}, can be null + * + * @see #cancel(boolean) + * @see #isCancelled() + */ + protected void onCancelled(Result result) { + onCancelled(); + } + + /** + *

    Applications should preferably override {@link #onCancelled(Object)}. + * This method is invoked by the default implementation of + * {@link #onCancelled(Object)}.

    + * + *

    Runs on the UI thread after {@link #cancel(boolean)} is invoked and + * {@link #doInBackground(Object[])} has finished.

    + * + * @see #onCancelled(Object) + * @see #cancel(boolean) + * @see #isCancelled() + */ + protected void onCancelled() { + } + + /** + * Returns true if this task was cancelled before it completed + * normally. If you are calling {@link #cancel(boolean)} on the task, + * the value returned by this method should be checked periodically from + * {@link #doInBackground(Object[])} to end the task as soon as possible. + * + * @return true if task was cancelled before it completed + * + * @see #cancel(boolean) + */ + public final boolean isCancelled() { + return false; + } + + /** + *

    Attempts to cancel execution of this task. This attempt will + * fail if the task has already completed, already been cancelled, + * or could not be cancelled for some other reason. If successful, + * and this task has not started when cancel is called, + * this task should never run. If the task has already started, + * then the mayInterruptIfRunning parameter determines + * whether the thread executing this task should be interrupted in + * an attempt to stop the task.

    + * + *

    Calling this method will result in {@link #onCancelled(Object)} being + * invoked on the UI thread after {@link #doInBackground(Object[])} + * returns. Calling this method guarantees that {@link #onPostExecute(Object)} + * is never invoked. After invoking this method, you should check the + * value returned by {@link #isCancelled()} periodically from + * {@link #doInBackground(Object[])} to finish the task as early as + * possible.

    + * + * @param mayInterruptIfRunning true if the thread executing this + * task should be interrupted; otherwise, in-progress tasks are allowed + * to complete. + * + * @return false if the task could not be cancelled, + * typically because it has already completed normally; + * true otherwise + * + * @see #isCancelled() + * @see #onCancelled(Object) + */ + public final boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + /** + * Waits if necessary for the computation to complete, and then + * retrieves its result. + * + * @return The computed result. + * + * @throws CancellationException If the computation was cancelled. + * @throws ExecutionException If the computation threw an exception. + * @throws InterruptedException If the current thread was interrupted + * while waiting. + */ + public final Result get() throws InterruptedException, ExecutionException { + return null; + } + + /** + * Executes the task with the specified parameters. The task returns + * itself (this) so that the caller can keep a reference to it. + * + *

    Note: this function schedules the task on a queue for a single background + * thread or pool of threads depending on the platform version. When first + * introduced, AsyncTasks were executed serially on a single background thread. + * Starting with {@link android.os.Build.VERSION_CODES#DONUT}, this was changed + * to a pool of threads allowing multiple tasks to operate in parallel. Starting + * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, tasks are back to being + * executed on a single thread to avoid common application errors caused + * by parallel execution. If you truly want parallel execution, you can use + * the {@link #executeOnExecutor} version of this method + * with {@link #THREAD_POOL_EXECUTOR}; however, see commentary there for warnings + * on its use. + * + *

    This method must be invoked on the UI thread. + * + * @param params The parameters of the task. + * + * @return This instance of AsyncTask. + * + * @throws IllegalStateException If {@link #getStatus()} returns either + * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}. + * + * @see #executeOnExecutor(java.util.concurrent.Executor, Object[]) + * @see #execute(Runnable) + */ + public final AsyncTask execute(Params... params) { + return null; + } + + /** + * Executes the task with the specified parameters. The task returns + * itself (this) so that the caller can keep a reference to it. + * + *

    This method is typically used with {@link #THREAD_POOL_EXECUTOR} to + * allow multiple tasks to run in parallel on a pool of threads managed by + * AsyncTask, however you can also use your own {@link Executor} for custom + * behavior. + * + *

    Warning: Allowing multiple tasks to run in parallel from + * a thread pool is generally not what one wants, because the order + * of their operation is not defined. For example, if these tasks are used + * to modify any state in common (such as writing a file due to a button click), + * there are no guarantees on the order of the modifications. + * Without careful work it is possible in rare cases for the newer version + * of the data to be over-written by an older one, leading to obscure data + * loss and stability issues. Such changes are best + * executed in serial; to guarantee such work is serialized regardless of + * platform version you can use this function with {@link #SERIAL_EXECUTOR}. + * + *

    This method must be invoked on the UI thread. + * + * @param exec The executor to use. {@link #THREAD_POOL_EXECUTOR} is available as a + * convenient process-wide thread pool for tasks that are loosely coupled. + * @param params The parameters of the task. + * + * @return This instance of AsyncTask. + * + * @throws IllegalStateException If {@link #getStatus()} returns either + * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}. + * + * @see #execute(Object[]) + */ + public final AsyncTask executeOnExecutor(Executor exec, + Params... params) { + return null; + } + + /** + * This method can be invoked from {@link #doInBackground} to + * publish updates on the UI thread while the background computation is + * still running. Each call to this method will trigger the execution of + * {@link #onProgressUpdate} on the UI thread. + * + * {@link #onProgressUpdate} will not be called if the task has been + * canceled. + * + * @param values The progress values to update the UI with. + * + * @see #onProgressUpdate + * @see #doInBackground + */ + protected final void publishProgress(Progress... values) { + } +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/os/CancellationSignal.java b/java/ql/test/stubs/google-android-9.0.0/android/os/CancellationSignal.java new file mode 100644 index 00000000000..93a3f05c5da --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/os/CancellationSignal.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.os; + +public final class CancellationSignal { + public CancellationSignal() {} + + public boolean isCanceled() { + return false; + } + + public void throwIfCanceled() {} + + public void cancel() {} + + public void setOnCancelListener(OnCancelListener listener) {} + + public interface OnCancelListener { + void onCancel(); + + } +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/os/ParcelFileDescriptor.java b/java/ql/test/stubs/google-android-9.0.0/android/os/ParcelFileDescriptor.java new file mode 100644 index 00000000000..c0689fefe75 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/os/ParcelFileDescriptor.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.os; + +import java.io.Closeable; +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.DatagramSocket; +import java.net.Socket; + +public class ParcelFileDescriptor implements Parcelable, Closeable { + public ParcelFileDescriptor(ParcelFileDescriptor wrapped) {} + + public ParcelFileDescriptor(FileDescriptor fd) {} + + public ParcelFileDescriptor(FileDescriptor fd, FileDescriptor commChannel) {} + + public static ParcelFileDescriptor open(File file, int mode) throws FileNotFoundException { + return null; + } + + public static ParcelFileDescriptor dup(FileDescriptor orig) throws IOException { + return null; + } + + public ParcelFileDescriptor dup() throws IOException { + return null; + } + + public static ParcelFileDescriptor fromFd(int fd) throws IOException { + return null; + } + + public static ParcelFileDescriptor adoptFd(int fd) { + return null; + } + + public static ParcelFileDescriptor fromSocket(Socket socket) { + return null; + } + + public static ParcelFileDescriptor fromDatagramSocket(DatagramSocket datagramSocket) { + return null; + } + + public static ParcelFileDescriptor[] createPipe() throws IOException { + return null; + } + + public static ParcelFileDescriptor[] createReliablePipe() throws IOException { + return null; + } + + public static ParcelFileDescriptor[] createSocketPair() throws IOException { + return null; + } + + public static ParcelFileDescriptor[] createSocketPair(int type) throws IOException { + return null; + } + + public static ParcelFileDescriptor[] createReliableSocketPair() throws IOException { + return null; + } + + public static ParcelFileDescriptor[] createReliableSocketPair(int type) throws IOException { + return null; + } + + public static ParcelFileDescriptor fromData(byte[] data, String name) throws IOException { + return null; + } + + public static int parseMode(String mode) { + return 0; + } + + public static File getFile(FileDescriptor fd) throws IOException { + return null; + } + + public FileDescriptor getFileDescriptor() { + return null; + } + + public long getStatSize() { + return 0; + } + + public long seekTo(long pos) throws IOException { + return 0; + } + + public int getFd() { + return 0; + } + + public int detachFd() { + return 0; + } + + @Override + public void close() throws IOException {} + + public void closeWithError(String msg) throws IOException {} + + public void releaseResources() {} + + public boolean canDetectErrors() { + return false; + } + + public void checkError() throws IOException {} + + @Override + public String toString() { + return null; + } + + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) {} + + public interface OnCloseListener { + public void onClose(IOException e); + + } + public static class FileDescriptorDetachedException extends IOException { + public FileDescriptorDetachedException() {} + + } +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/os/PatternMatcher.java b/java/ql/test/stubs/google-android-9.0.0/android/os/PatternMatcher.java new file mode 100644 index 00000000000..28e21f65bcd --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/os/PatternMatcher.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.os; + +public class PatternMatcher implements Parcelable { + public PatternMatcher(String pattern, int type) {} + + public final String getPath() { + return null; + } + + public final int getType() { + return 0; + } + + public boolean match(String str) { + return false; + } + + public String toString() { + return null; + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel dest, int flags) {} + + public PatternMatcher(Parcel src) {} + +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/os/RemoteException.java b/java/ql/test/stubs/google-android-9.0.0/android/os/RemoteException.java new file mode 100644 index 00000000000..18c57a49f62 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/os/RemoteException.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.os; + +import android.util.AndroidException; + +public class RemoteException extends AndroidException { + public RemoteException() {} + + public RemoteException(String message) {} + + public RemoteException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) {} + + public RuntimeException rethrowAsRuntimeException() { + return null; + } + + public RuntimeException rethrowFromSystemServer() { + return null; + } + +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/util/AndroidException.java b/java/ql/test/stubs/google-android-9.0.0/android/util/AndroidException.java new file mode 100644 index 00000000000..0263c2fda9d --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/util/AndroidException.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.util; + +public class AndroidException extends Exception { + public AndroidException() {} + + public AndroidException(String name) {} + + public AndroidException(String name, Throwable cause) {} + + public AndroidException(Exception cause) {} + +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/util/ArrayMap.java b/java/ql/test/stubs/google-android-9.0.0/android/util/ArrayMap.java new file mode 100644 index 00000000000..e04103cb29e --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/util/ArrayMap.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.util; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +public final class ArrayMap implements Map { + public static final ArrayMap EMPTY = new ArrayMap<>(-1); + + public ArrayMap() {} + + public ArrayMap(int capacity) {} + + public ArrayMap(int capacity, boolean identityHashCode) {} + + public ArrayMap(ArrayMap map) {} + + @Override + public void clear() {} + + public void erase() {} + + public void ensureCapacity(int minimumCapacity) {} + + @Override + public boolean containsKey(Object key) { + return false; + } + + public int indexOfKey(Object key) { + return 0; + } + + public int indexOfValue(Object value) { + return 0; + } + + @Override + public boolean containsValue(Object value) { + return false; + } + + @Override + public V get(Object key) { + return null; + } + + public K keyAt(int index) { + return null; + } + + public V valueAt(int index) { + return null; + } + + public V setValueAt(int index, V value) { + return null; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public V put(K key, V value) { + return null; + } + + public void append(K key, V value) {} + + public void validate() {} + + public void putAll(ArrayMap array) {} + + @Override + public V remove(Object key) { + return null; + } + + public V removeAt(int index) { + return null; + } + + @Override + public int size() { + return 0; + } + + @Override + public boolean equals(Object object) { + return false; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public String toString() { + return null; + } + + public boolean containsAll(Collection collection) { + return false; + } + + @Override + public void putAll(Map map) {} + + public boolean removeAll(Collection collection) { + return false; + } + + public boolean retainAll(Collection collection) { + return false; + } + + @Override + public Set> entrySet() { + return null; + } + + @Override + public Set keySet() { + return null; + } + + @Override + public Collection values() { + return null; + } + +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/util/Pair.java b/java/ql/test/stubs/google-android-9.0.0/android/util/Pair.java new file mode 100644 index 00000000000..e192dcf6944 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/util/Pair.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package android.util; + +public class Pair { + public Pair(F first, S second) {} + + @Override + public boolean equals(Object o) { + return false; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public String toString() { + return null; + } + + public static Pair create(A a, B b) { + return null; + } + +} diff --git a/java/ql/test/stubs/google-android-9.0.0/androidx/annotation/NonNull.java b/java/ql/test/stubs/google-android-9.0.0/androidx/annotation/NonNull.java new file mode 100644 index 00000000000..d8d30493ed6 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/androidx/annotation/NonNull.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.annotation; + +public @interface NonNull { +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/base/Converter.java b/java/ql/test/stubs/guava-30.0/com/google/common/base/Converter.java index d4e59f3ff91..4d2a445ccf8 100644 --- a/java/ql/test/stubs/guava-30.0/com/google/common/base/Converter.java +++ b/java/ql/test/stubs/guava-30.0/com/google/common/base/Converter.java @@ -1,55 +1,20 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ +// Generated automatically from com.google.common.base.Converter for testing purposes package com.google.common.base; -import org.checkerframework.checker.nullness.qual.Nullable; -public abstract class Converter implements Function { - public final @Nullable B convert(@Nullable A a) { - return null; - } - - public Iterable convertAll(final Iterable fromIterable) { - return null; - } - - public Converter reverse() { - return null; - } - - public final Converter andThen(Converter secondConverter) { - return null; - } - - @Override - public final @Nullable B apply(@Nullable A a) { - return null; - } - - @Override - public boolean equals(@Nullable Object object) { - return false; - } - - public static Converter from( - Function forwardFunction, - Function backwardFunction) { - return null; - } - - public static Converter identity() { - return null; - } +import com.google.common.base.Function; +abstract public class Converter implements Function +{ + protected Converter(){} + protected abstract A doBackward(B p0); + protected abstract B doForward(A p0); + public Converter reverse(){ return null; } + public Iterable convertAll(Iterable p0){ return null; } + public boolean equals(Object p0){ return false; } + public final Converter andThen(Converter p0){ return null; } + public final B apply(A p0){ return null; } + public final B convert(A p0){ return null; } + public static Converter from(Function p0, Function p1){ return null; } + public static Converter identity(){ return null; } } diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/base/Equivalence.java b/java/ql/test/stubs/guava-30.0/com/google/common/base/Equivalence.java new file mode 100644 index 00000000000..f3fe531bf93 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/base/Equivalence.java @@ -0,0 +1,32 @@ +// Generated automatically from com.google.common.base.Equivalence for testing purposes + +package com.google.common.base; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import java.io.Serializable; +import java.util.function.BiPredicate; + +abstract public class Equivalence implements BiPredicate +{ + protected Equivalence(){} + protected abstract boolean doEquivalent(T p0, T p1); + protected abstract int doHash(T p0); + public final Equivalence onResultOf(Function p0){ return null; } + public final Equivalence.Wrapper wrap(S p0){ return null; } + public final Equivalence> pairwise(){ return null; } + public final Predicate equivalentTo(T p0){ return null; } + public final boolean equivalent(T p0, T p1){ return false; } + public final boolean test(T p0, T p1){ return false; } + public final int hash(T p0){ return 0; } + public static Equivalence equals(){ return null; } + public static Equivalence identity(){ return null; } + static public class Wrapper implements Serializable + { + protected Wrapper() {} + public String toString(){ return null; } + public T get(){ return null; } + public boolean equals(Object p0){ return false; } + public int hashCode(){ return 0; } + } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/base/Optional.java b/java/ql/test/stubs/guava-30.0/com/google/common/base/Optional.java index 3f39995651a..7228faa03ab 100644 --- a/java/ql/test/stubs/guava-30.0/com/google/common/base/Optional.java +++ b/java/ql/test/stubs/guava-30.0/com/google/common/base/Optional.java @@ -1,77 +1,31 @@ -/* - * Copyright (C) 2011 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ +// Generated automatically from com.google.common.base.Optional for testing purposes, and manually adjusted. package com.google.common.base; + +import com.google.common.base.Function; +import com.google.common.base.Supplier; import java.io.Serializable; import java.util.Set; -import org.checkerframework.checker.nullness.qual.Nullable; - -public abstract class Optional implements Serializable { - public static Optional absent() { - return null; - } - - public static Optional of(T reference) { - return null; - } - - public static Optional fromNullable(@Nullable T nullableReference) { - return null; - } - - public static @Nullable Optional fromJavaUtil( - java.util.@Nullable Optional javaUtilOptional) { - return null; - } - - public static java.util.@Nullable Optional toJavaUtil( - @Nullable Optional googleOptional) { - return null; - } - - public java.util.Optional toJavaUtil() { - return null; - } - - public abstract boolean isPresent(); - - public abstract T get(); - - public abstract T or(T defaultValue); - - public abstract Optional or(Optional secondChoice); - - public abstract T or(Supplier supplier); - - public abstract @Nullable T orNull(); - - public abstract Set asSet(); - - public abstract Optional transform(Function function); - - @Override - public abstract boolean equals(@Nullable Object object); - - @Override - public abstract int hashCode(); - - @Override - public abstract String toString(); - - public static Iterable presentInstances( - final Iterable> optionals) { - return null; - } +abstract public class Optional implements Serializable +{ + Optional(){} + public java.util.Optional toJavaUtil(){ return null; } + public abstract Optional transform(Function p0); + public abstract Optional or(Optional p0); + public abstract Set asSet(); + public abstract String toString(); + public abstract T get(); + public abstract T or(Supplier p0); + public abstract T or(T p0); + public abstract T orNull(); + public abstract boolean equals(Object p0); + public abstract boolean isPresent(); + public abstract int hashCode(); + public static Iterable presentInstances(Iterable> p0){ return null; } + public static Optional absent(){ return null; } + public static Optional fromJavaUtil(java.util.Optional p0){ return null; } + public static Optional fromNullable(T p0){ return null; } + public static Optional of(T p0){ return null; } + public static java.util.Optional toJavaUtil(Optional p0){ return null; } } diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractListMultimap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractListMultimap.java new file mode 100644 index 00000000000..673bf12660a --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractListMultimap.java @@ -0,0 +1,21 @@ +// Generated automatically from com.google.common.collect.AbstractListMultimap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractMapBasedMultimap; +import com.google.common.collect.ListMultimap; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +abstract class AbstractListMultimap extends AbstractMapBasedMultimap implements ListMultimap +{ + protected AbstractListMultimap() {} + protected AbstractListMultimap(Map> p0){} + public List get(K p0){ return null; } + public List removeAll(Object p0){ return null; } + public List replaceValues(K p0, Iterable p1){ return null; } + public Map> asMap(){ return null; } + public boolean equals(Object p0){ return false; } + public boolean put(K p0, V p1){ return false; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractMapBasedMultimap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractMapBasedMultimap.java new file mode 100644 index 00000000000..81883754e6a --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractMapBasedMultimap.java @@ -0,0 +1,28 @@ +// Generated automatically from com.google.common.collect.AbstractMapBasedMultimap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractMultimap; +import java.io.Serializable; +import java.util.AbstractCollection; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Spliterator; +import java.util.function.BiConsumer; + +abstract class AbstractMapBasedMultimap extends AbstractMultimap implements Serializable +{ + protected AbstractMapBasedMultimap() {} + protected AbstractMapBasedMultimap(Map> p0){} + public Collection> entries(){ return null; } + public Collection get(K p0){ return null; } + public Collection removeAll(Object p0){ return null; } + public Collection replaceValues(K p0, Iterable p1){ return null; } + public Collection values(){ return null; } + public boolean containsKey(Object p0){ return false; } + public boolean put(K p0, V p1){ return false; } + public int size(){ return 0; } + public void clear(){} + public void forEach(BiConsumer p0){} +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractMapBasedMultiset.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractMapBasedMultiset.java new file mode 100644 index 00000000000..85f575c0d00 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractMapBasedMultiset.java @@ -0,0 +1,27 @@ +// Generated automatically from com.google.common.collect.AbstractMapBasedMultiset for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractMultiset; +import com.google.common.collect.Count; +import com.google.common.collect.Multiset; +import java.io.Serializable; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.function.ObjIntConsumer; + +abstract class AbstractMapBasedMultiset extends AbstractMultiset implements Serializable +{ + protected AbstractMapBasedMultiset() {} + protected AbstractMapBasedMultiset(Map p0){} + public Iterator iterator(){ return null; } + public Set> entrySet(){ return null; } + public int add(E p0, int p1){ return 0; } + public int count(Object p0){ return 0; } + public int remove(Object p0, int p1){ return 0; } + public int setCount(E p0, int p1){ return 0; } + public int size(){ return 0; } + public void clear(){} + public void forEachEntry(ObjIntConsumer p0){} +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractMultiset.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractMultiset.java new file mode 100644 index 00000000000..1403d74287b --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractMultiset.java @@ -0,0 +1,29 @@ +// Generated automatically from com.google.common.collect.AbstractMultiset for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.Multiset; +import java.util.AbstractCollection; +import java.util.Collection; +import java.util.Set; + +abstract class AbstractMultiset extends AbstractCollection implements Multiset +{ + public Set elementSet(){ return null; } + public Set> entrySet(){ return null; } + public abstract void clear(); + public boolean contains(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public boolean setCount(E p0, int p1, int p2){ return false; } + public final String toString(){ return null; } + public final boolean add(E p0){ return false; } + public final boolean addAll(Collection p0){ return false; } + public final boolean equals(Object p0){ return false; } + public final boolean remove(Object p0){ return false; } + public final boolean removeAll(Collection p0){ return false; } + public final boolean retainAll(Collection p0){ return false; } + public final int hashCode(){ return 0; } + public int add(E p0, int p1){ return 0; } + public int remove(Object p0, int p1){ return 0; } + public int setCount(E p0, int p1){ return 0; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractSetMultimap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractSetMultimap.java new file mode 100644 index 00000000000..58a869e4061 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractSetMultimap.java @@ -0,0 +1,22 @@ +// Generated automatically from com.google.common.collect.AbstractSetMultimap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractMapBasedMultimap; +import com.google.common.collect.SetMultimap; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +abstract class AbstractSetMultimap extends AbstractMapBasedMultimap implements SetMultimap +{ + protected AbstractSetMultimap() {} + protected AbstractSetMultimap(Map> p0){} + public Map> asMap(){ return null; } + public Set> entries(){ return null; } + public Set get(K p0){ return null; } + public Set removeAll(Object p0){ return null; } + public Set replaceValues(K p0, Iterable p1){ return null; } + public boolean equals(Object p0){ return false; } + public boolean put(K p0, V p1){ return false; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractSortedKeySortedSetMultimap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractSortedKeySortedSetMultimap.java new file mode 100644 index 00000000000..99e7dae3f3c --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractSortedKeySortedSetMultimap.java @@ -0,0 +1,15 @@ +// Generated automatically from com.google.common.collect.AbstractSortedKeySortedSetMultimap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractSortedSetMultimap; +import java.util.Collection; +import java.util.SortedMap; +import java.util.SortedSet; + +abstract class AbstractSortedKeySortedSetMultimap extends AbstractSortedSetMultimap +{ + protected AbstractSortedKeySortedSetMultimap() {} + public SortedMap> asMap(){ return null; } + public SortedSet keySet(){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractSortedMultiset.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractSortedMultiset.java new file mode 100644 index 00000000000..4b9b54003d6 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractSortedMultiset.java @@ -0,0 +1,22 @@ +// Generated automatically from com.google.common.collect.AbstractSortedMultiset for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractMultiset; +import com.google.common.collect.BoundType; +import com.google.common.collect.Multiset; +import com.google.common.collect.SortedMultiset; +import java.util.Comparator; +import java.util.NavigableSet; + +abstract class AbstractSortedMultiset extends AbstractMultiset implements SortedMultiset +{ + public Comparator comparator(){ return null; } + public Multiset.Entry firstEntry(){ return null; } + public Multiset.Entry lastEntry(){ return null; } + public Multiset.Entry pollFirstEntry(){ return null; } + public Multiset.Entry pollLastEntry(){ return null; } + public NavigableSet elementSet(){ return null; } + public SortedMultiset descendingMultiset(){ return null; } + public SortedMultiset subMultiset(E p0, BoundType p1, E p2, BoundType p3){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractSortedSetMultimap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractSortedSetMultimap.java new file mode 100644 index 00000000000..00d6491a2ca --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractSortedSetMultimap.java @@ -0,0 +1,20 @@ +// Generated automatically from com.google.common.collect.AbstractSortedSetMultimap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractSetMultimap; +import com.google.common.collect.SortedSetMultimap; +import java.util.Collection; +import java.util.Map; +import java.util.SortedSet; + +abstract class AbstractSortedSetMultimap extends AbstractSetMultimap implements SortedSetMultimap +{ + protected AbstractSortedSetMultimap() {} + protected AbstractSortedSetMultimap(Map> p0){} + public Collection values(){ return null; } + public Map> asMap(){ return null; } + public SortedSet get(K p0){ return null; } + public SortedSet removeAll(Object p0){ return null; } + public SortedSet replaceValues(K p0, Iterable p1){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractTable.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractTable.java index 9003783bab9..64ca3131671 100644 --- a/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractTable.java +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractTable.java @@ -1,90 +1,28 @@ -/* - * Copyright (C) 2013 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ +// Generated automatically from com.google.common.collect.AbstractTable for testing purposes package com.google.common.collect; +import com.google.common.collect.Table; import java.util.Collection; -import java.util.Map; import java.util.Set; -abstract class AbstractTable implements Table { - @Override - public boolean containsRow(Object rowKey) { - return false; - } - - @Override - public boolean containsColumn(Object columnKey) { - return false; - } - - @Override - public Set rowKeySet() { - return null; - } - - @Override - public Set columnKeySet() { - return null; - } - - @Override - public boolean containsValue(Object value) { - return false; - } - - @Override - public boolean contains(Object rowKey, Object columnKey) { - return false; - } - - @Override - public V get(Object rowKey, Object columnKey) { - return null; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public void clear() { - } - - @Override - public V remove(Object rowKey, Object columnKey) { - return null; - } - - @Override - public V put(R rowKey, C columnKey, V value) { - return null; - } - - @Override - public void putAll(Table table) { - } - - @Override - public Set> cellSet() { - return null; - } - - @Override - public Collection values() { - return null; - } - +abstract class AbstractTable implements Table +{ + public Collection values(){ return null; } + public Set columnKeySet(){ return null; } + public Set rowKeySet(){ return null; } + public Set> cellSet(){ return null; } + public String toString(){ return null; } + public V get(Object p0, Object p1){ return null; } + public V put(R p0, C p1, V p2){ return null; } + public V remove(Object p0, Object p1){ return null; } + public boolean contains(Object p0, Object p1){ return false; } + public boolean containsColumn(Object p0){ return false; } + public boolean containsRow(Object p0){ return false; } + public boolean containsValue(Object p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public int hashCode(){ return 0; } + public void clear(){} + public void putAll(Table p0){} } diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ArrayListMultimap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ArrayListMultimap.java new file mode 100644 index 00000000000..3e985271163 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ArrayListMultimap.java @@ -0,0 +1,15 @@ +// Generated automatically from com.google.common.collect.ArrayListMultimap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.ArrayListMultimapGwtSerializationDependencies; +import com.google.common.collect.Multimap; + +public class ArrayListMultimap extends ArrayListMultimapGwtSerializationDependencies +{ + protected ArrayListMultimap() {} + public static ArrayListMultimap create(){ return null; } + public static ArrayListMultimap create(Multimap p0){ return null; } + public static ArrayListMultimap create(int p0, int p1){ return null; } + public void trimToSize(){} +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ArrayListMultimapGwtSerializationDependencies.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ArrayListMultimapGwtSerializationDependencies.java new file mode 100644 index 00000000000..9cb4c8f0c51 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ArrayListMultimapGwtSerializationDependencies.java @@ -0,0 +1,10 @@ +// Generated automatically from com.google.common.collect.ArrayListMultimapGwtSerializationDependencies for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractListMultimap; + +abstract class ArrayListMultimapGwtSerializationDependencies extends AbstractListMultimap +{ + protected ArrayListMultimapGwtSerializationDependencies() {} +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ArrayTable.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ArrayTable.java new file mode 100644 index 00000000000..32543b5bc6a --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ArrayTable.java @@ -0,0 +1,45 @@ +// Generated automatically from com.google.common.collect.ArrayTable for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractTable; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Table; +import java.io.Serializable; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +public class ArrayTable extends AbstractTable implements Serializable +{ + protected ArrayTable() {} + public Collection values(){ return null; } + public ImmutableList columnKeyList(){ return null; } + public ImmutableList rowKeyList(){ return null; } + public ImmutableSet columnKeySet(){ return null; } + public ImmutableSet rowKeySet(){ return null; } + public Map> columnMap(){ return null; } + public Map row(R p0){ return null; } + public Map> rowMap(){ return null; } + public Map column(C p0){ return null; } + public Set> cellSet(){ return null; } + public V at(int p0, int p1){ return null; } + public V erase(Object p0, Object p1){ return null; } + public V get(Object p0, Object p1){ return null; } + public V put(R p0, C p1, V p2){ return null; } + public V remove(Object p0, Object p1){ return null; } + public V set(int p0, int p1, V p2){ return null; } + public V[][] toArray(Class p0){ return null; } + public boolean contains(Object p0, Object p1){ return false; } + public boolean containsColumn(Object p0){ return false; } + public boolean containsRow(Object p0){ return false; } + public boolean containsValue(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public int size(){ return 0; } + public static ArrayTable create(Iterable p0, Iterable p1){ return null; } + public static ArrayTable create(Table p0){ return null; } + public void clear(){} + public void eraseAll(){} + public void putAll(Table p0){} +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/BiMap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/BiMap.java new file mode 100644 index 00000000000..00e7a90086b --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/BiMap.java @@ -0,0 +1,15 @@ +// Generated automatically from com.google.common.collect.BiMap for testing purposes + +package com.google.common.collect; + +import java.util.Map; +import java.util.Set; + +public interface BiMap extends Map +{ + BiMap inverse(); + Set values(); + V forcePut(K p0, V p1); + V put(K p0, V p1); + void putAll(Map p0); +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/BoundType.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/BoundType.java new file mode 100644 index 00000000000..dda52f260dd --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/BoundType.java @@ -0,0 +1,10 @@ +// Generated automatically from com.google.common.collect.BoundType for testing purposes + +package com.google.common.collect; + + +public enum BoundType +{ + CLOSED, OPEN; + private BoundType() {} +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ClassToInstanceMap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ClassToInstanceMap.java new file mode 100644 index 00000000000..53dca6fb602 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ClassToInstanceMap.java @@ -0,0 +1,11 @@ +// Generated automatically from com.google.common.collect.ClassToInstanceMap for testing purposes + +package com.google.common.collect; + +import java.util.Map; + +public interface ClassToInstanceMap extends Map, B> +{ + T getInstance(Class p0); + T putInstance(Class p0, T p1); +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Collections2.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Collections2.java new file mode 100644 index 00000000000..12b85b66058 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Collections2.java @@ -0,0 +1,19 @@ +// Generated automatically from com.google.common.collect.Collections2 for testing purposes + +package com.google.common.collect; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; + +public class Collections2 +{ + protected Collections2() {} + public static > Collection> orderedPermutations(Iterable p0){ return null; } + public static Collection filter(Collection p0, Predicate p1){ return null; } + public static Collection> orderedPermutations(Iterable p0, Comparator p1){ return null; } + public static Collection> permutations(Collection p0){ return null; } + public static Collection transform(Collection p0, Function p1){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ConcurrentHashMultiset.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ConcurrentHashMultiset.java new file mode 100644 index 00000000000..8eeff3c5792 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ConcurrentHashMultiset.java @@ -0,0 +1,32 @@ +// Generated automatically from com.google.common.collect.ConcurrentHashMultiset for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractMultiset; +import com.google.common.collect.Multiset; +import java.io.Serializable; +import java.util.Iterator; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; + +public class ConcurrentHashMultiset extends AbstractMultiset implements Serializable +{ + protected ConcurrentHashMultiset() {} + public T[] toArray(T[] p0){ return null; } + public Iterator iterator(){ return null; } + public Object[] toArray(){ return null; } + public Set> createEntrySet(){ return null; } + public boolean isEmpty(){ return false; } + public boolean removeExactly(Object p0, int p1){ return false; } + public boolean setCount(E p0, int p1, int p2){ return false; } + public int add(E p0, int p1){ return 0; } + public int count(Object p0){ return 0; } + public int remove(Object p0, int p1){ return 0; } + public int setCount(E p0, int p1){ return 0; } + public int size(){ return 0; } + public static ConcurrentHashMultiset create(){ return null; } + public static ConcurrentHashMultiset create(ConcurrentMap p0){ return null; } + public static ConcurrentHashMultiset create(Iterable p0){ return null; } + public void clear(){} +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Count.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Count.java new file mode 100644 index 00000000000..a49c1849e0a --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Count.java @@ -0,0 +1,18 @@ +// Generated automatically from com.google.common.collect.Count for testing purposes + +package com.google.common.collect; + +import java.io.Serializable; + +class Count implements Serializable +{ + protected Count() {} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public int addAndGet(int p0){ return 0; } + public int get(){ return 0; } + public int getAndSet(int p0){ return 0; } + public int hashCode(){ return 0; } + public void add(int p0){} + public void set(int p0){} +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Cut.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Cut.java new file mode 100644 index 00000000000..ae1d3e14bc7 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Cut.java @@ -0,0 +1,13 @@ +// Generated automatically from com.google.common.collect.Cut for testing purposes + +package com.google.common.collect; + +import java.io.Serializable; + +abstract class Cut implements Comparable>, Serializable +{ + protected Cut() {} + public abstract int hashCode(); + public boolean equals(Object p0){ return false; } + public int compareTo(Cut p0){ return 0; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/DiscreteDomain.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/DiscreteDomain.java new file mode 100644 index 00000000000..6eb3681e382 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/DiscreteDomain.java @@ -0,0 +1,18 @@ +// Generated automatically from com.google.common.collect.DiscreteDomain for testing purposes + +package com.google.common.collect; + +import java.math.BigInteger; + +abstract public class DiscreteDomain +{ + protected DiscreteDomain(){} + public C maxValue(){ return null; } + public C minValue(){ return null; } + public abstract C next(C p0); + public abstract C previous(C p0); + public abstract long distance(C p0, C p1); + public static DiscreteDomain bigIntegers(){ return null; } + public static DiscreteDomain integers(){ return null; } + public static DiscreteDomain longs(){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ForwardingMap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ForwardingMap.java new file mode 100644 index 00000000000..bcb15cec45e --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ForwardingMap.java @@ -0,0 +1,37 @@ +// Generated automatically from com.google.common.collect.ForwardingMap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.ForwardingObject; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +abstract public class ForwardingMap extends ForwardingObject implements Map +{ + protected ForwardingMap(){} + protected String standardToString(){ return null; } + protected V standardRemove(Object p0){ return null; } + protected abstract Map delegate(); + protected boolean standardContainsKey(Object p0){ return false; } + protected boolean standardContainsValue(Object p0){ return false; } + protected boolean standardEquals(Object p0){ return false; } + protected boolean standardIsEmpty(){ return false; } + protected int standardHashCode(){ return 0; } + protected void standardClear(){} + protected void standardPutAll(Map p0){} + public Collection values(){ return null; } + public Set keySet(){ return null; } + public Set> entrySet(){ return null; } + public V get(Object p0){ return null; } + public V put(K p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public boolean containsKey(Object p0){ return false; } + public boolean containsValue(Object p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public int hashCode(){ return 0; } + public int size(){ return 0; } + public void clear(){} + public void putAll(Map p0){} +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ForwardingObject.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ForwardingObject.java new file mode 100644 index 00000000000..54cf8f64689 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ForwardingObject.java @@ -0,0 +1,11 @@ +// Generated automatically from com.google.common.collect.ForwardingObject for testing purposes + +package com.google.common.collect; + + +abstract public class ForwardingObject +{ + protected ForwardingObject(){} + protected abstract Object delegate(); + public String toString(){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/GeneralRange.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/GeneralRange.java new file mode 100644 index 00000000000..acf8f6bc9c9 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/GeneralRange.java @@ -0,0 +1,34 @@ +// Generated automatically from com.google.common.collect.GeneralRange for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.BoundType; +import com.google.common.collect.Range; +import java.io.Serializable; +import java.util.Comparator; + +class GeneralRange implements Serializable +{ + protected GeneralRange() {} + BoundType getLowerBoundType(){ return null; } + BoundType getUpperBoundType(){ return null; } + Comparator comparator(){ return null; } + GeneralRange intersect(GeneralRange p0){ return null; } + GeneralRange reverse(){ return null; } + T getLowerEndpoint(){ return null; } + T getUpperEndpoint(){ return null; } + boolean contains(T p0){ return false; } + boolean hasLowerBound(){ return false; } + boolean hasUpperBound(){ return false; } + boolean isEmpty(){ return false; } + boolean tooHigh(T p0){ return false; } + boolean tooLow(T p0){ return false; } + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public int hashCode(){ return 0; } + static GeneralRange from(Range p0){ return null; } + static GeneralRange all(Comparator p0){ return null; } + static GeneralRange downTo(Comparator p0, T p1, BoundType p2){ return null; } + static GeneralRange range(Comparator p0, T p1, BoundType p2, T p3, BoundType p4){ return null; } + static GeneralRange upTo(Comparator p0, T p1, BoundType p2){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/HashBasedTable.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/HashBasedTable.java new file mode 100644 index 00000000000..6284328c191 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/HashBasedTable.java @@ -0,0 +1,24 @@ +// Generated automatically from com.google.common.collect.HashBasedTable for testing purposes + +package com.google.common.collect; + +import com.google.common.base.Supplier; +import com.google.common.collect.StandardTable; +import com.google.common.collect.Table; +import java.io.Serializable; +import java.util.Map; + +public class HashBasedTable extends StandardTable +{ + protected HashBasedTable() {} + public V get(Object p0, Object p1){ return null; } + public V remove(Object p0, Object p1){ return null; } + public boolean contains(Object p0, Object p1){ return false; } + public boolean containsColumn(Object p0){ return false; } + public boolean containsRow(Object p0){ return false; } + public boolean containsValue(Object p0){ return false; } + public boolean equals(Object p0){ return false; } + public static HashBasedTable create(){ return null; } + public static HashBasedTable create(Table p0){ return null; } + public static HashBasedTable create(int p0, int p1){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/HashBiMap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/HashBiMap.java new file mode 100644 index 00000000000..ec5fd73b93f --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/HashBiMap.java @@ -0,0 +1,32 @@ +// Generated automatically from com.google.common.collect.HashBiMap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.BiMap; +import com.google.common.collect.Maps; +import java.io.Serializable; +import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; + +public class HashBiMap extends Maps.IteratorBasedAbstractMap implements BiMap, Serializable +{ + protected HashBiMap() {} + public BiMap inverse(){ return null; } + public Set keySet(){ return null; } + public Set values(){ return null; } + public V forcePut(K p0, V p1){ return null; } + public V get(Object p0){ return null; } + public V put(K p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public boolean containsKey(Object p0){ return false; } + public boolean containsValue(Object p0){ return false; } + public int size(){ return 0; } + public static HashBiMap create(){ return null; } + public static HashBiMap create(Map p0){ return null; } + public static HashBiMap create(int p0){ return null; } + public void clear(){} + public void forEach(BiConsumer p0){} + public void replaceAll(BiFunction p0){} +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/HashMultimap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/HashMultimap.java new file mode 100644 index 00000000000..69ff1caa89f --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/HashMultimap.java @@ -0,0 +1,14 @@ +// Generated automatically from com.google.common.collect.HashMultimap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.HashMultimapGwtSerializationDependencies; +import com.google.common.collect.Multimap; + +public class HashMultimap extends HashMultimapGwtSerializationDependencies +{ + protected HashMultimap() {} + public static HashMultimap create(){ return null; } + public static HashMultimap create(Multimap p0){ return null; } + public static HashMultimap create(int p0, int p1){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/HashMultimapGwtSerializationDependencies.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/HashMultimapGwtSerializationDependencies.java new file mode 100644 index 00000000000..9ff6310fa70 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/HashMultimapGwtSerializationDependencies.java @@ -0,0 +1,10 @@ +// Generated automatically from com.google.common.collect.HashMultimapGwtSerializationDependencies for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractSetMultimap; + +abstract class HashMultimapGwtSerializationDependencies extends AbstractSetMultimap +{ + protected HashMultimapGwtSerializationDependencies() {} +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/HashMultiset.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/HashMultiset.java new file mode 100644 index 00000000000..38d026f45fc --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/HashMultiset.java @@ -0,0 +1,13 @@ +// Generated automatically from com.google.common.collect.HashMultiset for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractMapBasedMultiset; + +public class HashMultiset extends AbstractMapBasedMultiset +{ + protected HashMultiset() {} + public static HashMultiset create(){ return null; } + public static HashMultiset create(Iterable p0){ return null; } + public static HashMultiset create(int p0){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableBiMap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableBiMap.java new file mode 100644 index 00000000000..b573c4aad0c --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableBiMap.java @@ -0,0 +1,40 @@ +// Generated automatically from com.google.common.collect.ImmutableBiMap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.BiMap; +import com.google.common.collect.ImmutableBiMapFauxverideShim; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import java.util.Comparator; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collector; + +abstract public class ImmutableBiMap extends ImmutableBiMapFauxverideShim implements BiMap +{ + public ImmutableSet values(){ return null; } + public abstract ImmutableBiMap inverse(); + public final V forcePut(K p0, V p1){ return null; } + public static ImmutableBiMap.Builder builder(){ return null; } + public static ImmutableBiMap.Builder builderWithExpectedSize(int p0){ return null; } + public static ImmutableBiMap copyOf(Iterable> p0){ return null; } + public static ImmutableBiMap copyOf(Map p0){ return null; } + public static ImmutableBiMap of(){ return null; } + public static ImmutableBiMap of(K p0, V p1){ return null; } + public static ImmutableBiMap of(K p0, V p1, K p2, V p3){ return null; } + public static ImmutableBiMap of(K p0, V p1, K p2, V p3, K p4, V p5){ return null; } + public static ImmutableBiMap of(K p0, V p1, K p2, V p3, K p4, V p5, K p6, V p7){ return null; } + public static ImmutableBiMap of(K p0, V p1, K p2, V p3, K p4, V p5, K p6, V p7, K p8, V p9){ return null; } + public static Collector> toImmutableBiMap(Function p0, Function p1){ return null; } + static public class Builder extends ImmutableMap.Builder + { + public Builder(){} + public ImmutableBiMap.Builder orderEntriesByValue(Comparator p0){ return null; } + public ImmutableBiMap.Builder put(K p0, V p1){ return null; } + public ImmutableBiMap.Builder put(Map.Entry p0){ return null; } + public ImmutableBiMap.Builder putAll(Iterable> p0){ return null; } + public ImmutableBiMap.Builder putAll(Map p0){ return null; } + public ImmutableBiMap build(){ return null; } + } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableBiMapFauxverideShim.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableBiMapFauxverideShim.java new file mode 100644 index 00000000000..d55d3be8d28 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableBiMapFauxverideShim.java @@ -0,0 +1,14 @@ +// Generated automatically from com.google.common.collect.ImmutableBiMapFauxverideShim for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.ImmutableMap; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.stream.Collector; + +abstract class ImmutableBiMapFauxverideShim extends ImmutableMap +{ + public static Collector> toImmutableMap(Function p0, Function p1){ return null; } + public static Collector> toImmutableMap(Function p0, Function p1, BinaryOperator p2){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableClassToInstanceMap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableClassToInstanceMap.java new file mode 100644 index 00000000000..2fd624f570a --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableClassToInstanceMap.java @@ -0,0 +1,27 @@ +// Generated automatically from com.google.common.collect.ImmutableClassToInstanceMap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.ClassToInstanceMap; +import com.google.common.collect.ForwardingMap; +import java.io.Serializable; +import java.util.Map; + +public class ImmutableClassToInstanceMap extends ForwardingMap, B> implements ClassToInstanceMap, Serializable +{ + protected ImmutableClassToInstanceMap() {} + protected Map, B> delegate(){ return null; } + public T getInstance(Class p0){ return null; } + public T putInstance(Class p0, T p1){ return null; } + public static ImmutableClassToInstanceMap copyOf(Map, ? extends S> p0){ return null; } + public static ImmutableClassToInstanceMap of(Class p0, T p1){ return null; } + public static ImmutableClassToInstanceMap.Builder builder(){ return null; } + public static ImmutableClassToInstanceMap of(){ return null; } + static public class Builder + { + public ImmutableClassToInstanceMap.Builder put(Class p0, T p1){ return null; } + public ImmutableClassToInstanceMap.Builder putAll(Map, ? extends T> p0){ return null; } + public Builder(){} + public ImmutableClassToInstanceMap build(){ return null; } + } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableListMultimap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableListMultimap.java new file mode 100644 index 00000000000..b8df07aa844 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableListMultimap.java @@ -0,0 +1,46 @@ +// Generated automatically from com.google.common.collect.ImmutableListMultimap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ListMultimap; +import com.google.common.collect.Multimap; +import java.util.Comparator; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collector; +import java.util.stream.Stream; + +public class ImmutableListMultimap extends ImmutableMultimap implements ListMultimap +{ + protected ImmutableListMultimap() {} + public ImmutableList get(K p0){ return null; } + public ImmutableListMultimap inverse(){ return null; } + public final ImmutableList removeAll(Object p0){ return null; } + public final ImmutableList replaceValues(K p0, Iterable p1){ return null; } + public static ImmutableListMultimap.Builder builder(){ return null; } + public static ImmutableListMultimap copyOf(Iterable> p0){ return null; } + public static ImmutableListMultimap copyOf(Multimap p0){ return null; } + public static ImmutableListMultimap of(){ return null; } + public static ImmutableListMultimap of(K p0, V p1){ return null; } + public static ImmutableListMultimap of(K p0, V p1, K p2, V p3){ return null; } + public static ImmutableListMultimap of(K p0, V p1, K p2, V p3, K p4, V p5){ return null; } + public static ImmutableListMultimap of(K p0, V p1, K p2, V p3, K p4, V p5, K p6, V p7){ return null; } + public static ImmutableListMultimap of(K p0, V p1, K p2, V p3, K p4, V p5, K p6, V p7, K p8, V p9){ return null; } + public static Collector> flatteningToImmutableListMultimap(Function p0, Function> p1){ return null; } + public static Collector> toImmutableListMultimap(Function p0, Function p1){ return null; } + static public class Builder extends ImmutableMultimap.Builder + { + public Builder(){} + public ImmutableListMultimap.Builder orderKeysBy(Comparator p0){ return null; } + public ImmutableListMultimap.Builder orderValuesBy(Comparator p0){ return null; } + public ImmutableListMultimap.Builder put(K p0, V p1){ return null; } + public ImmutableListMultimap.Builder put(Map.Entry p0){ return null; } + public ImmutableListMultimap.Builder putAll(Iterable> p0){ return null; } + public ImmutableListMultimap.Builder putAll(K p0, Iterable p1){ return null; } + public ImmutableListMultimap.Builder putAll(K p0, V... p1){ return null; } + public ImmutableListMultimap.Builder putAll(Multimap p0){ return null; } + public ImmutableListMultimap build(){ return null; } + } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedMap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedMap.java index dc3bfd49083..a88c9d79376 100644 --- a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedMap.java +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedMap.java @@ -1,105 +1,79 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Generated automatically from com.google.common.collect.ImmutableSortedMap for testing purposes package com.google.common.collect; +import com.google.common.collect.ImmutableCollection; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSortedMapFauxverideShim; +import com.google.common.collect.ImmutableSortedSet; import java.util.Comparator; import java.util.Map; +import java.util.NavigableMap; import java.util.SortedMap; +import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.stream.Collector; -public final class ImmutableSortedMap extends ImmutableMap{ - - public static ImmutableSortedMap of() { - return null; - } - - public static , V> ImmutableSortedMap of(K k1, V v1) { - return null; - } - - public static , V> ImmutableSortedMap of( - K k1, V v1, K k2, V v2) { - return null; - } - - public static , V> ImmutableSortedMap of( - K k1, V v1, K k2, V v2, K k3, V v3) { - return null; - } - - public static , V> ImmutableSortedMap of( - K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { - return null; - } - - public static , V> ImmutableSortedMap of( - K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { - return null; - } - - public static ImmutableSortedMap copyOf(Map map) { - return null; - } - - public static ImmutableSortedMap copyOf( - Map map, Comparator comparator) { - return null; - } - - public static ImmutableSortedMap copyOf( - Iterable> entries) { - return null; - } - - public static ImmutableSortedMap copyOf( - Iterable> entries, - Comparator comparator) { - return null; - } - - public static ImmutableSortedMap copyOfSorted(SortedMap map) { - return null; - } - - @Override - public V get(Object key) { - return null; - } - - @Override - public int size() { - return 0; - } - - public static , V> Builder naturalOrder() { - return null; - } - - public static Builder orderedBy(Comparator comparator) { - return null; - } - - public static , V> Builder reverseOrder() { - return null; - } - - public static class Builder extends ImmutableMap.Builder { - public Builder(Comparator comparator) { +public class ImmutableSortedMap extends ImmutableSortedMapFauxverideShim implements NavigableMap +{ + protected ImmutableSortedMap() {} + public Comparator comparator(){ return null; } + public ImmutableCollection values(){ return null; } + public ImmutableSet> entrySet(){ return null; } + public ImmutableSortedMap descendingMap(){ return null; } + public ImmutableSortedMap headMap(K p0){ return null; } + public ImmutableSortedMap headMap(K p0, boolean p1){ return null; } + public ImmutableSortedMap subMap(K p0, K p1){ return null; } + public ImmutableSortedMap subMap(K p0, boolean p1, K p2, boolean p3){ return null; } + public ImmutableSortedMap tailMap(K p0){ return null; } + public ImmutableSortedMap tailMap(K p0, boolean p1){ return null; } + public ImmutableSortedSet descendingKeySet(){ return null; } + public ImmutableSortedSet keySet(){ return null; } + public ImmutableSortedSet navigableKeySet(){ return null; } + public K ceilingKey(K p0){ return null; } + public K firstKey(){ return null; } + public K floorKey(K p0){ return null; } + public K higherKey(K p0){ return null; } + public K lastKey(){ return null; } + public K lowerKey(K p0){ return null; } + public Map.Entry ceilingEntry(K p0){ return null; } + public Map.Entry firstEntry(){ return null; } + public Map.Entry floorEntry(K p0){ return null; } + public Map.Entry higherEntry(K p0){ return null; } + public Map.Entry lastEntry(){ return null; } + public Map.Entry lowerEntry(K p0){ return null; } + public V get(Object p0){ return null; } + public final Map.Entry pollFirstEntry(){ return null; } + public final Map.Entry pollLastEntry(){ return null; } + public int size(){ return 0; } + public static , V> ImmutableSortedMap.Builder naturalOrder(){ return null; } + public static , V> ImmutableSortedMap.Builder reverseOrder(){ return null; } + public static , V> ImmutableSortedMap of(K p0, V p1){ return null; } + public static , V> ImmutableSortedMap of(K p0, V p1, K p2, V p3){ return null; } + public static , V> ImmutableSortedMap of(K p0, V p1, K p2, V p3, K p4, V p5){ return null; } + public static , V> ImmutableSortedMap of(K p0, V p1, K p2, V p3, K p4, V p5, K p6, V p7){ return null; } + public static , V> ImmutableSortedMap of(K p0, V p1, K p2, V p3, K p4, V p5, K p6, V p7, K p8, V p9){ return null; } + public static ImmutableSortedMap.Builder orderedBy(Comparator p0){ return null; } + public static ImmutableSortedMap copyOf(Iterable> p0){ return null; } + public static ImmutableSortedMap copyOf(Iterable> p0, Comparator p1){ return null; } + public static ImmutableSortedMap copyOf(Map p0){ return null; } + public static ImmutableSortedMap copyOf(Map p0, Comparator p1){ return null; } + public static ImmutableSortedMap copyOfSorted(SortedMap p0){ return null; } + public static ImmutableSortedMap of(){ return null; } + public static Collector> toImmutableSortedMap(Comparator p0, Function p1, Function p2){ return null; } + public static Collector> toImmutableSortedMap(Comparator p0, Function p1, Function p2, BinaryOperator p3){ return null; } + public void forEach(BiConsumer p0){} + static public class Builder extends ImmutableMap.Builder + { + protected Builder() {} + public Builder(Comparator p0){} + public ImmutableSortedMap.Builder put(K p0, V p1){ return null; } + public ImmutableSortedMap.Builder put(Map.Entry p0){ return null; } + public ImmutableSortedMap.Builder putAll(Iterable> p0){ return null; } + public ImmutableSortedMap.Builder putAll(Map p0){ return null; } + public ImmutableSortedMap build(){ return null; } + public final ImmutableSortedMap.Builder orderEntriesByValue(Comparator p0){ return null; } } - - } - } diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedMapFauxverideShim.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedMapFauxverideShim.java new file mode 100644 index 00000000000..c09533487b1 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedMapFauxverideShim.java @@ -0,0 +1,22 @@ +// Generated automatically from com.google.common.collect.ImmutableSortedMapFauxverideShim for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSortedMap; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.stream.Collector; + +abstract class ImmutableSortedMapFauxverideShim extends ImmutableMap +{ + public static ImmutableSortedMap.Builder builder(){ return null; } + public static ImmutableSortedMap.Builder builderWithExpectedSize(int p0){ return null; } + public static ImmutableSortedMap of(K p0, V p1){ return null; } + public static ImmutableSortedMap of(K p0, V p1, K p2, V p3){ return null; } + public static ImmutableSortedMap of(K p0, V p1, K p2, V p3, K p4, V p5){ return null; } + public static ImmutableSortedMap of(K p0, V p1, K p2, V p3, K p4, V p5, K p6, V p7){ return null; } + public static ImmutableSortedMap of(K p0, V p1, K p2, V p3, K p4, V p5, K p6, V p7, K p8, V p9){ return null; } + public static Collector> toImmutableMap(Function p0, Function p1){ return null; } + public static Collector> toImmutableMap(Function p0, Function p1, BinaryOperator p2){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedMultiset.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedMultiset.java new file mode 100644 index 00000000000..fc068de4215 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedMultiset.java @@ -0,0 +1,57 @@ +// Generated automatically from com.google.common.collect.ImmutableSortedMultiset for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.BoundType; +import com.google.common.collect.ImmutableMultiset; +import com.google.common.collect.ImmutableSortedMultisetFauxverideShim; +import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.Multiset; +import com.google.common.collect.SortedMultiset; +import java.util.Comparator; +import java.util.Iterator; +import java.util.function.Function; +import java.util.function.ToIntFunction; +import java.util.stream.Collector; + +abstract public class ImmutableSortedMultiset extends ImmutableSortedMultisetFauxverideShim implements SortedMultiset +{ + public ImmutableSortedMultiset descendingMultiset(){ return null; } + public ImmutableSortedMultiset subMultiset(E p0, BoundType p1, E p2, BoundType p3){ return null; } + public abstract ImmutableSortedMultiset headMultiset(E p0, BoundType p1); + public abstract ImmutableSortedMultiset tailMultiset(E p0, BoundType p1); + public abstract ImmutableSortedSet elementSet(); + public final Comparator comparator(){ return null; } + public final Multiset.Entry pollFirstEntry(){ return null; } + public final Multiset.Entry pollLastEntry(){ return null; } + public static > ImmutableSortedMultiset.Builder naturalOrder(){ return null; } + public static > ImmutableSortedMultiset.Builder reverseOrder(){ return null; } + public static > ImmutableSortedMultiset copyOf(E[] p0){ return null; } + public static > ImmutableSortedMultiset of(E p0){ return null; } + public static > ImmutableSortedMultiset of(E p0, E p1){ return null; } + public static > ImmutableSortedMultiset of(E p0, E p1, E p2){ return null; } + public static > ImmutableSortedMultiset of(E p0, E p1, E p2, E p3){ return null; } + public static > ImmutableSortedMultiset of(E p0, E p1, E p2, E p3, E p4){ return null; } + public static > ImmutableSortedMultiset of(E p0, E p1, E p2, E p3, E p4, E p5, E... p6){ return null; } + public static Collector> toImmutableSortedMultiset(Comparator p0){ return null; } + public static ImmutableSortedMultiset.Builder orderedBy(Comparator p0){ return null; } + public static ImmutableSortedMultiset copyOf(Comparator p0, Iterable p1){ return null; } + public static ImmutableSortedMultiset copyOf(Comparator p0, Iterator p1){ return null; } + public static ImmutableSortedMultiset copyOf(Iterable p0){ return null; } + public static ImmutableSortedMultiset copyOf(Iterator p0){ return null; } + public static ImmutableSortedMultiset copyOfSorted(SortedMultiset p0){ return null; } + public static ImmutableSortedMultiset of(){ return null; } + public static Collector> toImmutableSortedMultiset(Comparator p0, Function p1, ToIntFunction p2){ return null; } + static public class Builder extends ImmutableMultiset.Builder + { + protected Builder() {} + public Builder(Comparator p0){} + public ImmutableSortedMultiset.Builder add(E p0){ return null; } + public ImmutableSortedMultiset.Builder add(E... p0){ return null; } + public ImmutableSortedMultiset.Builder addAll(Iterable p0){ return null; } + public ImmutableSortedMultiset.Builder addAll(Iterator p0){ return null; } + public ImmutableSortedMultiset.Builder addCopies(E p0, int p1){ return null; } + public ImmutableSortedMultiset.Builder setCount(E p0, int p1){ return null; } + public ImmutableSortedMultiset build(){ return null; } + } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedMultisetFauxverideShim.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedMultisetFauxverideShim.java new file mode 100644 index 00000000000..85af2f484d6 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedMultisetFauxverideShim.java @@ -0,0 +1,23 @@ +// Generated automatically from com.google.common.collect.ImmutableSortedMultisetFauxverideShim for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.ImmutableMultiset; +import com.google.common.collect.ImmutableSortedMultiset; +import java.util.function.Function; +import java.util.function.ToIntFunction; +import java.util.stream.Collector; + +abstract class ImmutableSortedMultisetFauxverideShim extends ImmutableMultiset +{ + public static Collector> toImmutableMultiset(){ return null; } + public static ImmutableSortedMultiset.Builder builder(){ return null; } + public static ImmutableSortedMultiset copyOf(E[] p0){ return null; } + public static ImmutableSortedMultiset of(E p0){ return null; } + public static ImmutableSortedMultiset of(E p0, E p1){ return null; } + public static ImmutableSortedMultiset of(E p0, E p1, E p2){ return null; } + public static ImmutableSortedMultiset of(E p0, E p1, E p2, E p3){ return null; } + public static ImmutableSortedMultiset of(E p0, E p1, E p2, E p3, E p4){ return null; } + public static ImmutableSortedMultiset of(E p0, E p1, E p2, E p3, E p4, E p5, E... p6){ return null; } + public static Collector> toImmutableMultiset(Function p0, ToIntFunction p1){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedSet.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedSet.java index fb22c85b5ef..92cfc939d96 100644 --- a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedSet.java +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedSet.java @@ -1,111 +1,68 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Generated automatically from com.google.common.collect.ImmutableSortedSet for testing purposes package com.google.common.collect; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSortedSetFauxverideShim; +import com.google.common.collect.SortedIterable; +import com.google.common.collect.UnmodifiableIterator; import java.util.Collection; import java.util.Comparator; import java.util.Iterator; import java.util.NavigableSet; import java.util.SortedSet; +import java.util.Spliterator; +import java.util.stream.Collector; -public abstract class ImmutableSortedSet extends ImmutableSet - implements NavigableSet { - - public static ImmutableSortedSet of() { - return null; - } - - public static > ImmutableSortedSet of(E element) { - return null; - } - - public static > ImmutableSortedSet of(E e1, E e2) { - return null; - } - - public static > ImmutableSortedSet of(E e1, E e2, E e3) { - return null; - } - - public static > ImmutableSortedSet of(E e1, E e2, E e3, E e4) { - return null; - } - - public static > ImmutableSortedSet of( - E e1, E e2, E e3, E e4, E e5) { - return null; - } - - public static > ImmutableSortedSet of( - E e1, E e2, E e3, E e4, E e5, E e6, E... remaining) { - return null; - } - - public static > ImmutableSortedSet copyOf(E[] elements) { - return null; - } - - public static ImmutableSortedSet copyOf(Iterable elements) { - return null; - } - - public static ImmutableSortedSet copyOf(Collection elements) { - return null; - } - - public static ImmutableSortedSet copyOf(Iterator elements) { - return null; - } - - public static ImmutableSortedSet copyOf( - Comparator comparator, Iterator elements) { - return null; - } - - public static ImmutableSortedSet copyOf( - Comparator comparator, Iterable elements) { - return null; - } - - public static ImmutableSortedSet copyOf( - Comparator comparator, Collection elements) { - return null; - } - - public static ImmutableSortedSet copyOfSorted(SortedSet sortedSet) { - return null; - } - - public static Builder orderedBy(Comparator comparator) { - return null; - } - - public static > Builder reverseOrder() { - return null; - } - - public static > Builder naturalOrder() { - return null; - } - - public static final class Builder extends ImmutableSet.Builder { - public Builder(Comparator comparator) { +abstract public class ImmutableSortedSet extends ImmutableSortedSetFauxverideShim implements NavigableSet, SortedIterable +{ + protected ImmutableSortedSet() {} + public Comparator comparator(){ return null; } + public E ceiling(E p0){ return null; } + public E first(){ return null; } + public E floor(E p0){ return null; } + public E higher(E p0){ return null; } + public E last(){ return null; } + public E lower(E p0){ return null; } + public ImmutableSortedSet descendingSet(){ return null; } + public ImmutableSortedSet headSet(E p0){ return null; } + public ImmutableSortedSet headSet(E p0, boolean p1){ return null; } + public ImmutableSortedSet subSet(E p0, E p1){ return null; } + public ImmutableSortedSet subSet(E p0, boolean p1, E p2, boolean p3){ return null; } + public ImmutableSortedSet tailSet(E p0){ return null; } + public ImmutableSortedSet tailSet(E p0, boolean p1){ return null; } + public Spliterator spliterator(){ return null; } + public abstract UnmodifiableIterator descendingIterator(); + public abstract UnmodifiableIterator iterator(); + public final E pollFirst(){ return null; } + public final E pollLast(){ return null; } + public static > ImmutableSortedSet.Builder naturalOrder(){ return null; } + public static > ImmutableSortedSet.Builder reverseOrder(){ return null; } + public static > ImmutableSortedSet copyOf(E[] p0){ return null; } + public static > ImmutableSortedSet of(E p0){ return null; } + public static > ImmutableSortedSet of(E p0, E p1){ return null; } + public static > ImmutableSortedSet of(E p0, E p1, E p2){ return null; } + public static > ImmutableSortedSet of(E p0, E p1, E p2, E p3){ return null; } + public static > ImmutableSortedSet of(E p0, E p1, E p2, E p3, E p4){ return null; } + public static > ImmutableSortedSet of(E p0, E p1, E p2, E p3, E p4, E p5, E... p6){ return null; } + public static Collector> toImmutableSortedSet(Comparator p0){ return null; } + public static ImmutableSortedSet.Builder orderedBy(Comparator p0){ return null; } + public static ImmutableSortedSet copyOf(Collection p0){ return null; } + public static ImmutableSortedSet copyOf(Comparator p0, Collection p1){ return null; } + public static ImmutableSortedSet copyOf(Comparator p0, Iterable p1){ return null; } + public static ImmutableSortedSet copyOf(Comparator p0, Iterator p1){ return null; } + public static ImmutableSortedSet copyOf(Iterable p0){ return null; } + public static ImmutableSortedSet copyOf(Iterator p0){ return null; } + public static ImmutableSortedSet copyOfSorted(SortedSet p0){ return null; } + public static ImmutableSortedSet of(){ return null; } + static public class Builder extends ImmutableSet.Builder + { + protected Builder() {} + public Builder(Comparator p0){} + public ImmutableSortedSet.Builder add(E p0){ return null; } + public ImmutableSortedSet.Builder add(E... p0){ return null; } + public ImmutableSortedSet.Builder addAll(Iterable p0){ return null; } + public ImmutableSortedSet.Builder addAll(Iterator p0){ return null; } + public ImmutableSortedSet build(){ return null; } } - - } - } diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedSetFauxverideShim.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedSetFauxverideShim.java new file mode 100644 index 00000000000..b2a0cff1ccb --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedSetFauxverideShim.java @@ -0,0 +1,21 @@ +// Generated automatically from com.google.common.collect.ImmutableSortedSetFauxverideShim for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSortedSet; +import java.util.stream.Collector; + +abstract class ImmutableSortedSetFauxverideShim extends ImmutableSet +{ + public static Collector> toImmutableSet(){ return null; } + public static ImmutableSortedSet.Builder builder(){ return null; } + public static ImmutableSortedSet.Builder builderWithExpectedSize(int p0){ return null; } + public static ImmutableSortedSet copyOf(E[] p0){ return null; } + public static ImmutableSortedSet of(E p0){ return null; } + public static ImmutableSortedSet of(E p0, E p1){ return null; } + public static ImmutableSortedSet of(E p0, E p1, E p2){ return null; } + public static ImmutableSortedSet of(E p0, E p1, E p2, E p3){ return null; } + public static ImmutableSortedSet of(E p0, E p1, E p2, E p3, E p4){ return null; } + public static ImmutableSortedSet of(E p0, E p1, E p2, E p3, E p4, E p5, E... p6){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableTable.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableTable.java index 73b3907b352..88f28c9ab98 100644 --- a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableTable.java +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableTable.java @@ -1,124 +1,49 @@ -/* - * Copyright (C) 2009 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Generated automatically from com.google.common.collect.ImmutableTable for testing purposes package com.google.common.collect; +import com.google.common.collect.AbstractTable; +import com.google.common.collect.ImmutableCollection; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Table; +import java.io.Serializable; +import java.util.Comparator; import java.util.Map; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.stream.Collector; -public abstract class ImmutableTable extends AbstractTable { - - public static ImmutableTable of() { - return null; - } - - public static ImmutableTable of(R rowKey, C columnKey, V value) { - return null; - } - - public static ImmutableTable copyOf( - Table table) { - return null; - } - - public static Builder builder() { - return null; - } - - public static final class Builder { - public Builder() {} - - public Builder put(R rowKey, C columnKey, V value) { - return null; +abstract public class ImmutableTable extends AbstractTable implements Serializable +{ + public ImmutableCollection values(){ return null; } + public ImmutableMap row(R p0){ return null; } + public ImmutableMap column(C p0){ return null; } + public ImmutableSet columnKeySet(){ return null; } + public ImmutableSet rowKeySet(){ return null; } + public ImmutableSet> cellSet(){ return null; } + public abstract ImmutableMap> columnMap(); + public abstract ImmutableMap> rowMap(); + public boolean contains(Object p0, Object p1){ return false; } + public boolean containsValue(Object p0){ return false; } + public final V put(R p0, C p1, V p2){ return null; } + public final V remove(Object p0, Object p1){ return null; } + public final void clear(){} + public final void putAll(Table p0){} + public static ImmutableTable.Builder builder(){ return null; } + public static ImmutableTable copyOf(Table p0){ return null; } + public static ImmutableTable of(){ return null; } + public static ImmutableTable of(R p0, C p1, V p2){ return null; } + public static Collector> toImmutableTable(Function p0, Function p1, Function p2){ return null; } + public static Collector> toImmutableTable(Function p0, Function p1, Function p2, BinaryOperator p3){ return null; } + static public class Builder + { + public Builder(){} + public ImmutableTable.Builder orderColumnsBy(Comparator p0){ return null; } + public ImmutableTable.Builder orderRowsBy(Comparator p0){ return null; } + public ImmutableTable.Builder put(R p0, C p1, V p2){ return null; } + public ImmutableTable.Builder put(Table.Cell p0){ return null; } + public ImmutableTable.Builder putAll(Table p0){ return null; } + public ImmutableTable build(){ return null; } } - - public Builder put(Cell cell) { - return null; - } - - public Builder putAll(Table table) { - return null; - } - - public ImmutableTable build() { - return null; - } - - } - @Override - public ImmutableSet> cellSet() { - return null; - } - - @Override - public ImmutableCollection values() { - return null; - } - - @Override - public ImmutableMap column(C columnKey) { - return null; - } - - @Override - public ImmutableSet columnKeySet() { - return null; - } - - @Override - public abstract ImmutableMap> columnMap(); - - @Override - public ImmutableMap row(R rowKey) { - return null; - } - - @Override - public ImmutableSet rowKeySet() { - return null; - } - - @Override - public abstract ImmutableMap> rowMap(); - - @Override - public boolean contains(Object rowKey, Object columnKey) { - return false; - } - - @Override - public boolean containsValue(Object value) { - return false; - } - - @Override - public final void clear() { - } - - @Override - public final V put(R rowKey, C columnKey, V value) { - return null; - } - - @Override - public final void putAll(Table table) { - } - - @Override - public final V remove(Object rowKey, Object columnKey) { - return null; - } - } diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Iterables.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Iterables.java new file mode 100644 index 00000000000..6eb11f37e56 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Iterables.java @@ -0,0 +1,58 @@ +// Generated automatically from com.google.common.collect.Iterables for testing purposes + +package com.google.common.collect; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableCollection; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; + +public class Iterables +{ + protected Iterables() {} + public static Iterable unmodifiableIterable(ImmutableCollection p0){ return null; } + public static Iterable transform(Iterable p0, Function p1){ return null; } + public static Iterable> paddedPartition(Iterable p0, int p1){ return null; } + public static Iterable> partition(Iterable p0, int p1){ return null; } + public static Iterable concat(Iterable> p0){ return null; } + public static Iterable concat(Iterable p0, Iterable p1){ return null; } + public static Iterable concat(Iterable p0, Iterable p1, Iterable p2){ return null; } + public static Iterable concat(Iterable p0, Iterable p1, Iterable p2, Iterable p3){ return null; } + public static Iterable concat(Iterable... p0){ return null; } + public static Iterable consumingIterable(Iterable p0){ return null; } + public static Iterable cycle(Iterable p0){ return null; } + public static Iterable cycle(T... p0){ return null; } + public static Iterable filter(Iterable p0, Class p1){ return null; } + public static Iterable filter(Iterable p0, Predicate p1){ return null; } + public static Iterable limit(Iterable p0, int p1){ return null; } + public static Iterable mergeSorted(Iterable> p0, Comparator p1){ return null; } + public static Iterable skip(Iterable p0, int p1){ return null; } + public static Iterable unmodifiableIterable(Iterable p0){ return null; } + public static Optional tryFind(Iterable p0, Predicate p1){ return null; } + public static T find(Iterable p0, Predicate p1, T p2){ return null; } + public static T find(Iterable p0, Predicate p1){ return null; } + public static T get(Iterable p0, int p1, T p2){ return null; } + public static T get(Iterable p0, int p1){ return null; } + public static T getFirst(Iterable p0, T p1){ return null; } + public static T getLast(Iterable p0, T p1){ return null; } + public static T getLast(Iterable p0){ return null; } + public static T getOnlyElement(Iterable p0, T p1){ return null; } + public static T getOnlyElement(Iterable p0){ return null; } + public static T[] toArray(Iterable p0, Class p1){ return null; } + public static boolean addAll(Collection p0, Iterable p1){ return false; } + public static boolean all(Iterable p0, Predicate p1){ return false; } + public static boolean any(Iterable p0, Predicate p1){ return false; } + public static boolean removeIf(Iterable p0, Predicate p1){ return false; } + public static int indexOf(Iterable p0, Predicate p1){ return 0; } + public static String toString(Iterable p0){ return null; } + public static boolean contains(Iterable p0, Object p1){ return false; } + public static boolean elementsEqual(Iterable p0, Iterable p1){ return false; } + public static boolean isEmpty(Iterable p0){ return false; } + public static boolean removeAll(Iterable p0, Collection p1){ return false; } + public static boolean retainAll(Iterable p0, Collection p1){ return false; } + public static int frequency(Iterable p0, Object p1){ return 0; } + public static int size(Iterable p0){ return 0; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Iterators.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Iterators.java new file mode 100644 index 00000000000..4560e35a912 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Iterators.java @@ -0,0 +1,66 @@ +// Generated automatically from com.google.common.collect.Iterators for testing purposes + +package com.google.common.collect; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.PeekingIterator; +import com.google.common.collect.UnmodifiableIterator; +import java.util.Collection; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; + +public class Iterators +{ + protected Iterators() {} + public static Iterator transform(Iterator p0, Function p1){ return null; } + public static Enumeration asEnumeration(Iterator p0){ return null; } + public static Iterator concat(Iterator> p0){ return null; } + public static Iterator concat(Iterator p0, Iterator p1){ return null; } + public static Iterator concat(Iterator p0, Iterator p1, Iterator p2){ return null; } + public static Iterator concat(Iterator p0, Iterator p1, Iterator p2, Iterator p3){ return null; } + public static Iterator concat(Iterator... p0){ return null; } + public static Iterator consumingIterator(Iterator p0){ return null; } + public static Iterator cycle(Iterable p0){ return null; } + public static Iterator cycle(T... p0){ return null; } + public static Iterator limit(Iterator p0, int p1){ return null; } + public static Optional tryFind(Iterator p0, Predicate p1){ return null; } + public static PeekingIterator peekingIterator(Iterator p0){ return null; } + public static PeekingIterator peekingIterator(PeekingIterator p0){ return null; } + public static T find(Iterator p0, Predicate p1, T p2){ return null; } + public static T find(Iterator p0, Predicate p1){ return null; } + public static T get(Iterator p0, int p1, T p2){ return null; } + public static T get(Iterator p0, int p1){ return null; } + public static T getLast(Iterator p0, T p1){ return null; } + public static T getLast(Iterator p0){ return null; } + public static T getNext(Iterator p0, T p1){ return null; } + public static T getOnlyElement(Iterator p0, T p1){ return null; } + public static T getOnlyElement(Iterator p0){ return null; } + public static T[] toArray(Iterator p0, Class p1){ return null; } + public static UnmodifiableIterator> paddedPartition(Iterator p0, int p1){ return null; } + public static UnmodifiableIterator> partition(Iterator p0, int p1){ return null; } + public static UnmodifiableIterator filter(Iterator p0, Class p1){ return null; } + public static UnmodifiableIterator filter(Iterator p0, Predicate p1){ return null; } + public static UnmodifiableIterator forArray(T... p0){ return null; } + public static UnmodifiableIterator forEnumeration(Enumeration p0){ return null; } + public static UnmodifiableIterator mergeSorted(Iterable> p0, Comparator p1){ return null; } + public static UnmodifiableIterator singletonIterator(T p0){ return null; } + public static UnmodifiableIterator unmodifiableIterator(Iterator p0){ return null; } + public static UnmodifiableIterator unmodifiableIterator(UnmodifiableIterator p0){ return null; } + public static boolean addAll(Collection p0, Iterator p1){ return false; } + public static boolean all(Iterator p0, Predicate p1){ return false; } + public static boolean any(Iterator p0, Predicate p1){ return false; } + public static boolean removeIf(Iterator p0, Predicate p1){ return false; } + public static int indexOf(Iterator p0, Predicate p1){ return 0; } + public static String toString(Iterator p0){ return null; } + public static boolean contains(Iterator p0, Object p1){ return false; } + public static boolean elementsEqual(Iterator p0, Iterator p1){ return false; } + public static boolean removeAll(Iterator p0, Collection p1){ return false; } + public static boolean retainAll(Iterator p0, Collection p1){ return false; } + public static int advance(Iterator p0, int p1){ return 0; } + public static int frequency(Iterator p0, Object p1){ return 0; } + public static int size(Iterator p0){ return 0; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/LinkedHashMultimap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/LinkedHashMultimap.java new file mode 100644 index 00000000000..f6b539d1b58 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/LinkedHashMultimap.java @@ -0,0 +1,22 @@ +// Generated automatically from com.google.common.collect.LinkedHashMultimap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.LinkedHashMultimapGwtSerializationDependencies; +import com.google.common.collect.Multimap; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +public class LinkedHashMultimap extends LinkedHashMultimapGwtSerializationDependencies +{ + protected LinkedHashMultimap() {} + public Collection values(){ return null; } + public Set keySet(){ return null; } + public Set> entries(){ return null; } + public Set replaceValues(K p0, Iterable p1){ return null; } + public static LinkedHashMultimap create(){ return null; } + public static LinkedHashMultimap create(Multimap p0){ return null; } + public static LinkedHashMultimap create(int p0, int p1){ return null; } + public void clear(){} +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/LinkedHashMultimapGwtSerializationDependencies.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/LinkedHashMultimapGwtSerializationDependencies.java new file mode 100644 index 00000000000..18f861e3ad0 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/LinkedHashMultimapGwtSerializationDependencies.java @@ -0,0 +1,10 @@ +// Generated automatically from com.google.common.collect.LinkedHashMultimapGwtSerializationDependencies for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractSetMultimap; + +abstract class LinkedHashMultimapGwtSerializationDependencies extends AbstractSetMultimap +{ + protected LinkedHashMultimapGwtSerializationDependencies() {} +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/LinkedHashMultiset.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/LinkedHashMultiset.java new file mode 100644 index 00000000000..e25143c06f6 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/LinkedHashMultiset.java @@ -0,0 +1,13 @@ +// Generated automatically from com.google.common.collect.LinkedHashMultiset for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractMapBasedMultiset; + +public class LinkedHashMultiset extends AbstractMapBasedMultiset +{ + protected LinkedHashMultiset() {} + public static LinkedHashMultiset create(){ return null; } + public static LinkedHashMultiset create(Iterable p0){ return null; } + public static LinkedHashMultiset create(int p0){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/LinkedListMultimap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/LinkedListMultimap.java new file mode 100644 index 00000000000..2fb2075f923 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/LinkedListMultimap.java @@ -0,0 +1,28 @@ +// Generated automatically from com.google.common.collect.LinkedListMultimap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractMultimap; +import com.google.common.collect.ListMultimap; +import com.google.common.collect.Multimap; +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +public class LinkedListMultimap extends AbstractMultimap implements ListMultimap, Serializable +{ + public List> entries(){ return null; } + public List get(K p0){ return null; } + public List removeAll(Object p0){ return null; } + public List replaceValues(K p0, Iterable p1){ return null; } + public List values(){ return null; } + public boolean containsKey(Object p0){ return false; } + public boolean containsValue(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public boolean put(K p0, V p1){ return false; } + public int size(){ return 0; } + public static LinkedListMultimap create(){ return null; } + public static LinkedListMultimap create(Multimap p0){ return null; } + public static LinkedListMultimap create(int p0){ return null; } + public void clear(){} +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ListMultimap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ListMultimap.java new file mode 100644 index 00000000000..da8c80f8bae --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ListMultimap.java @@ -0,0 +1,17 @@ +// Generated automatically from com.google.common.collect.ListMultimap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.Multimap; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +public interface ListMultimap extends Multimap +{ + List get(K p0); + List removeAll(Object p0); + List replaceValues(K p0, Iterable p1); + Map> asMap(); + boolean equals(Object p0); +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Lists.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Lists.java new file mode 100644 index 00000000000..6be1146dbef --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Lists.java @@ -0,0 +1,35 @@ +// Generated automatically from com.google.common.collect.Lists for testing purposes + +package com.google.common.collect; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +public class Lists +{ + protected Lists() {} + public static List> cartesianProduct(List... p0){ return null; } + public static List> cartesianProduct(List> p0){ return null; } + public static ArrayList newArrayList(){ return null; } + public static ArrayList newArrayList(E... p0){ return null; } + public static ArrayList newArrayList(Iterable p0){ return null; } + public static ArrayList newArrayList(Iterator p0){ return null; } + public static ArrayList newArrayListWithCapacity(int p0){ return null; } + public static ArrayList newArrayListWithExpectedSize(int p0){ return null; } + public static CopyOnWriteArrayList newCopyOnWriteArrayList(){ return null; } + public static CopyOnWriteArrayList newCopyOnWriteArrayList(Iterable p0){ return null; } + public static LinkedList newLinkedList(){ return null; } + public static LinkedList newLinkedList(Iterable p0){ return null; } + public static List asList(E p0, E p1, E[] p2){ return null; } + public static List asList(E p0, E[] p1){ return null; } + public static List transform(List p0, Function p1){ return null; } + public static List> partition(List p0, int p1){ return null; } + public static List reverse(List p0){ return null; } + public static ImmutableList charactersOf(String p0){ return null; } + public static List charactersOf(CharSequence p0){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/MapDifference.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/MapDifference.java new file mode 100644 index 00000000000..b1a2efcf548 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/MapDifference.java @@ -0,0 +1,23 @@ +// Generated automatically from com.google.common.collect.MapDifference for testing purposes + +package com.google.common.collect; + +import java.util.Map; + +public interface MapDifference +{ + Map> entriesDiffering(); + Map entriesInCommon(); + Map entriesOnlyOnLeft(); + Map entriesOnlyOnRight(); + boolean areEqual(); + boolean equals(Object p0); + int hashCode(); + static public interface ValueDifference + { + V leftValue(); + V rightValue(); + boolean equals(Object p0); + int hashCode(); + } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Maps.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Maps.java new file mode 100644 index 00000000000..34779f28de0 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Maps.java @@ -0,0 +1,96 @@ +// Generated automatically from com.google.common.collect.Maps for testing purposes, and adjusted manually + +package com.google.common.collect; + +import com.google.common.base.Converter; +import com.google.common.base.Equivalence; +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.collect.BiMap; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.MapDifference; +import com.google.common.collect.Range; +import com.google.common.collect.SortedMapDifference; +import java.util.AbstractMap; +import java.util.Comparator; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NavigableMap; +import java.util.NavigableSet; +import java.util.Properties; +import java.util.Set; +import java.util.SortedMap; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentMap; +import java.util.function.BinaryOperator; +import java.util.stream.Collector; + +public class Maps +{ + protected Maps() {} + abstract static class IteratorBasedAbstractMap extends AbstractMap { + public Set> entrySet(){ return null; } + public void clear(){} + } + public static Converter asConverter(BiMap p0){ return null; } + public static TreeMap newTreeMap(Comparator p0){ return null; } + public static TreeMap newTreeMap(){ return null; } + public static , V> NavigableMap subMap(NavigableMap p0, Range p1){ return null; } + public static , V> EnumMap newEnumMap(Class p0){ return null; } + public static , V> EnumMap newEnumMap(Map p0){ return null; } + public static , V> ImmutableMap immutableEnumMap(Map p0){ return null; } + public static Map transformEntries(Map p0, Maps.EntryTransformer p1){ return null; } + public static Map transformValues(Map p0, Function p1){ return null; } + public static NavigableMap transformEntries(NavigableMap p0, Maps.EntryTransformer p1){ return null; } + public static NavigableMap transformValues(NavigableMap p0, Function p1){ return null; } + public static SortedMap transformEntries(SortedMap p0, Maps.EntryTransformer p1){ return null; } + public static SortedMap transformValues(SortedMap p0, Function p1){ return null; } + public static BiMap filterEntries(BiMap p0, Predicate> p1){ return null; } + public static BiMap filterKeys(BiMap p0, Predicate p1){ return null; } + public static BiMap filterValues(BiMap p0, Predicate p1){ return null; } + public static BiMap synchronizedBiMap(BiMap p0){ return null; } + public static BiMap unmodifiableBiMap(BiMap p0){ return null; } + public static ConcurrentMap newConcurrentMap(){ return null; } + public static HashMap newHashMap(){ return null; } + public static HashMap newHashMap(Map p0){ return null; } + public static HashMap newHashMapWithExpectedSize(int p0){ return null; } + public static IdentityHashMap newIdentityHashMap(){ return null; } + public static ImmutableMap toMap(Iterable p0, Function p1){ return null; } + public static ImmutableMap toMap(Iterator p0, Function p1){ return null; } + public static ImmutableMap uniqueIndex(Iterable p0, Function p1){ return null; } + public static ImmutableMap uniqueIndex(Iterator p0, Function p1){ return null; } + public static LinkedHashMap newLinkedHashMap(){ return null; } + public static LinkedHashMap newLinkedHashMap(Map p0){ return null; } + public static LinkedHashMap newLinkedHashMapWithExpectedSize(int p0){ return null; } + public static Map.Entry immutableEntry(K p0, V p1){ return null; } + public static Map asMap(Set p0, Function p1){ return null; } + public static Map filterEntries(Map p0, Predicate> p1){ return null; } + public static Map filterKeys(Map p0, Predicate p1){ return null; } + public static Map filterValues(Map p0, Predicate p1){ return null; } + public static MapDifference difference(Map p0, Map p1){ return null; } + public static MapDifference difference(Map p0, Map p1, Equivalence p2){ return null; } + public static NavigableMap asMap(NavigableSet p0, Function p1){ return null; } + public static NavigableMap filterEntries(NavigableMap p0, Predicate> p1){ return null; } + public static NavigableMap filterKeys(NavigableMap p0, Predicate p1){ return null; } + public static NavigableMap filterValues(NavigableMap p0, Predicate p1){ return null; } + public static NavigableMap synchronizedNavigableMap(NavigableMap p0){ return null; } + public static NavigableMap unmodifiableNavigableMap(NavigableMap p0){ return null; } + public static SortedMap asMap(SortedSet p0, Function p1){ return null; } + public static SortedMap filterEntries(SortedMap p0, Predicate> p1){ return null; } + public static SortedMap filterKeys(SortedMap p0, Predicate p1){ return null; } + public static SortedMap filterValues(SortedMap p0, Predicate p1){ return null; } + public static SortedMapDifference difference(SortedMap p0, Map p1){ return null; } + public static TreeMap newTreeMap(SortedMap p0){ return null; } + public static , V> Collector> toImmutableEnumMap(Function p0, Function p1){ return null; } + public static , V> Collector> toImmutableEnumMap(Function p0, Function p1, BinaryOperator p2){ return null; } + public static ImmutableMap fromProperties(Properties p0){ return null; } + static public interface EntryTransformer + { + V2 transformEntry(K p0, V1 p1); + } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Multimaps.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Multimaps.java new file mode 100644 index 00000000000..eef38c9636c --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Multimaps.java @@ -0,0 +1,64 @@ +// Generated automatically from com.google.common.collect.Multimaps for testing purposes, and adjusted manually + +package com.google.common.collect; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableListMultimap; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSetMultimap; +import com.google.common.collect.ListMultimap; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; +import com.google.common.collect.SetMultimap; +import com.google.common.collect.SortedSetMultimap; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.stream.Collector; +import java.util.stream.Stream; + +public class Multimaps +{ + protected Multimaps() {} + public static > M invertFrom(Multimap p0, M p1){ return null; } + public static ListMultimap transformEntries(ListMultimap p0, Maps.EntryTransformer p1){ return null; } + public static ListMultimap transformValues(ListMultimap p0, Function p1){ return null; } + public static Multimap transformEntries(Multimap p0, Maps.EntryTransformer p1){ return null; } + public static Multimap transformValues(Multimap p0, Function p1){ return null; } + public static ImmutableListMultimap index(Iterable p0, Function p1){ return null; } + public static ImmutableListMultimap index(Iterator p0, Function p1){ return null; } + public static ListMultimap filterKeys(ListMultimap p0, Predicate p1){ return null; } + public static ListMultimap newListMultimap(Map> p0, Supplier> p1){ return null; } + public static ListMultimap synchronizedListMultimap(ListMultimap p0){ return null; } + public static ListMultimap unmodifiableListMultimap(ImmutableListMultimap p0){ return null; } + public static ListMultimap unmodifiableListMultimap(ListMultimap p0){ return null; } + public static Map> asMap(Multimap p0){ return null; } + public static Map> asMap(ListMultimap p0){ return null; } + public static Map> asMap(SetMultimap p0){ return null; } + public static Map> asMap(SortedSetMultimap p0){ return null; } + public static Multimap filterEntries(Multimap p0, Predicate> p1){ return null; } + public static Multimap filterKeys(Multimap p0, Predicate p1){ return null; } + public static Multimap filterValues(Multimap p0, Predicate p1){ return null; } + public static Multimap newMultimap(Map> p0, Supplier> p1){ return null; } + public static Multimap synchronizedMultimap(Multimap p0){ return null; } + public static Multimap unmodifiableMultimap(ImmutableMultimap p0){ return null; } + public static Multimap unmodifiableMultimap(Multimap p0){ return null; } + public static SetMultimap filterEntries(SetMultimap p0, Predicate> p1){ return null; } + public static SetMultimap filterKeys(SetMultimap p0, Predicate p1){ return null; } + public static SetMultimap filterValues(SetMultimap p0, Predicate p1){ return null; } + public static SetMultimap forMap(Map p0){ return null; } + public static SetMultimap newSetMultimap(Map> p0, Supplier> p1){ return null; } + public static SetMultimap synchronizedSetMultimap(SetMultimap p0){ return null; } + public static SetMultimap unmodifiableSetMultimap(ImmutableSetMultimap p0){ return null; } + public static SetMultimap unmodifiableSetMultimap(SetMultimap p0){ return null; } + public static SortedSetMultimap newSortedSetMultimap(Map> p0, Supplier> p1){ return null; } + public static SortedSetMultimap synchronizedSortedSetMultimap(SortedSetMultimap p0){ return null; } + public static SortedSetMultimap unmodifiableSortedSetMultimap(SortedSetMultimap p0){ return null; } + public static > Collector flatteningToMultimap(Function p0, Function> p1, Supplier p2){ return null; } + public static > Collector toMultimap(Function p0, Function p1, Supplier p2){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Multisets.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Multisets.java new file mode 100644 index 00000000000..13c58b5d703 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Multisets.java @@ -0,0 +1,32 @@ +// Generated automatically from com.google.common.collect.Multisets for testing purposes + +package com.google.common.collect; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableMultiset; +import com.google.common.collect.Multiset; +import com.google.common.collect.SortedMultiset; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.function.ToIntFunction; +import java.util.stream.Collector; + +public class Multisets +{ + protected Multisets() {} + public static ImmutableMultiset copyHighestCountFirst(Multiset p0){ return null; } + public static Multiset.Entry immutableEntry(E p0, int p1){ return null; } + public static Multiset difference(Multiset p0, Multiset p1){ return null; } + public static Multiset filter(Multiset p0, Predicate p1){ return null; } + public static Multiset intersection(Multiset p0, Multiset p1){ return null; } + public static Multiset sum(Multiset p0, Multiset p1){ return null; } + public static Multiset union(Multiset p0, Multiset p1){ return null; } + public static Multiset unmodifiableMultiset(ImmutableMultiset p0){ return null; } + public static Multiset unmodifiableMultiset(Multiset p0){ return null; } + public static SortedMultiset unmodifiableSortedMultiset(SortedMultiset p0){ return null; } + public static > Collector toMultiset(Function p0, ToIntFunction p1, Supplier p2){ return null; } + public static boolean containsOccurrences(Multiset p0, Multiset p1){ return false; } + public static boolean removeOccurrences(Multiset p0, Iterable p1){ return false; } + public static boolean removeOccurrences(Multiset p0, Multiset p1){ return false; } + public static boolean retainOccurrences(Multiset p0, Multiset p1){ return false; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/MutableClassToInstanceMap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/MutableClassToInstanceMap.java new file mode 100644 index 00000000000..02c7f11227f --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/MutableClassToInstanceMap.java @@ -0,0 +1,22 @@ +// Generated automatically from com.google.common.collect.MutableClassToInstanceMap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.ClassToInstanceMap; +import com.google.common.collect.ForwardingMap; +import java.io.Serializable; +import java.util.Map; +import java.util.Set; + +public class MutableClassToInstanceMap extends ForwardingMap, B> implements ClassToInstanceMap, Serializable +{ + protected MutableClassToInstanceMap() {} + protected Map, B> delegate(){ return null; } + public T getInstance(Class p0){ return null; } + public T putInstance(Class p0, T p1){ return null; } + public B put(Class p0, B p1){ return null; } + public Set, B>> entrySet(){ return null; } + public static MutableClassToInstanceMap create(){ return null; } + public static MutableClassToInstanceMap create(Map, B> p0){ return null; } + public void putAll(Map, ? extends B> p0){} +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ObjectArrays.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ObjectArrays.java new file mode 100644 index 00000000000..5999b1ba04e --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ObjectArrays.java @@ -0,0 +1,14 @@ +// Generated automatically from com.google.common.collect.ObjectArrays for testing purposes + +package com.google.common.collect; + + +public class ObjectArrays +{ + protected ObjectArrays() {} + public static T[] concat(T p0, T[] p1){ return null; } + public static T[] concat(T[] p0, T p1){ return null; } + public static T[] concat(T[] p0, T[] p1, Class p2){ return null; } + public static T[] newArray(Class p0, int p1){ return null; } + public static T[] newArray(T[] p0, int p1){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Ordering.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Ordering.java new file mode 100644 index 00000000000..a6114bdea3e --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Ordering.java @@ -0,0 +1,51 @@ +// Generated automatically from com.google.common.collect.Ordering for testing purposes + +package com.google.common.collect; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +abstract public class Ordering implements Comparator +{ + Ordering> onKeys(){ return null; } + protected Ordering(){} + public E max(E p0, E p1){ return null; } + public E max(E p0, E p1, E p2, E... p3){ return null; } + public E max(Iterable p0){ return null; } + public E max(Iterator p0){ return null; } + public E min(E p0, E p1){ return null; } + public E min(E p0, E p1, E p2, E... p3){ return null; } + public E min(Iterable p0){ return null; } + public E min(Iterator p0){ return null; } + public ImmutableList immutableSortedCopy(Iterable p0){ return null; } + public List greatestOf(Iterable p0, int p1){ return null; } + public List greatestOf(Iterator p0, int p1){ return null; } + public List leastOf(Iterable p0, int p1){ return null; } + public List leastOf(Iterator p0, int p1){ return null; } + public List sortedCopy(Iterable p0){ return null; } + public Ordering onResultOf(Function p0){ return null; } + public Ordering> lexicographical(){ return null; } + public Ordering nullsFirst(){ return null; } + public Ordering nullsLast(){ return null; } + public Ordering reverse(){ return null; } + public Ordering compound(Comparator p0){ return null; } + public abstract int compare(T p0, T p1); + public boolean isOrdered(Iterable p0){ return false; } + public boolean isStrictlyOrdered(Iterable p0){ return false; } + public int binarySearch(List p0, T p1){ return 0; } + public static Ordering natural(){ return null; } + public static Ordering compound(Iterable> p0){ return null; } + public static Ordering explicit(List p0){ return null; } + public static Ordering explicit(T p0, T... p1){ return null; } + public static Ordering from(Comparator p0){ return null; } + public static Ordering from(Ordering p0){ return null; } + public static Ordering allEqual(){ return null; } + public static Ordering arbitrary(){ return null; } + public static Ordering usingToString(){ return null; } + static int LEFT_IS_GREATER = 0; + static int RIGHT_IS_GREATER = 0; +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/PeekingIterator.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/PeekingIterator.java new file mode 100644 index 00000000000..f84b92e41f6 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/PeekingIterator.java @@ -0,0 +1,12 @@ +// Generated automatically from com.google.common.collect.PeekingIterator for testing purposes + +package com.google.common.collect; + +import java.util.Iterator; + +public interface PeekingIterator extends Iterator +{ + E next(); + E peek(); + void remove(); +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Queues.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Queues.java new file mode 100644 index 00000000000..981720063fa --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Queues.java @@ -0,0 +1,45 @@ +// Generated automatically from com.google.common.collect.Queues for testing purposes + +package com.google.common.collect; + +import java.time.Duration; +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Deque; +import java.util.PriorityQueue; +import java.util.Queue; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.PriorityBlockingQueue; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.TimeUnit; + +public class Queues +{ + protected Queues() {} + public static PriorityBlockingQueue newPriorityBlockingQueue(){ return null; } + public static PriorityBlockingQueue newPriorityBlockingQueue(Iterable p0){ return null; } + public static PriorityQueue newPriorityQueue(){ return null; } + public static PriorityQueue newPriorityQueue(Iterable p0){ return null; } + public static ArrayBlockingQueue newArrayBlockingQueue(int p0){ return null; } + public static ArrayDeque newArrayDeque(){ return null; } + public static ArrayDeque newArrayDeque(Iterable p0){ return null; } + public static ConcurrentLinkedQueue newConcurrentLinkedQueue(){ return null; } + public static ConcurrentLinkedQueue newConcurrentLinkedQueue(Iterable p0){ return null; } + public static Deque synchronizedDeque(Deque p0){ return null; } + public static LinkedBlockingDeque newLinkedBlockingDeque(){ return null; } + public static LinkedBlockingDeque newLinkedBlockingDeque(Iterable p0){ return null; } + public static LinkedBlockingDeque newLinkedBlockingDeque(int p0){ return null; } + public static LinkedBlockingQueue newLinkedBlockingQueue(){ return null; } + public static LinkedBlockingQueue newLinkedBlockingQueue(Iterable p0){ return null; } + public static LinkedBlockingQueue newLinkedBlockingQueue(int p0){ return null; } + public static Queue synchronizedQueue(Queue p0){ return null; } + public static SynchronousQueue newSynchronousQueue(){ return null; } + public static int drain(BlockingQueue p0, Collection p1, int p2, Duration p3){ return 0; } + public static int drain(BlockingQueue p0, Collection p1, int p2, long p3, TimeUnit p4){ return 0; } + public static int drainUninterruptibly(BlockingQueue p0, Collection p1, int p2, Duration p3){ return 0; } + public static int drainUninterruptibly(BlockingQueue p0, Collection p1, int p2, long p3, TimeUnit p4){ return 0; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Range.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Range.java new file mode 100644 index 00000000000..15cfc94fc3d --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Range.java @@ -0,0 +1,47 @@ +// Generated automatically from com.google.common.collect.Range for testing purposes + +package com.google.common.collect; + +import com.google.common.base.Predicate; +import com.google.common.collect.BoundType; +import com.google.common.collect.DiscreteDomain; +import com.google.common.collect.RangeGwtSerializationDependencies; +import java.io.Serializable; + +public class Range extends RangeGwtSerializationDependencies implements Predicate, Serializable +{ + protected Range() {} + public BoundType lowerBoundType(){ return null; } + public BoundType upperBoundType(){ return null; } + public C lowerEndpoint(){ return null; } + public C upperEndpoint(){ return null; } + public Range canonical(DiscreteDomain p0){ return null; } + public Range gap(Range p0){ return null; } + public Range intersection(Range p0){ return null; } + public Range span(Range p0){ return null; } + public String toString(){ return null; } + public boolean apply(C p0){ return false; } + public boolean contains(C p0){ return false; } + public boolean containsAll(Iterable p0){ return false; } + public boolean encloses(Range p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean hasLowerBound(){ return false; } + public boolean hasUpperBound(){ return false; } + public boolean isConnected(Range p0){ return false; } + public boolean isEmpty(){ return false; } + public int hashCode(){ return 0; } + public static > Range all(){ return null; } + public static > Range atLeast(C p0){ return null; } + public static > Range atMost(C p0){ return null; } + public static > Range closed(C p0, C p1){ return null; } + public static > Range closedOpen(C p0, C p1){ return null; } + public static > Range downTo(C p0, BoundType p1){ return null; } + public static > Range encloseAll(Iterable p0){ return null; } + public static > Range greaterThan(C p0){ return null; } + public static > Range lessThan(C p0){ return null; } + public static > Range open(C p0, C p1){ return null; } + public static > Range openClosed(C p0, C p1){ return null; } + public static > Range range(C p0, BoundType p1, C p2, BoundType p3){ return null; } + public static > Range singleton(C p0){ return null; } + public static > Range upTo(C p0, BoundType p1){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/RangeGwtSerializationDependencies.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/RangeGwtSerializationDependencies.java new file mode 100644 index 00000000000..007eac594c6 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/RangeGwtSerializationDependencies.java @@ -0,0 +1,9 @@ +// Generated automatically from com.google.common.collect.RangeGwtSerializationDependencies for testing purposes + +package com.google.common.collect; + +import java.io.Serializable; + +abstract class RangeGwtSerializationDependencies implements Serializable +{ +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/RegularImmutableSortedSet.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/RegularImmutableSortedSet.java new file mode 100644 index 00000000000..5bf53b0b23d --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/RegularImmutableSortedSet.java @@ -0,0 +1,47 @@ +// Generated automatically from com.google.common.collect.RegularImmutableSortedSet for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.UnmodifiableIterator; +import java.util.Collection; +import java.util.Comparator; +import java.util.Spliterator; +import java.util.function.Consumer; + +class RegularImmutableSortedSet extends ImmutableSortedSet +{ + protected RegularImmutableSortedSet() {} + Comparator unsafeComparator(){ return null; } + ImmutableList createAsList(){ return null; } + ImmutableSortedSet createDescendingSet(){ return null; } + ImmutableSortedSet headSetImpl(E p0, boolean p1){ return null; } + ImmutableSortedSet subSetImpl(E p0, boolean p1, E p2, boolean p3){ return null; } + ImmutableSortedSet tailSetImpl(E p0, boolean p1){ return null; } + Object[] internalArray(){ return null; } + RegularImmutableSortedSet(ImmutableList p0, Comparator p1){} + RegularImmutableSortedSet getSubSet(int p0, int p1){ return null; } + boolean isPartialView(){ return false; } + int copyIntoArray(Object[] p0, int p1){ return 0; } + int headIndex(E p0, boolean p1){ return 0; } + int indexOf(Object p0){ return 0; } + int internalArrayEnd(){ return 0; } + int internalArrayStart(){ return 0; } + int tailIndex(E p0, boolean p1){ return 0; } + public E ceiling(E p0){ return null; } + public E first(){ return null; } + public E floor(E p0){ return null; } + public E higher(E p0){ return null; } + public E last(){ return null; } + public E lower(E p0){ return null; } + public Spliterator spliterator(){ return null; } + public UnmodifiableIterator descendingIterator(){ return null; } + public UnmodifiableIterator iterator(){ return null; } + public boolean contains(Object p0){ return false; } + public boolean containsAll(Collection p0){ return false; } + public boolean equals(Object p0){ return false; } + public int size(){ return 0; } + public void forEach(Consumer p0){} + static RegularImmutableSortedSet NATURAL_EMPTY_SET = null; +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/RowSortedTable.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/RowSortedTable.java new file mode 100644 index 00000000000..b4a1b74f25a --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/RowSortedTable.java @@ -0,0 +1,14 @@ +// Generated automatically from com.google.common.collect.RowSortedTable for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.Table; +import java.util.Map; +import java.util.SortedMap; +import java.util.SortedSet; + +public interface RowSortedTable extends Table +{ + SortedMap> rowMap(); + SortedSet rowKeySet(); +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Sets.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Sets.java index 77d3812f082..4e77f5d3a3c 100644 --- a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Sets.java +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Sets.java @@ -1,93 +1,79 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Generated automatically from com.google.common.collect.Sets for testing purposes, and adjusted manually package com.google.common.collect; +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Range; +import com.google.common.collect.UnmodifiableIterator; import java.util.AbstractSet; import java.util.Collection; +import java.util.Comparator; +import java.util.EnumSet; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.NavigableSet; -import java.util.NoSuchElementException; import java.util.Set; -import java.util.function.Predicate; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.stream.Collector; -public final class Sets { - private Sets() {} - - public static HashSet newHashSet() { - return null; - } - - public static HashSet newHashSet(E... elements) { - return null; - } - - public static HashSet newHashSet(Iterable elements) { - return null; - } - public abstract static class SetView extends AbstractSet { - private SetView() {} - } - - public static SetView union(final Set set1, final Set set2) { - return null; - } - - public static SetView intersection(final Set set1, final Set set2) { - return null; - } - - public static SetView difference(final Set set1, final Set set2) { - return null; - } - - public static SetView symmetricDifference( - final Set set1, final Set set2) { - return null; - } - - public static Set filter(Set unfiltered, Predicate predicate) { - return null; - } - - - public static Set> cartesianProduct(List> sets) { - return null; - } - - public static Set> cartesianProduct(Set... sets) { - return null; - } - - public static Set> powerSet(Set set) { - return null; - } - - public static Set> combinations(Set set, final int size) { - return null; - } - - public static NavigableSet synchronizedNavigableSet(NavigableSet navigableSet) { - return null; - } - - public static > NavigableSet subSet( - NavigableSet set, Object range) { - return null; - } +public class Sets +{ + protected Sets() {} + abstract static public class SetView extends AbstractSet + { + protected SetView() {} + public > S copyInto(S p0){ return null; } + public ImmutableSet immutableCopy(){ return null; } + public abstract UnmodifiableIterator iterator(); + public final boolean add(E p0){ return false; } + public final boolean addAll(Collection p0){ return false; } + public final boolean remove(Object p0){ return false; } + public final boolean removeAll(Collection p0){ return false; } + public final boolean removeIf(Predicate p0){ return false; } + public final boolean retainAll(Collection p0){ return false; } + public final void clear(){} + } + public static Set> cartesianProduct(List> p0){ return null; } + public static Set> cartesianProduct(Set... p0){ return null; } + public static TreeSet newTreeSet(){ return null; } + public static TreeSet newTreeSet(Iterable p0){ return null; } + public static > Collector> toImmutableEnumSet(){ return null; } + public static > EnumSet complementOf(Collection p0){ return null; } + public static > EnumSet complementOf(Collection p0, Class p1){ return null; } + public static > EnumSet newEnumSet(Iterable p0, Class p1){ return null; } + public static > ImmutableSet immutableEnumSet(E p0, E... p1){ return null; } + public static > ImmutableSet immutableEnumSet(Iterable p0){ return null; } + public static CopyOnWriteArraySet newCopyOnWriteArraySet(){ return null; } + public static CopyOnWriteArraySet newCopyOnWriteArraySet(Iterable p0){ return null; } + public static HashSet newHashSet(){ return null; } + public static HashSet newHashSet(E... p0){ return null; } + public static HashSet newHashSet(Iterable p0){ return null; } + public static HashSet newHashSet(Iterator p0){ return null; } + public static HashSet newHashSetWithExpectedSize(int p0){ return null; } + public static LinkedHashSet newLinkedHashSet(){ return null; } + public static LinkedHashSet newLinkedHashSet(Iterable p0){ return null; } + public static LinkedHashSet newLinkedHashSetWithExpectedSize(int p0){ return null; } + public static NavigableSet filter(NavigableSet p0, Predicate p1){ return null; } + public static NavigableSet synchronizedNavigableSet(NavigableSet p0){ return null; } + public static NavigableSet unmodifiableNavigableSet(NavigableSet p0){ return null; } + public static Set filter(Set p0, Predicate p1){ return null; } + public static Set newConcurrentHashSet(){ return null; } + public static Set newConcurrentHashSet(Iterable p0){ return null; } + public static Set newIdentityHashSet(){ return null; } + public static Set newSetFromMap(Map p0){ return null; } + public static Set> combinations(Set p0, int p1){ return null; } + public static Set> powerSet(Set p0){ return null; } + public static Sets.SetView difference(Set p0, Set p1){ return null; } + public static Sets.SetView intersection(Set p0, Set p1){ return null; } + public static Sets.SetView symmetricDifference(Set p0, Set p1){ return null; } + public static Sets.SetView union(Set p0, Set p1){ return null; } + public static SortedSet filter(SortedSet p0, Predicate p1){ return null; } + public static TreeSet newTreeSet(Comparator p0){ return null; } + public static > NavigableSet subSet(NavigableSet p0, Range p1){ return null; } } diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/SortedIterable.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/SortedIterable.java new file mode 100644 index 00000000000..41631eb4a3a --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/SortedIterable.java @@ -0,0 +1,12 @@ +// Generated automatically from com.google.common.collect.SortedIterable for testing purposes + +package com.google.common.collect; + +import java.util.Comparator; +import java.util.Iterator; + +interface SortedIterable extends Iterable +{ + Comparator comparator(); + Iterator iterator(); +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/SortedMapDifference.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/SortedMapDifference.java new file mode 100644 index 00000000000..c511f16d166 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/SortedMapDifference.java @@ -0,0 +1,14 @@ +// Generated automatically from com.google.common.collect.SortedMapDifference for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.MapDifference; +import java.util.SortedMap; + +public interface SortedMapDifference extends MapDifference +{ + SortedMap> entriesDiffering(); + SortedMap entriesInCommon(); + SortedMap entriesOnlyOnLeft(); + SortedMap entriesOnlyOnRight(); +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/SortedMultiset.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/SortedMultiset.java new file mode 100644 index 00000000000..33e26b12e56 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/SortedMultiset.java @@ -0,0 +1,28 @@ +// Generated automatically from com.google.common.collect.SortedMultiset for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.BoundType; +import com.google.common.collect.Multiset; +import com.google.common.collect.SortedIterable; +import com.google.common.collect.SortedMultisetBridge; +import java.util.Comparator; +import java.util.Iterator; +import java.util.NavigableSet; +import java.util.Set; + +public interface SortedMultiset extends SortedIterable, SortedMultisetBridge +{ + Comparator comparator(); + Iterator iterator(); + Multiset.Entry firstEntry(); + Multiset.Entry lastEntry(); + Multiset.Entry pollFirstEntry(); + Multiset.Entry pollLastEntry(); + NavigableSet elementSet(); + Set> entrySet(); + SortedMultiset descendingMultiset(); + SortedMultiset headMultiset(E p0, BoundType p1); + SortedMultiset subMultiset(E p0, BoundType p1, E p2, BoundType p3); + SortedMultiset tailMultiset(E p0, BoundType p1); +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/SortedMultisetBridge.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/SortedMultisetBridge.java new file mode 100644 index 00000000000..d61d1b242b9 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/SortedMultisetBridge.java @@ -0,0 +1,11 @@ +// Generated automatically from com.google.common.collect.SortedMultisetBridge for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.Multiset; +import java.util.SortedSet; + +interface SortedMultisetBridge extends Multiset +{ + SortedSet elementSet(); +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/SortedSetMultimap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/SortedSetMultimap.java new file mode 100644 index 00000000000..c2da3b40d85 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/SortedSetMultimap.java @@ -0,0 +1,18 @@ +// Generated automatically from com.google.common.collect.SortedSetMultimap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.SetMultimap; +import java.util.Collection; +import java.util.Comparator; +import java.util.Map; +import java.util.SortedSet; + +public interface SortedSetMultimap extends SetMultimap +{ + Comparator valueComparator(); + Map> asMap(); + SortedSet get(K p0); + SortedSet removeAll(Object p0); + SortedSet replaceValues(K p0, Iterable p1); +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/StandardRowSortedTable.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/StandardRowSortedTable.java new file mode 100644 index 00000000000..6690519bddc --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/StandardRowSortedTable.java @@ -0,0 +1,16 @@ +// Generated automatically from com.google.common.collect.StandardRowSortedTable for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.RowSortedTable; +import com.google.common.collect.StandardTable; +import java.util.Map; +import java.util.SortedMap; +import java.util.SortedSet; + +class StandardRowSortedTable extends StandardTable implements RowSortedTable +{ + protected StandardRowSortedTable() {} + public SortedMap> rowMap(){ return null; } + public SortedSet rowKeySet(){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/StandardTable.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/StandardTable.java new file mode 100644 index 00000000000..68cc22b9469 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/StandardTable.java @@ -0,0 +1,33 @@ +// Generated automatically from com.google.common.collect.StandardTable for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractTable; +import com.google.common.collect.Table; +import java.io.Serializable; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +class StandardTable extends AbstractTable implements Serializable +{ + protected StandardTable() {} + public Collection values(){ return null; } + public Map> columnMap(){ return null; } + public Map row(R p0){ return null; } + public Map> rowMap(){ return null; } + public Map column(C p0){ return null; } + public Set columnKeySet(){ return null; } + public Set rowKeySet(){ return null; } + public Set> cellSet(){ return null; } + public V get(Object p0, Object p1){ return null; } + public V put(R p0, C p1, V p2){ return null; } + public V remove(Object p0, Object p1){ return null; } + public boolean contains(Object p0, Object p1){ return false; } + public boolean containsColumn(Object p0){ return false; } + public boolean containsRow(Object p0){ return false; } + public boolean containsValue(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public int size(){ return 0; } + public void clear(){} +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Table.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Table.java index d310bd99182..bd3192c8c9e 100644 --- a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Table.java +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Table.java @@ -1,18 +1,4 @@ -/* - * Copyright (C) 2008 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Generated automatically from com.google.common.collect.Table for testing purposes package com.google.common.collect; @@ -20,50 +6,35 @@ import java.util.Collection; import java.util.Map; import java.util.Set; -public interface Table { - boolean contains(Object rowKey, Object columnKey); - - boolean containsRow(Object rowKey); - - boolean containsColumn(Object columnKey); - - boolean containsValue(Object value); - - V get(Object rowKey, Object columnKey); - - boolean isEmpty(); - - int size(); - - void clear(); - - V put(R rowKey, C columnKey, V value); - - void putAll(Table table); - - V remove(Object rowKey, Object columnKey); - - Map row(R rowKey); - - Map column(C columnKey); - - Set> cellSet(); - - Set rowKeySet(); - - Set columnKeySet(); - - Collection values(); - - Map> rowMap(); - - Map> columnMap(); - - interface Cell { - R getRowKey(); - - C getColumnKey(); - - V getValue(); - } +public interface Table +{ + Collection values(); + Map> columnMap(); + Map row(R p0); + Map> rowMap(); + Map column(C p0); + Set columnKeySet(); + Set rowKeySet(); + Set> cellSet(); + V get(Object p0, Object p1); + V put(R p0, C p1, V p2); + V remove(Object p0, Object p1); + boolean contains(Object p0, Object p1); + boolean containsColumn(Object p0); + boolean containsRow(Object p0); + boolean containsValue(Object p0); + boolean equals(Object p0); + boolean isEmpty(); + int hashCode(); + int size(); + static public interface Cell + { + C getColumnKey(); + R getRowKey(); + V getValue(); + boolean equals(Object p0); + int hashCode(); + } + void clear(); + void putAll(Table p0); } diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Tables.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Tables.java new file mode 100644 index 00000000000..9d5c157dca2 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Tables.java @@ -0,0 +1,25 @@ +// Generated automatically from com.google.common.collect.Tables for testing purposes, and adjusted manually + +package com.google.common.collect; + +import com.google.common.base.Function; +import com.google.common.base.Supplier; +import com.google.common.collect.RowSortedTable; +import com.google.common.collect.Table; +import java.util.Map; +import java.util.function.BinaryOperator; +import java.util.stream.Collector; + +public class Tables +{ + protected Tables() {} + public static Table transformValues(Table p0, Function p1){ return null; } + public static RowSortedTable unmodifiableRowSortedTable(RowSortedTable p0){ return null; } + public static Table.Cell immutableCell(R p0, C p1, V p2){ return null; } + public static Table transpose(Table p0){ return null; } + public static Table newCustomTable(Map> p0, Supplier> p1){ return null; } + public static Table synchronizedTable(Table p0){ return null; } + public static Table unmodifiableTable(Table p0){ return null; } + public static > Collector toTable(Function p0, Function p1, Function p2, BinaryOperator p3, Supplier p4){ return null; } + public static > Collector toTable(Function p0, Function p1, Function p2, Supplier p3){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/TreeBasedTable.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/TreeBasedTable.java new file mode 100644 index 00000000000..030593c26c9 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/TreeBasedTable.java @@ -0,0 +1,22 @@ +// Generated automatically from com.google.common.collect.TreeBasedTable for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.StandardRowSortedTable; +import java.util.Comparator; +import java.util.Map; +import java.util.SortedMap; +import java.util.SortedSet; + +public class TreeBasedTable extends StandardRowSortedTable +{ + protected TreeBasedTable() {} + public Comparator columnComparator(){ return null; } + public Comparator rowComparator(){ return null; } + public SortedMap row(R p0){ return null; } + public SortedMap> rowMap(){ return null; } + public SortedSet rowKeySet(){ return null; } + public static TreeBasedTable create(){ return null; } + public static TreeBasedTable create(Comparator p0, Comparator p1){ return null; } + public static TreeBasedTable create(TreeBasedTable p0){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/TreeMultimap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/TreeMultimap.java new file mode 100644 index 00000000000..97e9c26c95f --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/TreeMultimap.java @@ -0,0 +1,23 @@ +// Generated automatically from com.google.common.collect.TreeMultimap for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractSortedKeySortedSetMultimap; +import com.google.common.collect.Multimap; +import java.util.Collection; +import java.util.Comparator; +import java.util.NavigableMap; +import java.util.NavigableSet; + +public class TreeMultimap extends AbstractSortedKeySortedSetMultimap +{ + protected TreeMultimap() {} + public Comparator keyComparator(){ return null; } + public Comparator valueComparator(){ return null; } + public NavigableMap> asMap(){ return null; } + public NavigableSet keySet(){ return null; } + public NavigableSet get(K p0){ return null; } + public static TreeMultimap create(){ return null; } + public static TreeMultimap create(Multimap p0){ return null; } + public static TreeMultimap create(Comparator p0, Comparator p1){ return null; } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/TreeMultiset.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/TreeMultiset.java new file mode 100644 index 00000000000..e76b3086159 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/TreeMultiset.java @@ -0,0 +1,30 @@ +// Generated automatically from com.google.common.collect.TreeMultiset for testing purposes + +package com.google.common.collect; + +import com.google.common.collect.AbstractSortedMultiset; +import com.google.common.collect.BoundType; +import com.google.common.collect.SortedMultiset; +import java.io.Serializable; +import java.util.Comparator; +import java.util.Iterator; +import java.util.function.ObjIntConsumer; + +public class TreeMultiset extends AbstractSortedMultiset implements Serializable +{ + protected TreeMultiset() {} + public Iterator iterator(){ return null; } + public SortedMultiset headMultiset(E p0, BoundType p1){ return null; } + public SortedMultiset tailMultiset(E p0, BoundType p1){ return null; } + public boolean setCount(E p0, int p1, int p2){ return false; } + public int add(E p0, int p1){ return 0; } + public int count(Object p0){ return 0; } + public int remove(Object p0, int p1){ return 0; } + public int setCount(E p0, int p1){ return 0; } + public int size(){ return 0; } + public static TreeMultiset create(){ return null; } + public static TreeMultiset create(Iterable p0){ return null; } + public static TreeMultiset create(Comparator p0){ return null; } + public void clear(){} + public void forEachEntry(ObjIntConsumer p0){} +} diff --git a/java/ql/test/stubs/jakarta-mail-2.0.1/jakarta/mail/Authenticator.java b/java/ql/test/stubs/jakarta-mail-2.0.1/jakarta/mail/Authenticator.java new file mode 100644 index 00000000000..594f3876f19 --- /dev/null +++ b/java/ql/test/stubs/jakarta-mail-2.0.1/jakarta/mail/Authenticator.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package jakarta.mail; + +public abstract class Authenticator { +} diff --git a/java/ql/test/stubs/jakarta-mail-2.0.1/jakarta/mail/PasswordAuthentication.java b/java/ql/test/stubs/jakarta-mail-2.0.1/jakarta/mail/PasswordAuthentication.java new file mode 100644 index 00000000000..20751b7f7d9 --- /dev/null +++ b/java/ql/test/stubs/jakarta-mail-2.0.1/jakarta/mail/PasswordAuthentication.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the terms of the Eclipse + * Public License v. 2.0, which is available at http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary Licenses when the + * conditions for such availability set forth in the Eclipse Public License v. 2.0 are satisfied: + * GNU General Public License, version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package jakarta.mail; + +public final class PasswordAuthentication { + public PasswordAuthentication(String userName, String password) {} + + public String getUserName() { + return null; + } + + public String getPassword() { + return null; + } + +} diff --git a/java/ql/test/stubs/jakarta-mail-2.0.1/jakarta/mail/Session.java b/java/ql/test/stubs/jakarta-mail-2.0.1/jakarta/mail/Session.java new file mode 100644 index 00000000000..6f525babdae --- /dev/null +++ b/java/ql/test/stubs/jakarta-mail-2.0.1/jakarta/mail/Session.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the terms of the Eclipse + * Public License v. 2.0, which is available at http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary Licenses when the + * conditions for such availability set forth in the Eclipse Public License v. 2.0 are satisfied: + * GNU General Public License, version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package jakarta.mail; + +import java.lang.reflect.*; +import java.io.*; +import java.net.*; +import java.security.*; +import java.util.Properties; + +public final class Session { + public static Session getInstance(Properties props, Authenticator authenticator) { + return null; + } + + public static Session getInstance(Properties props) { + return null; + } + + public static synchronized Session getDefaultInstance(Properties props, + Authenticator authenticator) { + return null; + } + + public static Session getDefaultInstance(Properties props) { + return null; + } + + public synchronized void setDebug(boolean debug) {} + + public synchronized boolean getDebug() { + return false; + } + + public synchronized void setDebugOut(PrintStream out) {} + + public synchronized PrintStream getDebugOut() { + return null; + } + + public synchronized Provider[] getProviders() { + return null; + } + + public synchronized Provider getProvider(String protocol) throws NoSuchProviderException { + return null; + } + + public synchronized void setProvider(Provider provider) throws NoSuchProviderException {} + + public PasswordAuthentication requestPasswordAuthentication(InetAddress addr, int port, + String protocol, String prompt, String defaultUserName) { + return null; + } + + public Properties getProperties() { + return null; + } + + public String getProperty(String name) { + return null; + } + + public synchronized void addProvider(Provider provider) {} + + public synchronized void setProtocolForAddress(String addresstype, String protocol) {} + +} diff --git a/java/ql/test/stubs/javax-faces-2.3/javax/faces/component/UIComponent.java b/java/ql/test/stubs/javax-faces-2.3/javax/faces/component/UIComponent.java new file mode 100644 index 00000000000..a7d9efd8391 --- /dev/null +++ b/java/ql/test/stubs/javax-faces-2.3/javax/faces/component/UIComponent.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package javax.faces.component; + +import java.util.Map; + +/** + *

    + * UIComponent is the base class for + * all user interface components in Jakarta Server Faces. The set of {@link UIComponent} + * instances associated with a particular request and response are organized into a + * component tree under a {@link UIViewRoot} that represents the entire content of the + * request or response. + *

    + * + *

    + * For the convenience of component developers, {@link UIComponentBase} provides the + * default behavior that is specified for a {@link UIComponent}, and is the base class for + * all of the concrete {@link UIComponent} "base" implementations. Component writers are + * encouraged to subclass {@link UIComponentBase}, instead of directly implementing this + * abstract class, to reduce the impact of any future changes to the method signatures. + *

    + * + *

    + * If the {@link javax.faces.event.ListenerFor} annotation is attached to the class + * definition of a Component, that class must also implement + * {@link javax.faces.event.ComponentSystemEventListener}. + *

    + * + *

    + * Dynamically modifying the component tree can happen at any time, during and after + * restoring the view, but not during state saving and needs to function properly with + * respect to rendering and state saving + *

    + */ +public abstract class UIComponent { + + /** + *

    + * Return a mutable Map representing the attributes (and properties, see + * below) associated wth this {@link UIComponent}, keyed by attribute name (which must + * be a String). The returned implementation must support all of the standard and + * optional Map methods, plus support the following additional + * requirements: + *

    + *
      + *
    • The Map implementation must implement the + * java.io.Serializable interface.
    • + *
    • Any attempt to add a null key or value must throw a + * NullPointerException.
    • + *
    • Any attempt to add a key that is not a String must throw a + * ClassCastException.
    • + *
    • If the attribute name specified as a key matches a property of this + * {@link UIComponent}'s implementation class, the following methods will have special + * behavior: + *
        + *
      • containsKey - Return false.
      • + *
      • get() - If the property is readable, call the getter method and + * return the returned value (wrapping primitive values in their corresponding wrapper + * classes); otherwise throw IllegalArgumentException.
      • + *
      • put() - If the property is writeable, call the setter method to + * set the corresponding value (unwrapping primitive values in their corresponding + * wrapper classes). If the property is not writeable, or an attempt is made to set a + * property of primitive type to null, throw + * IllegalArgumentException.
      • + *
      • remove - Throw IllegalArgumentException.
      • + *
      + *
    • + *
    + * + * @return the component attribute map. + */ + public abstract Map getAttributes(); +} diff --git a/java/ql/test/stubs/javax-faces-2.3/javax/faces/context/ExternalContext.java b/java/ql/test/stubs/javax-faces-2.3/javax/faces/context/ExternalContext.java new file mode 100644 index 00000000000..76b985e9788 --- /dev/null +++ b/java/ql/test/stubs/javax-faces-2.3/javax/faces/context/ExternalContext.java @@ -0,0 +1,1076 @@ +/* + * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package javax.faces.context; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Writer; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +/** + *

    + * This class allows the Faces API to be unaware of the nature of its containing + * application environment. In particular, this class allows Jakarta Server Faces based + * applications to run in either a Jakarta Servlet or a Portlet environment.

    + * + *

    The documentation for this class only + * specifies the behavior for the Jakarta Servlet implementation of + * ExternalContext. The Portlet implementation of + * ExternalContext is specified under the revision of the + * Portlet Bridge + * Specification for JavaServer Faces JSR that corresponds to + * this version of the Jakarta Server Faces specification. See the Preface of the + * "prose document", linked + * from the javadocs, for a reference.

    + + *

    If a reference to an + * ExternalContext is obtained during application startup or shutdown + * time, any method documented as "valid to call this method during + * application startup or shutdown" must be supported during application startup or shutdown + * time. The result of calling a method during application startup or shutdown time + * that does not have this designation is undefined.

    + * + *

    An ExternalContext can be injected into a CDI + * managed bean using @Inject ExternalContext externalContext; + *

    + */ + +public abstract class ExternalContext { + + /** + *

    Adds the cookie represented by the + * arguments to the response.

    + * + *
    + * + *

    Jakarta Servlet: This must be accomplished by calling the + * javax.servlet.http.HttpServletResponse method + * addCookie(). The Cookie argument must + * be constructed by passing the name and + * value parameters. If the properties + * arugument is non-null and not empty, the + * Cookie instance must be initialized as described + * below.

    + * + *

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    Cookie handling table
    Key in "values" MapExpected type of value.Name of setter method on Cookie instance to be + * set with the value from the Map.
    commentStringsetComment
    domainStringsetDomain
    maxAgeIntegersetMaxAge
    secureBooleansetSecure
    pathStringsetPath
    httpOnlyBooleansetHttpOnly
    + * + *

    The default implementation throws + * UnsupportedOperationException and is provided for + * the sole purpose of not breaking existing applications that + * extend this class.

    + * + * + * + * @param name To be passed as the first argument to the + * Cookie constructor. + * + * @param value To be passed as the second argument to the + * Cookie constructor. + * + * @param properties A Map containg key/value pairs to be passed + * as arguments to the setter methods as described above. + * + * @throws IllegalArgumentException if the properties + * Map is not-null and not empty and contains + * any keys that are not one of the keys listed above. + * + * @since 2.0 + */ + + public void addResponseCookie(String name, + String value, + Map properties) { + } + + + /** + *

    Dispatch a request to the specified resource to create output + * for this response.

    + * + *

    Jakarta Servlet: This must be accomplished by calling the + * javax.servlet.ServletContext method + * getRequestDispatcher(path), and calling the + * forward() method on the resulting object.

    + *

    If the call to getRequestDisatcher(path) + * returns null, send aServletResponse SC_NOT_FOUND + * error code.

    + * + * @param path Context relative path to the specified resource, + * which must start with a slash ("/") character + * + * @throws javax.faces.FacesException thrown if a ServletException occurs + * @throws IOException if an input/output error occurs + */ + public abstract void dispatch(String path) throws IOException; + + + /** + *

    Return the input URL, after performing any rewriting needed to + * ensure that it will correctly identify an addressable action in the + * current application.

    + * + *

    Encoding the {@link javax.faces.lifecycle.ClientWindow}

    + * + *
    + * + *

    Call {@link javax.faces.lifecycle.ClientWindow#isClientWindowRenderModeEnabled(javax.faces.context.FacesContext) }. + * If the result is false take no further action and return + * the rewritten URL. If the result is true, call {@link #getClientWindow()}. + * If the result is non-null, call {@link javax.faces.lifecycle.ClientWindow#getId()} + * and append the id to the query string of the URL, making the necessary + * allowances for a pre-existing query string or no query-string.

    + * + *

    Call {@link javax.faces.lifecycle.ClientWindow#getQueryURLParameters}. + * If the result is non-{@code null}, for each parameter in the map, + * unconditionally add that parameter to the URL.

    + * + *

    The name + * of the query string parameter is given by the value of the constant + * {@link javax.faces.render.ResponseStateManager#CLIENT_WINDOW_URL_PARAM}.

    + * + *
    + * + *

    Jakarta Servlet: This must be the value returned by the + * javax.servlet.http.HttpServletResponse method + * encodeURL(url).

    + * + * @param url The input URL to be encoded + * + * @return the encoded URL. + * + * @throws NullPointerException if url + * is null + */ + public abstract String encodeActionURL(String url); + + + /** + *

    Return the input URL, after performing any rewriting needed to + * ensure that it will correctly identify an addressable resource in the + * current application.

    + * + *

    Jakarta Servlet: This must be the value returned by the + * javax.servlet.http.HttpServletResponse method + * encodeURL(url).

    + * + * @param url The input URL to be encoded + * + * @return the encoded resource URL. + * + * @throws NullPointerException if url + * is null + */ + // PENDING(craigmcc) - Currently identical to encodeActionURL() + public abstract String encodeResourceURL(String url); + + + /** + *

    + * Return the websocket URL, after performing any rewriting needed to + * ensure that it will correctly identify an addressable websocket in the + * current application. + *

    + * + *

    + * Jakarta Servlet: This must ensure that the input URL is prefixed + * with the correct websocket scheme, domain and port and then + * encoded by {@link #encodeResourceURL(String)}. + *

    + * + * @param url The input URL to be encoded. + * + * @return the encoded websocket URL. + * + * @throws NullPointerException if url is null. + * + * @since 2.3 + */ + public abstract String encodeWebsocketURL(String url); + + + /** + *

    Returns the MIME type of the + * specified file or null if the MIME type is not + * known. The MIME type is determined by the container.

    + + *

    It is valid to call this method + * during application startup or shutdown. If called during application + * startup or shutdown, this method calls through to the + * getMimeType() method on the same container + * context instance (ServletContext or + * PortletContext) as the one used when calling + * getMimeType() on the + * ExternalContext returned by the + * FacesContext during an actual request.

    + + *
    + + *

    Jakarta Servlet: This must be the value returned by the + * javax.servlet.ServletContext method + * getMimeType().

    + * + *
    + * + * @param file The file for which the mime type should be obtained. + * + * @return the MIME type of the file. + * + * @since 2.0 + */ + public String getMimeType(String file) { + return null; + } + + + /** + *

    Return the + * application environment object instance for the current + * appication.

    + + *

    It is valid to call this method + * during application startup or shutdown. If called during application + * startup or shutdown, this returns the same container context instance + * (ServletContext or PortletContext) as + * the one returned when calling getContext() on the + * ExternalContext returned by the + * FacesContext during an actual request.

    + + * + *

    Jakarta Servlet: This must be the current application's + * javax.servlet.ServletContext instance.

    + * + * @return the object of the ServletContext. + * + */ + public abstract Object getContext(); + + + /** + * + *

    Return the name of the container + * context for this application.

    + * + *

    Jakarta Servlet: + * Return the result of calling + * getContextPath() on the + * ServletContext instance for this application.

    + + *

    It is valid to call this method during application startup or + * shutdown.

    + * + *

    The default implementation throws + * UnsupportedOperationException and is provided for + * the sole purpose of not breaking existing applications that + * extend this class.

    + * + * @return the context path of this application. + * + * @since 2.2 + */ + + public String getApplicationContextPath() { + return null; + } + + + /** + *

    Return the value of + * the specified application initialization parameter (if any).

    + * + *

    Jakarta Servlet: This must be the result of the + * javax.servlet.ServletContext method + * getInitParameter(name).

    + * + *

    It is valid to call this method + * during application startup or shutdown. If called during application + * startup or shutdown, this method calls through to the actual container + * context to return the init parameter value.

    + + * @param name Name of the requested initialization parameter + * + * @throws NullPointerException if name + * is null + * + * @return the value of the specified parameter. + * + */ + public abstract String getInitParameter(String name); + + + /** + *

    Return an + * immutable Map whose keys are the set of application + * initialization parameter names configured for this application, + * and whose values are the corresponding parameter values. The + * returned Map must implement the entire contract for + * an unmodifiable map as described in the JavaDocs for + * java.util.Map.

    + * + *

    It is valid to call this method + * during application startup or shutdown. If called during application + * startup or shutdown, this method returns a Map that is backed by + * the same container context instance (ServletContext + * or PortletContext) as the one returned by calling + * getInitParameterMap() on the + * ExternalContext returned by the + * FacesContext during an actual request.

    + * + *

    Jakarta Servlet: This result must be as if it were synthesized + * by calling the javax.servlet.ServletContext + * method getInitParameterNames, and putting + * each configured parameter name/value pair into the result.

    + * + * @return the init parameter map for this application. + * + */ + public abstract Map getInitParameterMap(); + + + /** + *

    Return the login name of the user making the current request + * if any; otherwise, return null.

    + * + *

    Jakarta Servlet: This must be the value returned by the + * javax.servlet.http.HttpServletRequest method + * getRemoteUser().

    + * + * @return the user name of the current request. + * + */ + public abstract String getRemoteUser(); + + + /** + *

    Return the environment-specific object instance for the current + * request.

    + * + *

    Jakarta Servlet: This must be the current request's + * javax.servlet.http.HttpServletRequest instance.

    + * + * @return the instance of the current request. + * + */ + public abstract Object getRequest(); + + + /** + *

    Set the environment-specific request to be returned by + * subsequent calls to {@link #getRequest}. This may be used to + * install a wrapper for the request.

    + * + *

    The default implementation throws + * UnsupportedOperationException and is provided + * for the sole purpose of not breaking existing applications that extend + * this class.

    + * + * @param request the request object to be set. + * + * @since 1.2 + */ + public void setRequest(Object request) { + } + + + /** + *

    Returns the name of the scheme used + * to make this request, for example, http, https, or ftp.

    + * + *
    + *

    Jakarta Servlet: This must be the value returned by the + * javax.servlet.ServletRequest method + * getScheme().

    + * + *

    The default implementation throws + * UnsupportedOperationException and is provided for + * the sole purpose of not breaking existing applications that + * extend this class.

    + * + *
    + * + * @return the name of the scheme. + * + * @since 2.0 + */ + public String getRequestScheme() { + return null; + } + + + /** + *

    Returns the host name of the server + * to which the request was sent.

    + * + *
    + * + *

    Jakarta Servlet: This must be the value returned by the + * javax.servlet.ServletRequest method + * getServerName().

    + * + *

    The default implementation throws + * UnsupportedOperationException and is provided for + * the sole purpose of not breaking existing applications that + * extend this class.

    + * + *
    + * + * @return the host name of the server. + * + * @since 2.0 + */ + public String getRequestServerName() { + return null; + } + + + /** + *

    Returns the port number to which + * the request was sent.

    + * + *
    + * + *

    Jakarta Servlet: This must be the value returned by the + * javax.servlet.ServletRequest method + * getServerPort().

    + * + *

    The default implementation throws + * UnsupportedOperationException and is provided for + * the sole purpose of not breaking existing applications that + * extend this class.

    + * + *
    + * + * @return the port number to which the request was sent. + * + * @since 2.0 + */ + public int getRequestServerPort() { + return -1; + } + + + /** + *

    Returns a String containing the real + * path for a given virtual path.

    + * + *

    It is valid to call this method + * during application startup or shutdown. If called during application + * startup or shutdown, this method calls through to the + * getRealPath() method on the same container + * context instance (ServletContext or + * PortletContext) as the one used when calling + * getRealPath() on the + * ExternalContext returned by the + * FacesContext during an actual request. + *

    + * + *
    + * + *

    Jakarta Servlet: This must be the value returned by the + * javax.servlet.ServletContext method + * getRealPath().

    + * + *

    The default implementation throws + * UnsupportedOperationException and is provided + * for the sole purpose of not breaking existing applications that extend + * this class.

    + * + *
    + * + * @param path The context of the requested initialization parameter + * + * @return the real path for the specified virtual path. + * + * @since 2.0 + */ + public String getRealPath(String path) { + return null; + } + + + /** + *

    Return the portion of the request URI that identifies the web + * application context for this request.

    + * + *

    Jakarta Servlet: This must be the value returned by the + * javax.servlet.http.HttpServletRequest method + * getContextPath().

    + * + * @return the context path for this request. + */ + public abstract String getRequestContextPath(); + + + /** + *

    Return an immutable Map whose keys are the set of + * cookie names included in the current request, and whose + * values (of type javax.servlet.http.Cookie) + * are the first (or only) cookie for each cookie name + * returned by the underlying request. The returned + * Map must implement the entire contract for an unmodifiable + * map as described in the JavaDocs for java.util.Map.

    + * + *

    Jakarta Servlet: This must be the value returned by the + * javax.servlet.http.HttpServletRequest method + * getCookies(), unless null was returned, + * in which case this must be a zero-length array.

    + * + * @return the cookie map in the current request. + * + */ + public abstract Map getRequestCookieMap(); + + + /** + *

    Return an immutable Map whose keys are the set of + * request header names included in the current request, and whose + * values (of type String) are the first (or only) value for each + * header name returned by the underlying request. The returned + * Map must implement the entire contract for an unmodifiable + * map as described in the JavaDocs for java.util.Map. In + * addition, key comparisons must be performed in a case insensitive + * manner.

    + * + *

    Jakarta Servlet: This must be the set of headers available via + * the javax.servlet.http.HttpServletRequest methods + * getHeader() and getHeaderNames().

    + * + * @return the header map in the current request. + * + */ + public abstract Map getRequestHeaderMap(); + + + /** + *

    Return an immutable Map whose keys are the set of + * request header names included in the current request, and whose + * values (of type String[]) are all of the value for each + * header name returned by the underlying request. The returned + * Map must implement the entire contract for an unmodifiable + * map as described in the JavaDocs for java.util.Map. In + * addition, key comparisons must be performed in a case insensitive + * manner.

    + * + *

    Jakarta Servlet: This must be the set of headers available via + * the javax.servlet.http.HttpServletRequest methods + * getHeaders() and getHeaderNames().

    + * + * @return the header values map in the current request. + */ + public abstract Map getRequestHeaderValuesMap(); + + + /** + *

    Return a mutable Map representing the request + * scope attributes for the current application. The returned + * Map must implement the entire contract for a + * modifiable map as described in the JavaDocs for + * java.util.Map. Modifications made in the + * Map must cause the corresponding changes in the set + * of request scope attributes. Particularly the + * clear(), remove(), put(), + * putAll(), and get() operations must + * take the appropriate action on the underlying data structure.

    + * + *

    For any of the Map methods that cause an element + * to be removed from the underlying data structure, the following + * action regarding managed-beans must be taken. If the element to + * be removed is a managed-bean, and it has one or more public + * no-argument void return methods annotated with + * javax.annotation.PreDestroy, each such method must + * be called before the element is removed from the underlying data + * structure. Elements that are not managed-beans, but do happen to + * have methods with that annotation must not have those methods + * called on removal. Any exception thrown by the + * PreDestroy annotated methods must by caught and not + * rethrown. The exception may be logged.

    + * + *

    Jakarta Servlet: This must be the set of attributes available via + * the javax.servlet.ServletRequest methods + * getAttribute(), getAttributeNames(), + * removeAttribute(), and setAttribute().

    + * + * @return the map including the attributes of the current request. + * + */ + public abstract Map getRequestMap(); + + + /** + *

    Return an immutable Map whose keys are the set of + * request parameters names included in the current request, and whose + * values (of type String) are the first (or only) value for each + * parameter name returned by the underlying request. The returned + * Map must implement the entire contract for an unmodifiable + * map as described in the JavaDocs for java.util.Map.

    + * + *

    Jakarta Servlet: This must be the set of parameters available via + * the javax.servlet.ServletRequest methods + * getParameter() and getParameterNames().

    + * + * @return the map for the current request parameters. + * + */ + public abstract Map getRequestParameterMap(); + + + /** + *

    Return an Iterator over the names of all request + * parameters included in the current request.

    + * + *

    Jakarta Servlet: This must be an Iterator over the + * values returned by the javax.servlet.ServletRequest + * method getParameterNames().

    + * + * @return the Iterator for the names of the current request parameters. + * + */ + public abstract Iterator getRequestParameterNames(); + + + /** + *

    Return an immutable Map whose keys are the set of + * request parameters names included in the current request, and whose + * values (of type String[]) are all of the values for each + * parameter name returned by the underlying request. The returned + * Map must implement the entire contract for an unmodifiable + * map as described in the JavaDocs for java.util.Map.

    + * + *

    Jakarta Servlet: This must be the set of parameters available via + * the javax.servlet.ServletRequest methods + * getParameterValues() and + * getParameterNames().

    + * + * @return the map for the parameter values of the current request. + * + */ + public abstract Map getRequestParameterValuesMap(); + + + /** + *

    Return the extra path information (if any) included in the + * request URI; otherwise, return null.

    + * + *

    Jakarta Servlet: This must be the value returned by the + * javax.servlet.http.HttpServletRequest method + * getPathInfo().

    + * + * @return the path information of the current request. + * + */ + public abstract String getRequestPathInfo(); + + + /** + *

    Return the Jakarta Servlet path information (if any) included in the + * request URI; otherwise, return null.

    + * + *

    Jakarta Servlet: This must be the value returned by the + * javax.servlet.http.HttpServletRequest method + * getServletPath().

    + * + * @return the Jakarta Servlet path information of the current request. + */ + public abstract String getRequestServletPath(); + + + /** + *

    Return a + * URL for the application resource mapped to the + * specified path, if it exists; otherwise, return + * null.

    + * + *

    It is valid to call this method + * during application startup or shutdown. If called during application + * startup or shutdown, this method calls through to the + * getResource() method on the same container + * context instance (ServletContext or + * PortletContext) as the one used when calling + * getResource() on the + * ExternalContext returned by the + * FacesContext during an actual request.

    + + *

    Jakarta Servlet: This must be the value returned by the + * javax.servlet.ServletContext method + * getResource(path).

    + * + * @param path The path to the requested resource, which must + * start with a slash ("/" character + * + * @return the URL of the resource. + * + * @throws MalformedURLException if the specified path + * is not in the correct form + * @throws NullPointerException if path + * is null + */ + public abstract URL getResource(String path) throws MalformedURLException; + + + /** + *

    Return an + * InputStream for an application resource mapped to + * the specified path, if it exists; otherwise, return + * null.

    + + *

    It is valid to call this method + * during application startup or shutdown. If called during application + * startup or shutdown, this method calls through to the + * getResourceAsStream() method on the same container + * context instance (ServletContext or + * PortletContext) as the one used when calling + * getResourceAsStream() on the + * ExternalContext returned by the + * FacesContext during an actual request.

    + * + *

    Jakarta Servlet: This must be the value returned by the + * javax.servlet.ServletContext method + * getResourceAsStream(path).

    + * + * @param path The path to the requested resource, which must + * start with a slash ("/" character + * + * @return the InputStream for the application resource. + * + * @throws NullPointerException if path + * is null + */ + public abstract InputStream getResourceAsStream(String path); + + + /** + *

    Return the + * Set of resource paths for all application resources + * whose resource path starts with the specified argument.

    + * + *

    It is valid to call this method + * during application startup or shutdown. If called during application + * startup or shutdown, this method calls through to the + * getResourcePaths() method on the same container + * context instance (ServletContext or + * PortletContext) as the one used when calling + * getResourcePaths() on the + * ExternalContext returned by the + * FacesContext during an actual request.

    + + *

    Jakarta Servlet: This must be the value returned by the + * javax.servlet.ServletContext method + * getResourcePaths(path).

    + * + * @param path Partial path used to match resources, which must + * start with a slash ("/") character + * + * @return the Set of resource paths for the application resources. + * + * @throws NullPointerException if path + * is null + */ + public abstract Set getResourcePaths(String path); + + + /** + *

    Return the environment-specific object instance for the current + * response.

    + * + *

    Jakarta Servlet: This is the current request's + * javax.servlet.http.HttpServletResponse instance.

    + * + * @return the instance of the current javax.servlet.http.HttpServletResponse. + */ + public abstract Object getResponse(); + + /** + *

    Set the environment-specific response to be returned by + * subsequent calls to {@link #getResponse}. This may be used to + * install a wrapper for the response.

    + * + *

    The default implementation throws + * UnsupportedOperationException and is provided + * for the sole purpose of not breaking existing applications that extend + * this class.

    + * + * @param response the response instance to be set. + * + * @since 1.2 + */ + public void setResponse(Object response) { + } + + + /** + *

    Returns an OutputStream + * suitable for writing binary data to the user-agent.

    + * + *
    + * + *

    Jakarta Servlet: This must return the value returned by the + * javax.servlet.ServletResponse method + * getOutputStream().

    + * + *

    The default implementation throws + * UnsupportedOperationException and is provided for + * the sole purpose of not breaking existing applications that + * extend this class.

    + * + *
    + * + * @return the OutputStream for the current response. + * + * @throws IOException any IO related exception. + * + * @since 2.0 + */ + public OutputStream getResponseOutputStream() throws IOException { + return null; + } + + + /** + *

    Returns a Writer + * suitable for writing character data to the user-agent.

    + * + *
    + * + *

    Jakarta Servlet: This must return the value returned by the + * {@link javax.servlet.ServletResponse#getWriter}.

    + * + *

    The default implementation throws + * UnsupportedOperationException and is provided for + * the sole purpose of not breaking existing applications that + * extend this class.

    + * + *
    + * + * @return the Writer for the current response. + * + * @throws IOException any IO related exception. + * + * @since 2.0 + */ + public Writer getResponseOutputWriter() throws IOException { + return null; + } + + + /** + *

    Redirect a request + * to the specified URL, and cause the + * responseComplete() method to be called on the + * {@link FacesContext} instance for the current request.

    + * + *

    The implementation must determine if + * the request is an Ajax request by obtaining a + * {@link PartialViewContext} instance from the {@link FacesContext} and + * calling {@link PartialViewContext#isAjaxRequest()}.

    + * + *

    Jakarta Servlet: For + * non Ajax requests, this must be accomplished by calling + * the javax.servlet.http.HttpServletResponse method + * sendRedirect().

    + * For Ajax requests, the implementation must: + *
    + *
      + *
    • Get a {@link PartialResponseWriter} instance from the + * {@link FacesContext}.
    • + *
    • Call {@link #setResponseContentType} with text/xml
    • + *
    • Call {@link #setResponseCharacterEncoding} with UTF-8
    • + *
    • Call {@link #addResponseHeader} with Cache-Control, + * no-cache
    • + *
    • Call {@link PartialResponseWriter#startDocument}
    • + *
    • Call {@link PartialResponseWriter#redirect} with the url + * argument.
    • + *
    • Call {@link PartialResponseWriter#endDocument}
    • + *
    + * + * @param url Absolute URL to which the client should be redirected + * + * @throws IllegalArgumentException if the specified url is relative + * @throws IllegalStateException if, in a portlet environment, + * the current response object is a RenderResponse + * instead of an ActionResponse + * @throws IllegalStateException if, in a Jakarta Servlet environment, + * the current response has already been committed + * @throws IOException if an input/output error occurs + */ + public abstract void redirect(String url) throws IOException; + + + /** + *

    Set the response header with the given name and value.

    + * + *

    Jakarta Servlet:This must be performed by calling the + * javax.servlet.http.HttpServletResponse setHeader + * method.

    + * + *

    The default implementation throws + * UnsupportedOperationException and is provided for + * the sole purpose of not breaking existing applications that + * extend this class.

    + * + * @param name The name of the response header. + * @param value The value of the response header. + * + * @since 2.0 + */ + public void setResponseHeader(String name, String value) { + } + + /** + *

    Add the given name and value to the response header.

    + * + *

    Jakarta Servlet:This must be performed by calling the + * javax.servlet.http.HttpServletResponse addHeader + * method.

    + * + *

    The default implementation throws + * UnsupportedOperationException and is provided for + * the sole purpose of not breaking existing applications that + * extend this class.

    + * + * @param name The name of the response header. + * @param value The value of the response header. + * + * @since 2.0 + */ + public void addResponseHeader(String name, String value) { + } + + + /** + *

    Sets the HTTP status code for the response.

    + * + *

    Jakarta Servlet: This must be performed by calling the + * javax.servlet.http.HttpServletResponse setStatus + * method.

    + * + *

    The default implementation throws + * UnsupportedOperationException and is provided for + * the sole purpose of not breaking existing applications that + * extend this class.

    + * + * @param statusCode an HTTP status code + * + * @since 2.0 + */ + public void setResponseStatus(int statusCode) { + } + + + /** + * The purpose of this method is to generate a query string from the collection of Parameter + * objects provided by the parameters argument and append that query string to the baseUrl. + * This method must be able to encode the parameters to a baseUrl that may or may not have existing query parameters. The parameter values should be encoded appropriately for the + * environment so that the resulting URL can be used as the target of a redirect. It's + * possible for an ExternalContext implementation to override this method to accomodate the + * definition of redirect for that environment. + * + *

    See {@link #encodeActionURL(java.lang.String)} + * for the required specification of how to encode the {@link javax.faces.lifecycle.ClientWindow}. + *

    + * + * @param baseUrl The base URL onto which the query string generated by this method will be appended. The URL may contain query parameters. + * @param parameters The collection of Parameter objects, representing name=value pairs that are used to produce a query string + * + * @return the result of encoding. + * @since 2.0 + */ + public String encodeRedirectURL(String baseUrl, + Map> parameters) { + return null; + } +} diff --git a/java/ql/test/stubs/javax-faces-2.3/javax/faces/context/FacesContext.java b/java/ql/test/stubs/javax-faces-2.3/javax/faces/context/FacesContext.java new file mode 100644 index 00000000000..9c56dd6340b --- /dev/null +++ b/java/ql/test/stubs/javax-faces-2.3/javax/faces/context/FacesContext.java @@ -0,0 +1,195 @@ +/* + * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package javax.faces.context; + + +import java.util.Iterator; +import java.util.Map; + +/** + *

    FacesContext contains all of the + * per-request state information related to the processing of a single + * Jakarta Server Faces request, and the rendering of the corresponding + * response. It is passed to, and potentially modified by, each phase + * of the request processing lifecycle.

    + * + *

    A {@link FacesContext} instance is associated with a particular + * request at the beginning of request processing, by a call to the + * getFacesContext() method of the {@link FacesContextFactory} + * instance associated with the current web application. The instance + * remains active until its release() method is called, after + * which no further references to this instance are allowed. While a + * {@link FacesContext} instance is active, it must not be referenced + * from any thread other than the one upon which the Jakarta Servlet container + * executing this web application utilizes for the processing of this request. + *

    + * + *

    A FacesContext can be injected into a request + * scoped bean using @Inject FacesContext facesContext; + *

    + */ + +public abstract class FacesContext { + + public FacesContext() { + } + + /** + *

    Return a mutable Map + * representing the attributes associated wth this + * FacesContext instance. This Map is + * useful to store attributes that you want to go out of scope when the + * Faces lifecycle for the current request ends, which is not always the same + * as the request ending, especially in the case of Jakarta Servlet filters + * that are invoked after the Faces lifecycle for this + * request completes. Accessing this Map does not cause any + * events to fire, as is the case with the other maps: for request, session, and + * application scope. When {@link #release()} is invoked, the attributes + * must be cleared.

    + * + *
    + * + *

    The Map returned by this method is not associated with + * the request. If you would like to get or set request attributes, + * see {@link ExternalContext#getRequestMap}. + * + *

    The default implementation throws + * UnsupportedOperationException and is provided + * for the sole purpose of not breaking existing applications that extend + * this class.

    + * + *
    + * + * @return mutable Map representing the attributes associated wth this + * FacesContext instance. + * + * @throws IllegalStateException if this method is called after + * this instance has been released + * + * @since 2.0 + */ + + public Map getAttributes() { + return null; + } + + /** + *

    Return an Iterator over the client identifiers for + * which at least one {@link javax.faces.application.FacesMessage} has been queued. If there are no + * such client identifiers, an empty Iterator is returned. + * If any messages have been queued that were not associated with any + * specific client identifier, a null value will be included + * in the iterated values. The elements in the Iterator must + * be returned in the order in which they were added with {@link #addMessage}.

    + * + * @return the Iterator over the client identifiers for + * which at least one {@link javax.faces.application.FacesMessage} has been queued. + * + * @throws IllegalStateException if this method is called after + * this instance has been released + */ + public abstract Iterator getClientIdsWithMessages(); + + /** + *

    Return the {@link + * ExternalContext} instance for this FacesContext + * instance.

    + + *

    It is valid to call this method + * during application startup or shutdown. If called during application + * startup or shutdown, this method returns an {@link ExternalContext} instance + * with the special behaviors indicated in the javadoc for that + * class. Methods document as being valid to call during + * application startup or shutdown must be supported.

    + * + * @return instance of ExternalContext + * + * @throws IllegalStateException if this method is called after + * this instance has been released + */ + public abstract ExternalContext getExternalContext(); + + /** + *

    Return the {@link ResponseStream} to which components should + * direct their binary output. Within a given response, components + * can use either the ResponseStream or the ResponseWriter, + * but not both. + * + * @return ResponseStream instance. + * + * @throws IllegalStateException if this method is called after + * this instance has been released + */ + public abstract ResponseStream getResponseStream(); + + /** + *

    Set the {@link ResponseStream} to which components should + * direct their binary output. + * + * @param responseStream The new ResponseStream for this response + * + * @throws NullPointerException if responseStream + * is null + * + * @throws IllegalStateException if this method is called after + * this instance has been released + */ + public abstract void setResponseStream(ResponseStream responseStream); + + /** + *

    Return the {@link ResponseWriter} to which components should + * direct their character-based output. Within a given response, + * components can use either the ResponseStream or the ResponseWriter, + * but not both.

    + * + * @return ResponseWriter instance. + * + * @throws IllegalStateException if this method is called after + * this instance has been released + */ + public abstract ResponseWriter getResponseWriter(); + + /** + *

    Set the {@link ResponseWriter} to which components should + * direct their character-based output. + * + * @param responseWriter The new ResponseWriter for this response + * + * @throws IllegalStateException if this method is called after + * this instance has been released + * @throws NullPointerException if responseWriter + * is null + */ + public abstract void setResponseWriter(ResponseWriter responseWriter); + + /** + *

    Return the {@link FacesContext} + * instance for the request that is being processed by the current + * thread. If called during application initialization or shutdown, + * any method documented as "valid to call this method during + * application startup or shutdown" must be supported during + * application startup or shutdown time. The result of calling a + * method during application startup or shutdown time that does not + * have this designation is undefined.

    + * + * @return the instance of FacesContext. + */ + public static FacesContext getCurrentInstance() { + return null; + } +} diff --git a/java/ql/test/stubs/javax-faces-2.3/javax/faces/context/ResponseStream.java b/java/ql/test/stubs/javax-faces-2.3/javax/faces/context/ResponseStream.java new file mode 100644 index 00000000000..7a3b63024ca --- /dev/null +++ b/java/ql/test/stubs/javax-faces-2.3/javax/faces/context/ResponseStream.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package javax.faces.context; + + +import java.io.OutputStream; + + +/** + *

    ResponseStream is an interface describing an adapter + * to an underlying output mechanism for binary output.

    + */ + +public abstract class ResponseStream extends OutputStream { +} diff --git a/java/ql/test/stubs/javax-faces-2.3/javax/faces/context/ResponseWriter.java b/java/ql/test/stubs/javax-faces-2.3/javax/faces/context/ResponseWriter.java new file mode 100644 index 00000000000..4ad2f53f843 --- /dev/null +++ b/java/ql/test/stubs/javax-faces-2.3/javax/faces/context/ResponseWriter.java @@ -0,0 +1,372 @@ +/* + * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package javax.faces.context; + + +import javax.faces.component.UIComponent; +import java.io.IOException; +import java.io.Writer; + + +/** + *

    ResponseWriter + * is an abstract class describing an adapter to an underlying output + * mechanism for character-based output. In addition to the low-level + * write() methods inherited from + * java.io.Writer, this class provides utility methods that + * are useful in producing elements and attributes for markup languages + * like HTML and XML.

    + */ + +public abstract class ResponseWriter extends Writer { + + + /** + *

    Return the content type (such as "text/html") for this {@link + * ResponseWriter}. Note: this must not include the "charset=" + * suffix.

    + * + * @return the content type + */ + public abstract String getContentType(); + + + /** + *

    Return the character encoding (such as "ISO-8859-1") for this + * {@link ResponseWriter}. Please see the + * IANA for a list of character encodings.

    + * + * @return the character encoding + */ + public abstract String getCharacterEncoding(); + + + /** + *

    Flush any ouput buffered by the output method to the + * underlying Writer or OutputStream. This method + * will not flush the underlying Writer or OutputStream; it + * simply clears any values buffered by this {@link ResponseWriter}.

    + */ + @Override + public abstract void flush() throws IOException; + + + /** + *

    Write whatever text should begin a response.

    + * + * @throws IOException if an input/output error occurs + */ + public abstract void startDocument() throws IOException; + + + /** + *

    Write whatever text should end a response. If there is an open + * element that has been created by a call to startElement(), + * that element will be closed first.

    + * + * @throws IOException if an input/output error occurs + */ + public abstract void endDocument() throws IOException; + + + /** + *

    Write the start of an element, + up to and including the + * element name. Once this method has been called, clients can + * call the writeAttribute() or + * writeURIAttribute() methods to add attributes and + * corresponding values. The starting element will be closed + * (that is, the trailing '>' character added) + * on any subsequent call to startElement(), + * writeComment(), + * writeText(), endElement(), + * endDocument(), close(), + * flush(), or write().

    + * + *
    + * + *

    If the argument component's pass through attributes + * includes an attribute of the name given by the value of the symbolic + * constant {@link javax.faces.render.Renderer#PASSTHROUGH_RENDERER_LOCALNAME_KEY}, + * use that as the element name, instead of the value passed as the first + * parameter to this method. Care must be taken so that this value + * is not also rendered when any other pass through attributes on this component + * are rendered.

    + * + *
    + * + * @param name Name of the element to be started + + * @param component The {@link UIComponent} (if any) to which this + * element corresponds. This component is + * inspected for its pass through attributes as + * described in the standard HTML_BASIC {@code + * RenderKit} specification. + + * @throws IOException if an input/output error occurs + * @throws NullPointerException if name + * is null + */ + public abstract void startElement(String name, UIComponent component) + throws IOException; + + + /** + *

    Write the end of an element, + * after closing any open element + * created by a call to startElement(). Elements must be + * closed in the inverse order from which they were opened; it is an + * error to do otherwise.

    + * + *
    + * + *

    If the argument component's pass through attributes + * includes an attribute of the name given by the value of the symbolic + * constant {@link javax.faces.render.Renderer#PASSTHROUGH_RENDERER_LOCALNAME_KEY}, + * use that as the element name, instead of the value passed as the first + * parameter to this method.

    + * + *
    + * + * @param name Name of the element to be ended + * @throws IOException if an input/output error occurs + * @throws NullPointerException if name + * is null + */ + public abstract void endElement(String name) throws IOException; + + + /** + *

    Write an attribute name and corresponding value, after converting + * that text to a String (if necessary), and after performing any escaping + * appropriate for the markup language being rendered. + * This method may only be called after a call to + * startElement(), and before the opened element has been + * closed.

    + * + * @param name Attribute name to be added + * @param value Attribute value to be added + * @param property Name of the property or attribute (if any) of the + * {@link UIComponent} associated with the containing element, + * to which this generated attribute corresponds + * @throws IllegalStateException if this method is called when there + * is no currently open element + * @throws IOException if an input/output error occurs + * @throws NullPointerException if name is + * null + */ + public abstract void writeAttribute(String name, Object value, + String property) + throws IOException; + + + /** + *

    Write a URI + * attribute name and corresponding value, after converting that + * text to a String (if necessary), and after performing any + * encoding or escaping + * appropriate to the markup language being rendered. When rendering in a WWW environment, + * the escaping conventions established in the W3C URI spec document + * <http://www.w3.org/Addressing/URL/uri-spec.html> + * must be followed. In particular, spaces ' ' must be encoded as + * %20 and not the plus character '+'. This method may only + * be called after a call to startElement(), and before + * the opened element has been closed.

    + * + * @param name Attribute name to be added + * @param value Attribute value to be added + * @param property Name of the property or attribute (if any) of the + * {@link UIComponent} associated with the containing element, + * to which this generated attribute corresponds + * @throws IllegalStateException if this method is called when there + * is no currently open element + * @throws IOException if an input/output error occurs + * @throws NullPointerException if name is + * null + */ + public abstract void writeURIAttribute(String name, Object value, + String property) + throws IOException; + + /** + *

    Open an XML CDATA + * block. Note that XML does not allow nested CDATA + * blocks, though this method does not enforce that constraint. The + * default implementation of this method takes no action when + * invoked.

    + * @throws IOException if input/output error occures + */ + public void startCDATA() throws IOException { + + } + + + /** + + *

    Close an XML CDATA + * block. The default implementation of this method takes no action + * when invoked.

    + + * @throws IOException if input/output error occures + */ + public void endCDATA() throws IOException { + throw new UnsupportedOperationException(); + } + + + /** + *

    Write a comment containing the specified text, after converting + * that text to a String (if necessary), and after performing any escaping + * appropriate for the markup language being rendered. If there is + * an open element that has been created by a call to + * startElement(), that element will be closed first.

    + * + * @param comment Text content of the comment + * @throws IOException if an input/output error occurs + * @throws NullPointerException if comment + * is null + */ + public abstract void writeComment(Object comment) throws IOException; + + + /** + *

    Write a string containing the markup specific + * preamble. + * No escaping is performed. The default + * implementation simply calls through to {@link #write(java.lang.String)} .

    + * + *
    + * + *

    The implementation makes no checks if this is the correct place + * in the response to have a preamble, nor does it prevent the preamble + * from being written more than once.

    + * + *
    + * + * @since 2.2 + * @param preamble Text content of the preamble + * @throws IOException if an input/output error occurs + */ + public void writePreamble(String preamble) throws IOException { + write(preamble); + } + + /** + *

    Write a string containing the markup specific + * doctype. + * No escaping is performed. The default + * implementation simply calls through to {@link #write(java.lang.String)} .

    + * + *
    + * + *

    The implementation makes no checks if this is the correct place + * in the response to have a doctype, nor does it prevent the doctype + * from being written more than once.

    + * + *
    + * + * @since 2.2 + * @param doctype Text content of the doctype + * @throws IOException if an input/output error occurs + */ + public void writeDoctype(String doctype) throws IOException { + write(doctype); + } + + + /** + *

    Write an object, after converting it to a String (if necessary), + * and after performing any escaping appropriate for the markup language + * being rendered. If there is an open element that has been created + * by a call to startElement(), that element will be closed + * first.

    + * + * @param text Text to be written + * @param property Name of the property or attribute (if any) of the + * {@link UIComponent} associated with the containing element, + * to which this generated text corresponds + * @throws IOException if an input/output error occurs + * @throws NullPointerException if text + * is null + */ + public abstract void writeText(Object text, String property) + throws IOException; + + /** + *

    Write an object, after converting it to a String (if + * necessary), and after performing any escaping appropriate for the + * markup language being rendered. This method is equivalent to + * {@link #writeText(java.lang.Object,java.lang.String)} but adds a + * component property to allow custom + * ResponseWriter implementations to associate a + * component with an arbitrary portion of text.

    + * + *

    The default implementation simply ignores the + * component argument and calls through to {@link + * #writeText(java.lang.Object,java.lang.String)}

    + * + * @param text Text to be written + * @param component The {@link UIComponent} (if any) to which + * this element corresponds + * @param property Name of the property or attribute (if any) of the + * {@link UIComponent} associated with the containing element, + * to which this generated text corresponds + * @throws IOException if an input/output error occurs + * @throws NullPointerException if text + * is null + * @since 1.2 + */ + public void writeText(Object text, UIComponent component, String property) + throws IOException { + writeText(text, property); + } + + + /** + *

    Write text from a character array, after any performing any + * escaping appropriate for the markup language being rendered. + * If there is an open element that has been created by a call to + * startElement(), that element will be closed first.

    + * + * @param text Text to be written + * @param off Starting offset (zero-relative) + * @param len Number of characters to be written + * @throws IndexOutOfBoundsException if the calculated starting or + * ending position is outside the bounds of the character array + * @throws IOException if an input/output error occurs + * @throws NullPointerException if text + * is null + */ + public abstract void writeText(char text[], int off, int len) + throws IOException; + + + /** + *

    Create and return a new instance of this {@link ResponseWriter}, + * using the specified Writer as the output destination.

    + * + * @param writer The Writer that is the output destination + * + * @return the new ResponseWriter + */ + public abstract ResponseWriter cloneWithWriter(Writer writer); +} diff --git a/java/ql/test/stubs/javax-faces-2.3/javax/faces/render/FacesRenderer.java b/java/ql/test/stubs/javax-faces-2.3/javax/faces/render/FacesRenderer.java new file mode 100644 index 00000000000..872b71d92d0 --- /dev/null +++ b/java/ql/test/stubs/javax-faces-2.3/javax/faces/render/FacesRenderer.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package javax.faces.render; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.Inherited; + +/** + *

    The presence of this annotation on a + * class automatically registers the class with the runtime as a {@link + * Renderer}. The value of the {@link #renderKitId} attribute is taken + * to be the render-kit-id to which an instance of this + * Renderer is to be added. There must be a public + * zero-argument constructor on any class where this annotation appears. + * The implementation must indicate a fatal error if such a constructor + * does not exist and the application must not be placed in service. + * Within that {@link RenderKit}, The value of the {@link #rendererType} + * attribute is taken to be the renderer-type, and the value of + * the {@link #componentFamily} attribute is to be taken as the + * component-family. The implementation must guarantee that + * for each class annotated with FacesRenderer, found with + * the algorithm in section JSF.11.5, + * the following actions are taken.

    + + *
    + + *
      + + *
    • Obtain a reference to the {@link RenderKitFactory} for + * this application.

    • + +
    • See if a RenderKit exists for + render-kit-id. If so, let that instance be + renderKit for discussion. If not, the implementation + must indicate a fatal error if such a RenderKit + does not exist and the application must not be placed in + service.

    • + +
    • Create an instance of this class using the public + zero-argument constructor.

    • + +
    • Call {@link RenderKit#addRenderer} on + renderKit, passing component-family as the + first argument, renderer-type as the second, and the + newly instantiated RenderKit instance as the + third argument.

    • + + *
    + + + *
    + + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Inherited +public @interface FacesRenderer { + + + /** + *

    The value of this annotation + * attribute is taken to be the render-kit-id in which an + * instance of this class of Renderer must be + * installed.

    + * + * @return the render-kit-id + */ + + String renderKitId() default ""; + + + /** + *

    The value of this annotation + * attribute is taken to be the renderer-type which, in + * combination with {@link #componentFamily} can be used to obtain a + * reference to an instance of this {@link Renderer} by calling + * {@link javax.faces.render.RenderKit#getRenderer(java.lang.String, + * java.lang.String)}.

    + * + * @return the renderer-type + */ + + String rendererType(); + + + /** + *

    The value of this annotation + * attribute is taken to be the component-family which, in + * combination with {@link #rendererType} can be used to obtain a + * reference to an instance of this {@link Renderer} by calling + * {@link javax.faces.render.RenderKit#getRenderer(java.lang.String, + * java.lang.String)}.

    + * + * @return the component-family + */ + + String componentFamily(); + +} diff --git a/java/ql/test/stubs/javax-faces-2.3/javax/faces/render/Renderer.java b/java/ql/test/stubs/javax-faces-2.3/javax/faces/render/Renderer.java new file mode 100644 index 00000000000..a5fc4b47799 --- /dev/null +++ b/java/ql/test/stubs/javax-faces-2.3/javax/faces/render/Renderer.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package javax.faces.render; + + +import java.io.IOException; +import java.util.Iterator; +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; + + +/** + *

    A Renderer converts + * the internal representation of {@link UIComponent}s into the output + * stream (or writer) associated with the response we are creating for a + * particular request. Each Renderer knows how to render + * one or more {@link UIComponent} types (or classes), and advertises a + * set of render-dependent attributes that it recognizes for each + * supported {@link UIComponent}.

    + * + *

    Families of {@link Renderer}s are packaged as a {@link RenderKit}, + * and together support the rendering of all of the {@link UIComponent}s + * in a view associated with a {@link FacesContext}. Within the set of + * {@link Renderer}s for a particular {@link RenderKit}, each must be + * uniquely identified by the rendererType property.

    + * + *

    Individual {@link Renderer} instances will be instantiated as requested + * during the rendering process, and will remain in existence for the + * remainder of the lifetime of a web application. Because each instance + * may be invoked from more than one request processing thread simultaneously, + * they MUST be programmed in a thread-safe manner.

    + * + *
    + + *

    If the {@link javax.faces.event.ListenerFor} annotation is + * attached to the class definition of a Renderer, that + * class must also implement {@link + * javax.faces.event.ComponentSystemEventListener}, and the action + * pertaining to the processing of ResourceDependency on a + * Renderer described in {@link + * javax.faces.event.ListenerFor} must be taken.

    + + *

    If the {@link javax.faces.application.ResourceDependency} + * annotation is attached to the class definition of a + * Renderer, the action pertaining to the processing of + * ResourceDependency on a Renderer described + * in {@link UIComponent#getChildren} must be taken.

    + + *
    + */ + +public abstract class Renderer { + + /** + *

    Decode any new state of the specified {@link UIComponent} + * from the request contained in the specified {@link FacesContext}, + * and store that state on the {@link UIComponent}.

    + * + *

    During decoding, events may be enqueued for later processing + * (by event listeners that have registered an interest), by calling + * queueEvent() on the associated {@link UIComponent}. + *

    + * + * @param context {@link FacesContext} for the request we are processing + * @param component {@link UIComponent} to be decoded. + * + * @throws NullPointerException if context + * or component is null + */ + public void decode(FacesContext context, UIComponent component) { + } + + + /** + *

    Render the beginning specified {@link UIComponent} to the + * output stream or writer associated with the response we are creating. + * If the conversion attempted in a previous call to + * getConvertedValue() for this component failed, the state + * information saved during execution + * of decode() should be used to reproduce the incorrect + * input.

    + * + * @param context {@link FacesContext} for the request we are processing + * @param component {@link UIComponent} to be rendered + * + * @throws IOException if an input/output error occurs while rendering + * @throws NullPointerException if context + * or component is null + */ + public void encodeBegin(FacesContext context, + UIComponent component) + throws IOException { + } + + + /** + *

    Render the child components of this {@link UIComponent}, following + * the rules described for encodeBegin() to acquire the + * appropriate value to be rendered. This method will only be called + * if the rendersChildren property of this component + * is true.

    + * + * @param context {@link FacesContext} for the response we are creating + * @param component {@link UIComponent} whose children are to be rendered + * + * @throws IOException if an input/output error occurs while rendering + * @throws NullPointerException if context + * or component is null + */ + public void encodeChildren(FacesContext context, UIComponent component) + throws IOException { + } + + + /** + *

    Render the ending of the current state of the specified + * {@link UIComponent}, following the rules described for + * encodeBegin() to acquire the appropriate value + * to be rendered.

    + * + * @param context {@link FacesContext} for the response we are creating + * @param component {@link UIComponent} to be rendered + * + * @throws IOException if an input/output error occurs while rendering + * @throws NullPointerException if context + * or component is null + */ + public void encodeEnd(FacesContext context, + UIComponent component) + throws IOException { + } + + /** + *

    Convert the component generated client id to a form suitable + * for transmission to the client.

    + * + *

    The default implementation returns the argument + * clientId unchanged.

    + * + * @param context {@link FacesContext} for the current request + * @param clientId the client identifier to be converted to client a + * specific format. + * + * @throws NullPointerException if context + * or clientId is null + * + * @return the converted {@code clientId} + */ + public String convertClientId(FacesContext context, String clientId) { + return null; + } +} diff --git a/java/ql/test/stubs/javax-ws-rs-api-2.1.1/javax/ws/rs/container/ContainerRequestContext.java b/java/ql/test/stubs/javax-ws-rs-api-2.1.1/javax/ws/rs/container/ContainerRequestContext.java new file mode 100644 index 00000000000..049e42396dd --- /dev/null +++ b/java/ql/test/stubs/javax-ws-rs-api-2.1.1/javax/ws/rs/container/ContainerRequestContext.java @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package javax.ws.rs.container; + +import java.io.InputStream; +import java.net.URI; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import javax.ws.rs.core.Cookie; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Request; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.SecurityContext; +import javax.ws.rs.core.UriInfo; + +/** + * Container request filter context. + * + * A mutable class that provides request-specific information for the filter, such as request URI, message headers, + * message entity or request-scoped properties. The exposed setters allow modification of the exposed request-specific + * information. + * + * @author Marek Potociar + * @since 2.0 + */ +public interface ContainerRequestContext { + + /** + * Returns the property with the given name registered in the current request/response exchange context, or {@code null} + * if there is no property by that name. + *

    + * A property allows a JAX-RS filters and interceptors to exchange additional custom information not already provided by + * this interface. + *

    + *

    + * A list of supported properties can be retrieved using {@link #getPropertyNames()}. Custom property names should + * follow the same convention as package names. + *

    + *

    + * In a Servlet container, the properties are synchronized with the {@code ServletRequest} and expose all the attributes + * available in the {@code ServletRequest}. Any modifications of the properties are also reflected in the set of + * properties of the associated {@code ServletRequest}. + *

    + * + * @param name a {@code String} specifying the name of the property. + * @return an {@code Object} containing the value of the property, or {@code null} if no property exists matching the + * given name. + * @see #getPropertyNames() + */ + public Object getProperty(String name); + + /** + * Returns {@code true} if the property with the given name is registered in the current request/response exchange + * context, or {@code false} if there is no property by that name. + *

    + * Use the {@link #getProperty} method with a property name to get the value of a property. + *

    + * + * @param name a {@code String} specifying the name of the property. + * @return {@code true} if this property is registered in the context, or {@code false} if no property exists matching + * the given name. + * @see #getPropertyNames() + */ + public default boolean hasProperty(String name) { + return getProperty(name) != null; + } + + /** + * Returns an immutable {@link java.util.Collection collection} containing the property names available within the + * context of the current request/response exchange context. + *

    + * Use the {@link #getProperty} method with a property name to get the value of a property. + *

    + *

    + * In a Servlet container, the properties are synchronized with the {@code ServletRequest} and expose all the attributes + * available in the {@code ServletRequest}. Any modifications of the properties are also reflected in the set of + * properties of the associated {@code ServletRequest}. + *

    + * + * @return an immutable {@link java.util.Collection collection} of property names. + * @see #getProperty + */ + public Collection getPropertyNames(); + + /** + * Binds an object to a given property name in the current request/response exchange context. If the name specified is + * already used for a property, this method will replace the value of the property with the new value. + *

    + * A property allows a JAX-RS filters and interceptors to exchange additional custom information not already provided by + * this interface. + *

    + *

    + * A list of supported properties can be retrieved using {@link #getPropertyNames()}. Custom property names should + * follow the same convention as package names. + *

    + *

    + * If a {@code null} value is passed, the effect is the same as calling the {@link #removeProperty(String)} method. + *

    + *

    + * In a Servlet container, the properties are synchronized with the {@code ServletRequest} and expose all the attributes + * available in the {@code ServletRequest}. Any modifications of the properties are also reflected in the set of + * properties of the associated {@code ServletRequest}. + *

    + * + * @param name a {@code String} specifying the name of the property. + * @param object an {@code Object} representing the property to be bound. + */ + public void setProperty(String name, Object object); + + /** + * Removes a property with the given name from the current request/response exchange context. After removal, subsequent + * calls to {@link #getProperty} to retrieve the property value will return {@code null}. + *

    + * In a Servlet container, the properties are synchronized with the {@code ServletRequest} and expose all the attributes + * available in the {@code ServletRequest}. Any modifications of the properties are also reflected in the set of + * properties of the associated {@code ServletRequest}. + *

    + * + * @param name a {@code String} specifying the name of the property to be removed. + */ + public void removeProperty(String name); + + /** + * Get request URI information. + * + * The returned object contains "live" view of the request URI information in a sense that any changes made to the + * request URI using one of the {@code setRequestUri(...)} methods will be reflected in the previously returned + * {@link UriInfo} instance. + * + * @return request URI information. + */ + public UriInfo getUriInfo(); + + /** + * Set a new request URI using the current base URI of the application to resolve the application-specific request URI + * part. + *

    + * Note that the method is usable only in pre-matching filters, prior to the resource matching occurs. Trying to invoke + * the method in a filter bound to a resource method results in an {@link IllegalStateException} being thrown. + *

    + * + * @param requestUri new URI of the request. + * @throws IllegalStateException in case the method is not invoked from a {@link PreMatching pre-matching} request + * filter. + * @see #setRequestUri(java.net.URI, java.net.URI) + */ + public void setRequestUri(URI requestUri); + + /** + * Set a new request URI using a new base URI to resolve the application-specific request URI part. + *

    + * Note that the method is usable only in pre-matching filters, prior to the resource matching occurs. Trying to invoke + * the method in a filter bound to a resource method results in an {@link IllegalStateException} being thrown. + *

    + * + * @param baseUri base URI that will be used to resolve the application-specific part of the request URI. + * @param requestUri new URI of the request. + * @throws IllegalStateException in case the method is not invoked from a {@link PreMatching pre-matching} request + * filter. + * @see #setRequestUri(java.net.URI) + */ + public void setRequestUri(URI baseUri, URI requestUri); + + /** + * Get the injectable request information. + * + * @return injectable request information. + */ + public Request getRequest(); + + /** + * Get the request method. + * + * @return the request method. + * @see javax.ws.rs.HttpMethod + */ + public String getMethod(); + + /** + * Set the request method. + *

    + * Note that the method is usable only in pre-matching filters, prior to the resource matching occurs. Trying to invoke + * the method in a filter bound to a resource method results in an {@link IllegalStateException} being thrown. + *

    + * + * @param method new request method. + * @throws IllegalStateException in case the method is not invoked from a {@link PreMatching pre-matching} request + * filter. + * @see javax.ws.rs.HttpMethod + */ + public void setMethod(String method); + + /** + * Get the mutable request headers multivalued map. + * + * @return mutable multivalued map of request headers. + * @see #getHeaderString(String) + */ + public MultivaluedMap getHeaders(); + + /** + * Get a message header as a single string value. + * + * @param name the message header. + * @return the message header value. If the message header is not present then {@code null} is returned. If the message + * header is present but has no value then the empty string is returned. If the message header is present more than once + * then the values of joined together and separated by a ',' character. + * @see #getHeaders() + */ + public String getHeaderString(String name); + + /** + * Get message date. + * + * @return the message date, otherwise {@code null} if not present. + */ + public Date getDate(); + + /** + * Get the language of the entity. + * + * @return the language of the entity or {@code null} if not specified + */ + public Locale getLanguage(); + + /** + * Get Content-Length value. + * + * @return Content-Length as integer if present and valid number. In other cases returns {@code -1}. + */ + public int getLength(); + + /** + * Get the media type of the entity. + * + * @return the media type or {@code null} if not specified (e.g. there's no request entity). + */ + public MediaType getMediaType(); + + /** + * Get a list of media types that are acceptable for the response. + * + * @return a read-only list of requested response media types sorted according to their q-value, with highest preference + * first. + */ + public List getAcceptableMediaTypes(); + + /** + * Get a list of languages that are acceptable for the response. + * + * @return a read-only list of acceptable languages sorted according to their q-value, with highest preference first. + */ + public List getAcceptableLanguages(); + + /** + * Get any cookies that accompanied the request. + * + * @return a read-only map of cookie name (String) to {@link Cookie}. + */ + public Map getCookies(); + + /** + * Check if there is a non-empty entity input stream available in the request message. + * + * The method returns {@code true} if the entity is present, returns {@code false} otherwise. + * + * @return {@code true} if there is an entity present in the message, {@code false} otherwise. + */ + public boolean hasEntity(); + + /** + * Get the entity input stream. The JAX-RS runtime is responsible for closing the input stream. + * + * @return entity input stream. + */ + public InputStream getEntityStream(); + + /** + * Set a new entity input stream. The JAX-RS runtime is responsible for closing the input stream. + * + * @param input new entity input stream. + * @throws IllegalStateException in case the method is invoked from a response filter. + */ + public void setEntityStream(InputStream input); + + /** + * Get the injectable security context information for the current request. + * + * The {@link SecurityContext#getUserPrincipal()} must return {@code null} if the current request has not been + * authenticated. + * + * @return injectable request security context information. + */ + public SecurityContext getSecurityContext(); + + /** + * Set a new injectable security context information for the current request. + * + * The {@link SecurityContext#getUserPrincipal()} must return {@code null} if the current request has not been + * authenticated. + * + * @param context new injectable request security context information. + * @throws IllegalStateException in case the method is invoked from a response filter. + */ + public void setSecurityContext(SecurityContext context); + + /** + * Abort the filter chain with a response. + * + * This method breaks the filter chain processing and returns the provided response back to the client. The provided + * response goes through the chain of applicable response filters. + * + * @param response response to be sent back to the client. + * @throws IllegalStateException in case the method is invoked from a response filter. + */ + public void abortWith(Response response); +} diff --git a/java/ql/test/stubs/javax-ws-rs-api-2.1.1/javax/ws/rs/core/Request.java b/java/ql/test/stubs/javax-ws-rs-api-2.1.1/javax/ws/rs/core/Request.java new file mode 100644 index 00000000000..a452c4f4a1e --- /dev/null +++ b/java/ql/test/stubs/javax-ws-rs-api-2.1.1/javax/ws/rs/core/Request.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2010, 2019 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package javax.ws.rs.core; + +import java.util.Date; +import java.util.List; + +import javax.ws.rs.core.Response.ResponseBuilder; + +/** + * An injectable helper for request processing, all methods throw an {@link IllegalStateException} if called outside the + * scope of a request (e.g. from a provider constructor). + * + * Precondition processing (see the {@code evaluatePreconditions} methods) can result in either a {@code null} return + * value to indicate that preconditions have been met and that the request should continue, or a non-{@code null} return + * value to indicate that preconditions were not met. In the event that preconditions were not met, the returned + * {@code ResponseBuilder} instance will have an appropriate status and will also include a {@code Vary} header if the + * {@link #selectVariant(List)} method was called prior to to calling {@code evaluatePreconditions}. It is the + * responsibility of the caller to check the status and add additional metadata if required. E.g., see + * HTTP/1.1, section 10.3.5 for details + * of the headers that are expected to accompany a {@code 304 Not Modified} response. + * + * @author Paul Sandoz + * @author Marc Hadley + * @author Marek Potociar + * @since 1.0 + */ +public interface Request { + + /** + * Get the request method, e.g. GET, POST, etc. + * + * @return the request method. + * @see javax.ws.rs.HttpMethod + */ + public String getMethod(); + + /** + * Select the representation variant that best matches the request. Returns {@code null} in case there is no matching + * variant in the list. + *

    + * More explicit variants are chosen ahead of less explicit ones. A vary header is computed from the supplied list and + * automatically added to the response. + *

    + * + * @param variants a list of Variant that describe all of the available representation variants. + * @return the variant that best matches the request or {@code null} if there's no match. + * @throws java.lang.IllegalArgumentException if variants is empty or {@code null}. + * @throws java.lang.IllegalStateException if called outside the scope of a request. + * @see Variant.VariantListBuilder + */ + public Variant selectVariant(List variants); + + /** + * Evaluate request preconditions based on the passed in value. + * + * @param eTag an ETag for the current state of the resource + * @return {@code null} if the preconditions are met or a {@code ResponseBuilder} set with the appropriate status if the + * preconditions are not met. A returned {@code ResponseBuilder} will include an ETag header set with the value of eTag, + * provided none of the precondition evaluation has failed, in which case the ETag header would not be included and the + * status code of the returned {@code ResponseBuilder} would be set to {@link Response.Status#PRECONDITION_FAILED}. + * @throws java.lang.IllegalArgumentException if eTag is {@code null}. + * @throws java.lang.IllegalStateException if called outside the scope of a request. + */ + public ResponseBuilder evaluatePreconditions(EntityTag eTag); + + /** + * Evaluate request preconditions based on the passed in value. + * + * @param lastModified a date that specifies the modification date of the resource + * @return {@code null} if the preconditions are met or a {@code ResponseBuilder} set with the appropriate status if the + * preconditions are not met. + * @throws java.lang.IllegalArgumentException if lastModified is {@code null}. + * @throws java.lang.IllegalStateException if called outside the scope of a request. + */ + public ResponseBuilder evaluatePreconditions(Date lastModified); + + /** + * Evaluate request preconditions based on the passed in value. + * + * @param lastModified a date that specifies the modification date of the resource + * @param eTag an ETag for the current state of the resource + * @return {@code null} if the preconditions are met or a {@code ResponseBuilder} set with the appropriate status if the + * preconditions are not met. A returned {@code ResponseBuilder} will include an ETag header set with the value of eTag, + * provided none of the precondition evaluation has failed, in which case the ETag header would not be included and the + * status code of the returned {@code ResponseBuilder} would be set to {@link Response.Status#PRECONDITION_FAILED}. + * @throws java.lang.IllegalArgumentException if lastModified or eTag is {@code null}. + * @throws java.lang.IllegalStateException if called outside the scope of a request. + */ + public ResponseBuilder evaluatePreconditions(Date lastModified, EntityTag eTag); + + /** + * Evaluate request preconditions for a resource that does not currently exist. The primary use of this method is to + * support the If-Match: * and + * If-None-Match: * preconditions. + * + *

    + * Note that precondition If-None-Match: something will never be + * considered to have been met, and it is the application's responsibility to enforce any additional method-specific + * semantics. E.g. a {@code PUT} on a resource that does not exist might succeed whereas a {@code GET} on a resource + * that does not exist would likely result in a 404 response. It would be the responsibility of the application to + * generate the 404 response. + *

    + * + * @return {@code null} if the preconditions are met or a {@code ResponseBuilder} set with the appropriate status if the + * preconditions are not met. + * @throws IllegalStateException if called outside the scope of a request. + * @since 1.1 + */ + public ResponseBuilder evaluatePreconditions(); + +} diff --git a/java/ql/test/stubs/javax-ws-rs-api-2.1.1/javax/ws/rs/core/SecurityContext.java b/java/ql/test/stubs/javax-ws-rs-api-2.1.1/javax/ws/rs/core/SecurityContext.java new file mode 100644 index 00000000000..65b27763b2b --- /dev/null +++ b/java/ql/test/stubs/javax-ws-rs-api-2.1.1/javax/ws/rs/core/SecurityContext.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2010, 2019 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package javax.ws.rs.core; + +import java.security.Principal; + +/** + * An injectable interface that provides access to security related information. + * + * @author Paul Sandoz + * @author Marc Hadley + * @see Context + * @since 1.0 + */ +public interface SecurityContext { + + /** + * String identifier for Basic authentication. Value "BASIC" + */ + public static final String BASIC_AUTH = "BASIC"; + /** + * String identifier for Client Certificate authentication. Value "CLIENT_CERT" + */ + public static final String CLIENT_CERT_AUTH = "CLIENT_CERT"; + /** + * String identifier for Digest authentication. Value "DIGEST" + */ + public static final String DIGEST_AUTH = "DIGEST"; + /** + * String identifier for Form authentication. Value "FORM" + */ + public static final String FORM_AUTH = "FORM"; + + /** + * Returns a java.security.Principal object containing the name of the current authenticated user. If the + * user has not been authenticated, the method returns null. + * + * @return a java.security.Principal containing the name of the user making this request; null if the user + * has not been authenticated + * @throws java.lang.IllegalStateException if called outside the scope of a request + */ + public Principal getUserPrincipal(); + + /** + * Returns a boolean indicating whether the authenticated user is included in the specified logical "role". If the user + * has not been authenticated, the method returns false. + * + * @param role a String specifying the name of the role + * @return a boolean indicating whether the user making the request belongs to a given role; + * false if the user has not been authenticated + * @throws java.lang.IllegalStateException if called outside the scope of a request + */ + public boolean isUserInRole(String role); + + /** + * Returns a boolean indicating whether this request was made using a secure channel, such as HTTPS. + * + * @return true if the request was made using a secure channel, false otherwise + * @throws java.lang.IllegalStateException if called outside the scope of a request + */ + public boolean isSecure(); + + /** + * Returns the string value of the authentication scheme used to protect the resource. If the resource is not + * authenticated, null is returned. + * + * Values are the same as the CGI variable AUTH_TYPE + * + * @return one of the static members BASIC_AUTH, FORM_AUTH, CLIENT_CERT_AUTH, DIGEST_AUTH (suitable for == comparison) + * or the container-specific string indicating the authentication scheme, or null if the request was not authenticated. + * @throws java.lang.IllegalStateException if called outside the scope of a request + */ + public String getAuthenticationScheme(); +} \ No newline at end of file diff --git a/java/ql/test/stubs/javax-ws-rs-api-3.0.0/jakarta/ws/rs/container/ContainerRequestContext.java b/java/ql/test/stubs/javax-ws-rs-api-3.0.0/jakarta/ws/rs/container/ContainerRequestContext.java new file mode 100644 index 00000000000..b7e593e279c --- /dev/null +++ b/java/ql/test/stubs/javax-ws-rs-api-3.0.0/jakarta/ws/rs/container/ContainerRequestContext.java @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package jakarta.ws.rs.container; + +import java.io.InputStream; +import java.net.URI; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import jakarta.ws.rs.core.Cookie; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.MultivaluedMap; +import jakarta.ws.rs.core.Request; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.SecurityContext; +import jakarta.ws.rs.core.UriInfo; + +/** + * Container request filter context. + * + * A mutable class that provides request-specific information for the filter, such as request URI, message headers, + * message entity or request-scoped properties. The exposed setters allow modification of the exposed request-specific + * information. + * + * @author Marek Potociar + * @since 2.0 + */ +public interface ContainerRequestContext { + + /** + * Returns the property with the given name registered in the current request/response exchange context, or {@code null} + * if there is no property by that name. + *

    + * A property allows a JAX-RS filters and interceptors to exchange additional custom information not already provided by + * this interface. + *

    + *

    + * A list of supported properties can be retrieved using {@link #getPropertyNames()}. Custom property names should + * follow the same convention as package names. + *

    + *

    + * In a Servlet container, the properties are synchronized with the {@code ServletRequest} and expose all the attributes + * available in the {@code ServletRequest}. Any modifications of the properties are also reflected in the set of + * properties of the associated {@code ServletRequest}. + *

    + * + * @param name a {@code String} specifying the name of the property. + * @return an {@code Object} containing the value of the property, or {@code null} if no property exists matching the + * given name. + * @see #getPropertyNames() + */ + public Object getProperty(String name); + + /** + * Returns {@code true} if the property with the given name is registered in the current request/response exchange + * context, or {@code false} if there is no property by that name. + *

    + * Use the {@link #getProperty} method with a property name to get the value of a property. + *

    + * + * @param name a {@code String} specifying the name of the property. + * @return {@code true} if this property is registered in the context, or {@code false} if no property exists matching + * the given name. + * @see #getPropertyNames() + */ + public default boolean hasProperty(String name) { + return getProperty(name) != null; + } + + /** + * Returns an immutable {@link java.util.Collection collection} containing the property names available within the + * context of the current request/response exchange context. + *

    + * Use the {@link #getProperty} method with a property name to get the value of a property. + *

    + *

    + * In a Servlet container, the properties are synchronized with the {@code ServletRequest} and expose all the attributes + * available in the {@code ServletRequest}. Any modifications of the properties are also reflected in the set of + * properties of the associated {@code ServletRequest}. + *

    + * + * @return an immutable {@link java.util.Collection collection} of property names. + * @see #getProperty + */ + public Collection getPropertyNames(); + + /** + * Binds an object to a given property name in the current request/response exchange context. If the name specified is + * already used for a property, this method will replace the value of the property with the new value. + *

    + * A property allows a JAX-RS filters and interceptors to exchange additional custom information not already provided by + * this interface. + *

    + *

    + * A list of supported properties can be retrieved using {@link #getPropertyNames()}. Custom property names should + * follow the same convention as package names. + *

    + *

    + * If a {@code null} value is passed, the effect is the same as calling the {@link #removeProperty(String)} method. + *

    + *

    + * In a Servlet container, the properties are synchronized with the {@code ServletRequest} and expose all the attributes + * available in the {@code ServletRequest}. Any modifications of the properties are also reflected in the set of + * properties of the associated {@code ServletRequest}. + *

    + * + * @param name a {@code String} specifying the name of the property. + * @param object an {@code Object} representing the property to be bound. + */ + public void setProperty(String name, Object object); + + /** + * Removes a property with the given name from the current request/response exchange context. After removal, subsequent + * calls to {@link #getProperty} to retrieve the property value will return {@code null}. + *

    + * In a Servlet container, the properties are synchronized with the {@code ServletRequest} and expose all the attributes + * available in the {@code ServletRequest}. Any modifications of the properties are also reflected in the set of + * properties of the associated {@code ServletRequest}. + *

    + * + * @param name a {@code String} specifying the name of the property to be removed. + */ + public void removeProperty(String name); + + /** + * Get request URI information. + * + * The returned object contains "live" view of the request URI information in a sense that any changes made to the + * request URI using one of the {@code setRequestUri(...)} methods will be reflected in the previously returned + * {@link UriInfo} instance. + * + * @return request URI information. + */ + public UriInfo getUriInfo(); + + /** + * Set a new request URI using the current base URI of the application to resolve the application-specific request URI + * part. + *

    + * Note that the method is usable only in pre-matching filters, prior to the resource matching occurs. Trying to invoke + * the method in a filter bound to a resource method results in an {@link IllegalStateException} being thrown. + *

    + * + * @param requestUri new URI of the request. + * @throws IllegalStateException in case the method is not invoked from a {@link PreMatching pre-matching} request + * filter. + * @see #setRequestUri(java.net.URI, java.net.URI) + */ + public void setRequestUri(URI requestUri); + + /** + * Set a new request URI using a new base URI to resolve the application-specific request URI part. + *

    + * Note that the method is usable only in pre-matching filters, prior to the resource matching occurs. Trying to invoke + * the method in a filter bound to a resource method results in an {@link IllegalStateException} being thrown. + *

    + * + * @param baseUri base URI that will be used to resolve the application-specific part of the request URI. + * @param requestUri new URI of the request. + * @throws IllegalStateException in case the method is not invoked from a {@link PreMatching pre-matching} request + * filter. + * @see #setRequestUri(java.net.URI) + */ + public void setRequestUri(URI baseUri, URI requestUri); + + /** + * Get the injectable request information. + * + * @return injectable request information. + */ + public Request getRequest(); + + /** + * Get the request method. + * + * @return the request method. + * @see jakarta.ws.rs.HttpMethod + */ + public String getMethod(); + + /** + * Set the request method. + *

    + * Note that the method is usable only in pre-matching filters, prior to the resource matching occurs. Trying to invoke + * the method in a filter bound to a resource method results in an {@link IllegalStateException} being thrown. + *

    + * + * @param method new request method. + * @throws IllegalStateException in case the method is not invoked from a {@link PreMatching pre-matching} request + * filter. + * @see jakarta.ws.rs.HttpMethod + */ + public void setMethod(String method); + + /** + * Get the mutable request headers multivalued map. + * + * @return mutable multivalued map of request headers. + * @see #getHeaderString(String) + */ + public MultivaluedMap getHeaders(); + + /** + * Get a message header as a single string value. + * + * @param name the message header. + * @return the message header value. If the message header is not present then {@code null} is returned. If the message + * header is present but has no value then the empty string is returned. If the message header is present more than once + * then the values of joined together and separated by a ',' character. + * @see #getHeaders() + */ + public String getHeaderString(String name); + + /** + * Get message date. + * + * @return the message date, otherwise {@code null} if not present. + */ + public Date getDate(); + + /** + * Get the language of the entity. + * + * @return the language of the entity or {@code null} if not specified + */ + public Locale getLanguage(); + + /** + * Get Content-Length value. + * + * @return Content-Length as integer if present and valid number. In other cases returns {@code -1}. + */ + public int getLength(); + + /** + * Get the media type of the entity. + * + * @return the media type or {@code null} if not specified (e.g. there's no request entity). + */ + public MediaType getMediaType(); + + /** + * Get a list of media types that are acceptable for the response. + * + * @return a read-only list of requested response media types sorted according to their q-value, with highest preference + * first. + */ + public List getAcceptableMediaTypes(); + + /** + * Get a list of languages that are acceptable for the response. + * + * @return a read-only list of acceptable languages sorted according to their q-value, with highest preference first. + */ + public List getAcceptableLanguages(); + + /** + * Get any cookies that accompanied the request. + * + * @return a read-only map of cookie name (String) to {@link Cookie}. + */ + public Map getCookies(); + + /** + * Check if there is a non-empty entity input stream available in the request message. + * + * The method returns {@code true} if the entity is present, returns {@code false} otherwise. + * + * @return {@code true} if there is an entity present in the message, {@code false} otherwise. + */ + public boolean hasEntity(); + + /** + * Get the entity input stream. The JAX-RS runtime is responsible for closing the input stream. + * + * @return entity input stream. + */ + public InputStream getEntityStream(); + + /** + * Set a new entity input stream. The JAX-RS runtime is responsible for closing the input stream. + * + * @param input new entity input stream. + * @throws IllegalStateException in case the method is invoked from a response filter. + */ + public void setEntityStream(InputStream input); + + /** + * Get the injectable security context information for the current request. + * + * The {@link SecurityContext#getUserPrincipal()} must return {@code null} if the current request has not been + * authenticated. + * + * @return injectable request security context information. + */ + public SecurityContext getSecurityContext(); + + /** + * Set a new injectable security context information for the current request. + * + * The {@link SecurityContext#getUserPrincipal()} must return {@code null} if the current request has not been + * authenticated. + * + * @param context new injectable request security context information. + * @throws IllegalStateException in case the method is invoked from a response filter. + */ + public void setSecurityContext(SecurityContext context); + + /** + * Abort the filter chain with a response. + * + * This method breaks the filter chain processing and returns the provided response back to the client. The provided + * response goes through the chain of applicable response filters. + * + * @param response response to be sent back to the client. + * @throws IllegalStateException in case the method is invoked from a response filter. + */ + public void abortWith(Response response); +} diff --git a/java/ql/test/stubs/javax-ws-rs-api-3.0.0/jakarta/ws/rs/core/Request.java b/java/ql/test/stubs/javax-ws-rs-api-3.0.0/jakarta/ws/rs/core/Request.java new file mode 100644 index 00000000000..a9d06d6b5a3 --- /dev/null +++ b/java/ql/test/stubs/javax-ws-rs-api-3.0.0/jakarta/ws/rs/core/Request.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2010, 2019 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package jakarta.ws.rs.core; + +import java.util.Date; +import java.util.List; + +import jakarta.ws.rs.core.Response.ResponseBuilder; + +/** + * An injectable helper for request processing, all methods throw an {@link IllegalStateException} if called outside the + * scope of a request (e.g. from a provider constructor). + * + * Precondition processing (see the {@code evaluatePreconditions} methods) can result in either a {@code null} return + * value to indicate that preconditions have been met and that the request should continue, or a non-{@code null} return + * value to indicate that preconditions were not met. In the event that preconditions were not met, the returned + * {@code ResponseBuilder} instance will have an appropriate status and will also include a {@code Vary} header if the + * {@link #selectVariant(List)} method was called prior to to calling {@code evaluatePreconditions}. It is the + * responsibility of the caller to check the status and add additional metadata if required. E.g., see + * HTTP/1.1, section 10.3.5 for details + * of the headers that are expected to accompany a {@code 304 Not Modified} response. + * + * @author Paul Sandoz + * @author Marc Hadley + * @author Marek Potociar + * @since 1.0 + */ +public interface Request { + + /** + * Get the request method, e.g. GET, POST, etc. + * + * @return the request method. + * @see jakarta.ws.rs.HttpMethod + */ + public String getMethod(); + + /** + * Select the representation variant that best matches the request. Returns {@code null} in case there is no matching + * variant in the list. + *

    + * More explicit variants are chosen ahead of less explicit ones. A vary header is computed from the supplied list and + * automatically added to the response. + *

    + * + * @param variants a list of Variant that describe all of the available representation variants. + * @return the variant that best matches the request or {@code null} if there's no match. + * @throws java.lang.IllegalArgumentException if variants is empty or {@code null}. + * @throws java.lang.IllegalStateException if called outside the scope of a request. + * @see Variant.VariantListBuilder + */ + public Variant selectVariant(List variants); + + /** + * Evaluate request preconditions based on the passed in value. + * + * @param eTag an ETag for the current state of the resource + * @return {@code null} if the preconditions are met or a {@code ResponseBuilder} set with the appropriate status if the + * preconditions are not met. A returned {@code ResponseBuilder} will include an ETag header set with the value of eTag, + * provided none of the precondition evaluation has failed, in which case the ETag header would not be included and the + * status code of the returned {@code ResponseBuilder} would be set to {@link Response.Status#PRECONDITION_FAILED}. + * @throws java.lang.IllegalArgumentException if eTag is {@code null}. + * @throws java.lang.IllegalStateException if called outside the scope of a request. + */ + public ResponseBuilder evaluatePreconditions(EntityTag eTag); + + /** + * Evaluate request preconditions based on the passed in value. + * + * @param lastModified a date that specifies the modification date of the resource + * @return {@code null} if the preconditions are met or a {@code ResponseBuilder} set with the appropriate status if the + * preconditions are not met. + * @throws java.lang.IllegalArgumentException if lastModified is {@code null}. + * @throws java.lang.IllegalStateException if called outside the scope of a request. + */ + public ResponseBuilder evaluatePreconditions(Date lastModified); + + /** + * Evaluate request preconditions based on the passed in value. + * + * @param lastModified a date that specifies the modification date of the resource + * @param eTag an ETag for the current state of the resource + * @return {@code null} if the preconditions are met or a {@code ResponseBuilder} set with the appropriate status if the + * preconditions are not met. A returned {@code ResponseBuilder} will include an ETag header set with the value of eTag, + * provided none of the precondition evaluation has failed, in which case the ETag header would not be included and the + * status code of the returned {@code ResponseBuilder} would be set to {@link Response.Status#PRECONDITION_FAILED}. + * @throws java.lang.IllegalArgumentException if lastModified or eTag is {@code null}. + * @throws java.lang.IllegalStateException if called outside the scope of a request. + */ + public ResponseBuilder evaluatePreconditions(Date lastModified, EntityTag eTag); + + /** + * Evaluate request preconditions for a resource that does not currently exist. The primary use of this method is to + * support the If-Match: * and + * If-None-Match: * preconditions. + * + *

    + * Note that precondition If-None-Match: something will never be + * considered to have been met, and it is the application's responsibility to enforce any additional method-specific + * semantics. E.g. a {@code PUT} on a resource that does not exist might succeed whereas a {@code GET} on a resource + * that does not exist would likely result in a 404 response. It would be the responsibility of the application to + * generate the 404 response. + *

    + * + * @return {@code null} if the preconditions are met or a {@code ResponseBuilder} set with the appropriate status if the + * preconditions are not met. + * @throws IllegalStateException if called outside the scope of a request. + * @since 1.1 + */ + public ResponseBuilder evaluatePreconditions(); + +} diff --git a/java/ql/test/stubs/javax-ws-rs-api-3.0.0/jakarta/ws/rs/core/SecurityContext.java b/java/ql/test/stubs/javax-ws-rs-api-3.0.0/jakarta/ws/rs/core/SecurityContext.java new file mode 100644 index 00000000000..ee382639a07 --- /dev/null +++ b/java/ql/test/stubs/javax-ws-rs-api-3.0.0/jakarta/ws/rs/core/SecurityContext.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2010, 2019 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package jakarta.ws.rs.core; + +import java.security.Principal; + +/** + * An injectable interface that provides access to security related information. + * + * @author Paul Sandoz + * @author Marc Hadley + * @see Context + * @since 1.0 + */ +public interface SecurityContext { + + /** + * String identifier for Basic authentication. Value "BASIC" + */ + public static final String BASIC_AUTH = "BASIC"; + /** + * String identifier for Client Certificate authentication. Value "CLIENT_CERT" + */ + public static final String CLIENT_CERT_AUTH = "CLIENT_CERT"; + /** + * String identifier for Digest authentication. Value "DIGEST" + */ + public static final String DIGEST_AUTH = "DIGEST"; + /** + * String identifier for Form authentication. Value "FORM" + */ + public static final String FORM_AUTH = "FORM"; + + /** + * Returns a java.security.Principal object containing the name of the current authenticated user. If the + * user has not been authenticated, the method returns null. + * + * @return a java.security.Principal containing the name of the user making this request; null if the user + * has not been authenticated + * @throws java.lang.IllegalStateException if called outside the scope of a request + */ + public Principal getUserPrincipal(); + + /** + * Returns a boolean indicating whether the authenticated user is included in the specified logical "role". If the user + * has not been authenticated, the method returns false. + * + * @param role a String specifying the name of the role + * @return a boolean indicating whether the user making the request belongs to a given role; + * false if the user has not been authenticated + * @throws java.lang.IllegalStateException if called outside the scope of a request + */ + public boolean isUserInRole(String role); + + /** + * Returns a boolean indicating whether this request was made using a secure channel, such as HTTPS. + * + * @return true if the request was made using a secure channel, false otherwise + * @throws java.lang.IllegalStateException if called outside the scope of a request + */ + public boolean isSecure(); + + /** + * Returns the string value of the authentication scheme used to protect the resource. If the resource is not + * authenticated, null is returned. + * + * Values are the same as the CGI variable AUTH_TYPE + * + * @return one of the static members BASIC_AUTH, FORM_AUTH, CLIENT_CERT_AUTH, DIGEST_AUTH (suitable for == comparison) + * or the container-specific string indicating the authentication scheme, or null if the request was not authenticated. + * @throws java.lang.IllegalStateException if called outside the scope of a request + */ + public String getAuthenticationScheme(); +} \ No newline at end of file diff --git a/java/ql/test/stubs/rundeck-api-java-client-13.2/org/rundeck/api/parser/ParserHelper.java b/java/ql/test/stubs/rundeck-api-java-client-13.2/org/rundeck/api/parser/ParserHelper.java new file mode 100644 index 00000000000..34acd64f63e --- /dev/null +++ b/java/ql/test/stubs/rundeck-api-java-client-13.2/org/rundeck/api/parser/ParserHelper.java @@ -0,0 +1,13 @@ +package org.rundeck.api.parser; + +import java.io.InputStream; +import org.dom4j.Document; + +public class ParserHelper { + public ParserHelper() { + } + + public static Document loadDocument(InputStream inputStream) { + return null; + } +} diff --git a/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/codec/Base64.java b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/codec/Base64.java new file mode 100644 index 00000000000..d1599df6abe --- /dev/null +++ b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/codec/Base64.java @@ -0,0 +1,36 @@ +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by Fernflower decompiler) +// + +package org.apache.shiro.codec; + +public class Base64 { + static final int CHUNK_SIZE = 76; + static final byte[] CHUNK_SEPARATOR = "\r\n".getBytes(); + private static final int BASELENGTH = 255; + private static final int LOOKUPLENGTH = 64; + private static final int EIGHTBIT = 8; + private static final int SIXTEENBIT = 16; + private static final int TWENTYFOURBITGROUP = 24; + private static final int FOURBYTE = 4; + private static final int SIGN = -128; + private static final byte PAD = 61; + private static final byte[] base64Alphabet = new byte[255]; + private static final byte[] lookUpBase64Alphabet = new byte[64]; + + public Base64() { + } + + + public static byte[] decode(String base64Encoded) { + byte[] bytes = new byte[1024]; + return decode(bytes); + } + + public static byte[] decode(byte[] base64Data) { + return base64Data; + } + } + + diff --git a/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/AbstractSymmetricCipherService.java b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/AbstractSymmetricCipherService.java new file mode 100644 index 00000000000..70cce8e76c5 --- /dev/null +++ b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/AbstractSymmetricCipherService.java @@ -0,0 +1,28 @@ +package org.apache.shiro.crypto; + +import java.security.Key; +import java.security.NoSuchAlgorithmException; +import javax.crypto.KeyGenerator; + +public abstract class AbstractSymmetricCipherService extends JcaCipherService { + protected AbstractSymmetricCipherService(String algorithmName) { + super(algorithmName); + } + + public Key generateNewKey() { + return this.generateNewKey(this.getKeySize()); + } + + public Key generateNewKey(int keyBitSize) { + KeyGenerator kg; + try { + kg = KeyGenerator.getInstance(this.getAlgorithmName()); + } catch (NoSuchAlgorithmException var5) { + String msg = "Unable to acquire " + this.getAlgorithmName() + " algorithm. This is required to function."; + throw new IllegalStateException(msg, var5); + } + + kg.init(keyBitSize); + return kg.generateKey(); + } +} \ No newline at end of file diff --git a/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/AesCipherService.java b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/AesCipherService.java new file mode 100644 index 00000000000..c8a727d1400 --- /dev/null +++ b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/AesCipherService.java @@ -0,0 +1,9 @@ +package org.apache.shiro.crypto; + +public class AesCipherService extends DefaultBlockCipherService { + private static final String ALGORITHM_NAME = "AES"; + + public AesCipherService() { + super("AES"); + } +} \ No newline at end of file diff --git a/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/CipherService.java b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/CipherService.java new file mode 100644 index 00000000000..b5996d331c6 --- /dev/null +++ b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/CipherService.java @@ -0,0 +1,12 @@ + +package org.apache.shiro.crypto; + +import java.io.InputStream; +import java.io.OutputStream; + +public interface CipherService { + + void decrypt(InputStream var1, OutputStream var2, byte[] var3) throws Exception; + + void encrypt(InputStream var1, OutputStream var2, byte[] var3) throws Exception; +} diff --git a/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/DefaultBlockCipherService.java b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/DefaultBlockCipherService.java new file mode 100644 index 00000000000..e4aa1e8b482 --- /dev/null +++ b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/DefaultBlockCipherService.java @@ -0,0 +1,120 @@ +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by Fernflower decompiler) +// + +package org.apache.shiro.crypto; + +public class DefaultBlockCipherService extends AbstractSymmetricCipherService { + private static final int DEFAULT_BLOCK_SIZE = 0; + private static final String TRANSFORMATION_STRING_DELIMITER = "/"; + private static final int DEFAULT_STREAMING_BLOCK_SIZE = 8; + private String modeName; + private int blockSize; + private String paddingSchemeName; + private String streamingModeName; + private int streamingBlockSize; + private String streamingPaddingSchemeName; + private String transformationString; + private String streamingTransformationString; + + public DefaultBlockCipherService(String algorithmName) { + super(algorithmName); + this.modeName = OperationMode.CBC.name(); + this.paddingSchemeName = PaddingScheme.PKCS5.getTransformationName(); + this.blockSize = 0; + this.streamingModeName = OperationMode.CBC.name(); + this.streamingPaddingSchemeName = PaddingScheme.PKCS5.getTransformationName(); + this.streamingBlockSize = 8; + } + + public String getModeName() { + return null; + } + + public void setModeName(String modeName) { + } + + public void setMode(OperationMode mode) { + } + + public String getPaddingSchemeName() { + return null; + } + + public void setPaddingSchemeName(String paddingSchemeName) { + + } + + public void setPaddingScheme(PaddingScheme paddingScheme) { + + } + + public int getBlockSize() { + return 1; + } + + public void setBlockSize(int blockSize) { + } + + public String getStreamingModeName() { + return null; + } + + private boolean isModeStreamingCompatible(String modeName) { + return false; + } + + public void setStreamingModeName(String streamingModeName) { + + } + + public void setStreamingMode(OperationMode mode) { + + } + + public String getStreamingPaddingSchemeName() { + return null; + } + + public void setStreamingPaddingSchemeName(String streamingPaddingSchemeName) { + } + + public void setStreamingPaddingScheme(PaddingScheme scheme) { + } + + public int getStreamingBlockSize() { + return 1; + } + + public void setStreamingBlockSize(int streamingBlockSize) { + } + + protected String getTransformationString(boolean streaming) { + return null; + } + + private String buildTransformationString() { + return null; + } + + private String buildStreamingTransformationString() { + return null; + } + + private String buildTransformationString(String modeName, String paddingSchemeName, int blockSize) { + return null; + } + + private boolean isModeInitializationVectorCompatible(String modeName) { + return false; + } + + protected boolean isGenerateInitializationVectors(boolean streaming) { + return false; + } + + protected byte[] generateInitializationVector(boolean streaming) { + return null; + } +} diff --git a/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/JcaCipherService.java b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/JcaCipherService.java new file mode 100644 index 00000000000..8d1c628e4ff --- /dev/null +++ b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/JcaCipherService.java @@ -0,0 +1,113 @@ +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by Fernflower decompiler) +// + +package org.apache.shiro.crypto; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.Key; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +public abstract class JcaCipherService implements CipherService { + private static final int DEFAULT_KEY_SIZE = 128; + private static final int DEFAULT_STREAMING_BUFFER_SIZE = 512; + private static final int BITS_PER_BYTE = 8; + private static final String RANDOM_NUM_GENERATOR_ALGORITHM_NAME = "SHA1PRNG"; + private String algorithmName; + private int keySize; + private int streamingBufferSize; + private boolean generateInitializationVectors; + private int initializationVectorSize; + + + protected JcaCipherService(String algorithmName) { + this.algorithmName = algorithmName; + this.keySize = 128; + this.initializationVectorSize = 128; + this.streamingBufferSize = 512; + this.generateInitializationVectors = true; + } + + public String getAlgorithmName() { + return null; + } + + public int getKeySize() { + return 1; + } + + public void setKeySize(int keySize) { + } + + public boolean isGenerateInitializationVectors() { + return false; + } + + public void setGenerateInitializationVectors(boolean generateInitializationVectors) { + } + + public int getInitializationVectorSize() { + return 1; + } + + public void setInitializationVectorSize(int initializationVectorSize) throws IllegalArgumentException { + + } + + protected boolean isGenerateInitializationVectors(boolean streaming) { + return false; + } + + public int getStreamingBufferSize() { + return 1; + } + + public void setStreamingBufferSize(int streamingBufferSize) { + } + + protected String getTransformationString(boolean streaming) { + return null; + } + + protected byte[] generateInitializationVector(boolean streaming) { + return null; + } + + + + + private byte[] crypt(byte[] bytes, byte[] key, byte[] iv, int mode) throws IllegalArgumentException, Exception { + return null; + } + + public void encrypt(InputStream in, OutputStream out, byte[] key) throws Exception { + } + + private void encrypt(InputStream in, OutputStream out, byte[] key, byte[] iv, boolean prependIv) throws Exception { + } + + public void decrypt(InputStream in, OutputStream out, byte[] key) throws Exception { + } + + private void decrypt(InputStream in, OutputStream out, byte[] key, boolean ivPrepended) throws Exception { + } + + private void decrypt(InputStream in, OutputStream out, byte[] decryptionKey, byte[] iv) throws Exception { + + } + + private void crypt(InputStream in, OutputStream out, byte[] keyBytes, byte[] iv, int cryptMode) throws Exception { + + } + + +} diff --git a/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/OperationMode.java b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/OperationMode.java new file mode 100644 index 00000000000..d5eadd91170 --- /dev/null +++ b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/OperationMode.java @@ -0,0 +1,19 @@ + +package org.apache.shiro.crypto; + +public enum OperationMode { + CBC, + CCM, + CFB, + CTR, + EAX, + ECB, + GCM, + NONE, + OCB, + OFB, + PCBC; + + private OperationMode() { + } +} diff --git a/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/PaddingScheme.java b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/PaddingScheme.java new file mode 100644 index 00000000000..d09017041bc --- /dev/null +++ b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/crypto/PaddingScheme.java @@ -0,0 +1,25 @@ +package org.apache.shiro.crypto; + +public enum PaddingScheme { + NONE("NoPadding"), + ISO10126("ISO10126Padding"), + OAEP("OAEPPadding"), + OAEPWithMd5AndMgf1("OAEPWithMD5AndMGF1Padding"), + OAEPWithSha1AndMgf1("OAEPWithSHA-1AndMGF1Padding"), + OAEPWithSha256AndMgf1("OAEPWithSHA-256AndMGF1Padding"), + OAEPWithSha384AndMgf1("OAEPWithSHA-384AndMGF1Padding"), + OAEPWithSha512AndMgf1("OAEPWithSHA-512AndMGF1Padding"), + PKCS1("PKCS1Padding"), + PKCS5("PKCS5Padding"), + SSL3("SSL3Padding"); + + private final String transformationName; + + private PaddingScheme(String transformationName) { + this.transformationName = transformationName; + } + + public String getTransformationName() { + return this.transformationName; + } +} \ No newline at end of file diff --git a/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/mgt/AbstractRememberMeManager.java b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/mgt/AbstractRememberMeManager.java new file mode 100644 index 00000000000..e251ed8bc0c --- /dev/null +++ b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/mgt/AbstractRememberMeManager.java @@ -0,0 +1,34 @@ + +package org.apache.shiro.mgt; +import org.apache.shiro.crypto.AesCipherService; + +public abstract class AbstractRememberMeManager { + + private byte[] encryptionCipherKey; + private byte[] decryptionCipherKey; + private AesCipherService cipherService; + + public AbstractRememberMeManager() { + AesCipherService cipherService = new AesCipherService(); + this.cipherService = cipherService; + this.setCipherKey(cipherService.generateNewKey().getEncoded()); + } + + public void setEncryptionCipherKey(byte[] encryptionCipherKey) { + + this.encryptionCipherKey = encryptionCipherKey; + } + + + public void setDecryptionCipherKey(byte[] decryptionCipherKey) { + this.decryptionCipherKey = decryptionCipherKey; + } + + + public void setCipherKey(byte[] cipherKey) { + this.setEncryptionCipherKey(cipherKey); + this.setDecryptionCipherKey(cipherKey); + } + + +} diff --git a/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/web/mgt/CookieRememberMeManager.java b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/web/mgt/CookieRememberMeManager.java new file mode 100644 index 00000000000..39811aeca7a --- /dev/null +++ b/java/ql/test/stubs/shiro-core-1.4.0/org/apache/shiro/web/mgt/CookieRememberMeManager.java @@ -0,0 +1,30 @@ +package org.apache.shiro.web.mgt; + +import org.apache.shiro.mgt.AbstractRememberMeManager; +public class CookieRememberMeManager extends AbstractRememberMeManager { + + public CookieRememberMeManager() { + } + + + public void setCookie() { + } + + protected void rememberSerializedIdentity() { + } + + private boolean isIdentityRemoved() { + return false; + } + + protected byte[] getRememberedSerializedIdentity() { + return null; + } + + private String ensurePadding(String base64) { + return null; + } + + + +} diff --git a/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/Expression.java b/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/Expression.java index 2c3fc44075f..4556c65a518 100644 --- a/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/Expression.java +++ b/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/Expression.java @@ -1,14 +1,65 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + package org.springframework.expression; +import org.springframework.lang.Nullable; + public interface Expression { + String getExpressionString(); Object getValue() throws EvaluationException; + T getValue(@Nullable Class desiredResultType) throws EvaluationException; + + Object getValue(@Nullable Object rootObject) throws EvaluationException; + + T getValue(@Nullable Object rootObject, @Nullable Class desiredResultType) + throws EvaluationException; + Object getValue(EvaluationContext context) throws EvaluationException; + Object getValue(EvaluationContext context, @Nullable Object rootObject) + throws EvaluationException; + + T getValue(EvaluationContext context, @Nullable Class desiredResultType) + throws EvaluationException; + + T getValue(EvaluationContext context, @Nullable Object rootObject, + @Nullable Class desiredResultType) throws EvaluationException; + Class getValueType() throws EvaluationException; + Class getValueType(@Nullable Object rootObject) throws EvaluationException; + Class getValueType(EvaluationContext context) throws EvaluationException; - void setValue(Object rootObject, Object value) throws EvaluationException; -} \ No newline at end of file + Class getValueType(EvaluationContext context, @Nullable Object rootObject) + throws EvaluationException; + + boolean isWritable(@Nullable Object rootObject) throws EvaluationException; + + boolean isWritable(EvaluationContext context) throws EvaluationException; + + boolean isWritable(EvaluationContext context, @Nullable Object rootObject) + throws EvaluationException; + + void setValue(@Nullable Object rootObject, @Nullable Object value) throws EvaluationException; + + void setValue(EvaluationContext context, @Nullable Object value) throws EvaluationException; + + void setValue(EvaluationContext context, @Nullable Object rootObject, @Nullable Object value) + throws EvaluationException; + +} diff --git a/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/ExpressionException.java b/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/ExpressionException.java new file mode 100644 index 00000000000..7cd8ed51fe9 --- /dev/null +++ b/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/ExpressionException.java @@ -0,0 +1,53 @@ +/* + * Copyright 2002-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package org.springframework.expression; + +import org.springframework.lang.Nullable; + +public class ExpressionException extends RuntimeException { + public ExpressionException(String message) {} + + public ExpressionException(String message, Throwable cause) {} + + public ExpressionException(@Nullable String expressionString, String message) {} + + public ExpressionException(@Nullable String expressionString, int position, String message) {} + + public ExpressionException(int position, String message) {} + + public ExpressionException(int position, String message, Throwable cause) {} + + public final String getExpressionString() { + return null; + } + + public final int getPosition() { + return 0; + } + + @Override + public String getMessage() { + return null; + } + + public String toDetailedString() { + return null; + } + + public String getSimpleMessage() { + return null; + } + +} diff --git a/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/ExpressionParser.java b/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/ExpressionParser.java index 4bfbf796c1e..f90848acc84 100644 --- a/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/ExpressionParser.java +++ b/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/ExpressionParser.java @@ -1,6 +1,23 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + package org.springframework.expression; public interface ExpressionParser { + Expression parseExpression(String expressionString) throws ParseException; - Expression parseExpression(String string); -} \ No newline at end of file + Expression parseExpression(String expressionString, ParserContext context) + throws ParseException; + +} diff --git a/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/ParseException.java b/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/ParseException.java new file mode 100644 index 00000000000..8a2a0ecd9d2 --- /dev/null +++ b/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/ParseException.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package org.springframework.expression; + +import org.springframework.lang.Nullable; + +public class ParseException extends ExpressionException { + public ParseException(@Nullable String expressionString, int position, String message) { + super(expressionString, message); + } + + public ParseException(int position, String message, Throwable cause) { + super(message, cause); + } + + public ParseException(int position, String message) { + super(message); + } + +} diff --git a/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/ParserContext.java b/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/ParserContext.java new file mode 100644 index 00000000000..5e772eb5971 --- /dev/null +++ b/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/ParserContext.java @@ -0,0 +1,26 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package org.springframework.expression; + +public interface ParserContext { + boolean isTemplate(); + + String getExpressionPrefix(); + + String getExpressionSuffix(); + + ParserContext TEMPLATE_EXPRESSION = null; + +} diff --git a/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/common/TemplateAwareExpressionParser.java b/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/common/TemplateAwareExpressionParser.java new file mode 100644 index 00000000000..55a2aa5756f --- /dev/null +++ b/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/common/TemplateAwareExpressionParser.java @@ -0,0 +1,35 @@ +/* + * Copyright 2002-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package org.springframework.expression.common; + +import org.springframework.expression.Expression; +import org.springframework.expression.ExpressionParser; +import org.springframework.expression.ParseException; +import org.springframework.expression.ParserContext; +import org.springframework.lang.Nullable; + +public abstract class TemplateAwareExpressionParser implements ExpressionParser { + @Override + public Expression parseExpression(String expressionString) throws ParseException { + return null; + } + + @Override + public Expression parseExpression(String expressionString, @Nullable ParserContext context) + throws ParseException { + return null; + } + +} diff --git a/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/spel/standard/SpelExpression.java b/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/spel/standard/SpelExpression.java new file mode 100644 index 00000000000..949eab02e2c --- /dev/null +++ b/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/spel/standard/SpelExpression.java @@ -0,0 +1,137 @@ +/* + * Copyright 2002-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package org.springframework.expression.spel.standard; + +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.EvaluationException; +import org.springframework.expression.Expression; +import org.springframework.lang.Nullable; + +public class SpelExpression implements Expression { + public void setEvaluationContext(EvaluationContext evaluationContext) {} + + public EvaluationContext getEvaluationContext() { + return null; + } + + @Override + public String getExpressionString() { + return null; + } + + @Override + public Object getValue() throws EvaluationException { + return null; + } + + @Override + public T getValue(@Nullable Class expectedResultType) throws EvaluationException { + return null; + } + + @Override + public Object getValue(@Nullable Object rootObject) throws EvaluationException { + return null; + } + + @Override + public T getValue(@Nullable Object rootObject, @Nullable Class expectedResultType) + throws EvaluationException { + return null; + } + + @Override + public Object getValue(EvaluationContext context) throws EvaluationException { + return null; + } + + @Override + public T getValue(EvaluationContext context, @Nullable Class expectedResultType) + throws EvaluationException { + return null; + } + + @Override + public Object getValue(EvaluationContext context, @Nullable Object rootObject) + throws EvaluationException { + return null; + } + + @Override + public T getValue(EvaluationContext context, @Nullable Object rootObject, + @Nullable Class expectedResultType) throws EvaluationException { + return null; + } + + @Override + public Class getValueType() throws EvaluationException { + return null; + } + + @Override + public Class getValueType(@Nullable Object rootObject) throws EvaluationException { + return null; + } + + @Override + public Class getValueType(EvaluationContext context) throws EvaluationException { + return null; + } + + @Override + public Class getValueType(EvaluationContext context, @Nullable Object rootObject) + throws EvaluationException { + return null; + } + + @Override + public boolean isWritable(@Nullable Object rootObject) throws EvaluationException { + return false; + } + + @Override + public boolean isWritable(EvaluationContext context) throws EvaluationException { + return false; + } + + @Override + public boolean isWritable(EvaluationContext context, @Nullable Object rootObject) + throws EvaluationException { + return false; + } + + @Override + public void setValue(@Nullable Object rootObject, @Nullable Object value) + throws EvaluationException {} + + @Override + public void setValue(EvaluationContext context, @Nullable Object value) + throws EvaluationException {} + + @Override + public void setValue(EvaluationContext context, @Nullable Object rootObject, + @Nullable Object value) throws EvaluationException {} + + public boolean compileExpression() { + return false; + } + + public void revertToInterpreted() {} + + public String toStringAST() { + return null; + } + +} diff --git a/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/spel/standard/SpelExpressionParser.java b/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/spel/standard/SpelExpressionParser.java index 4aee45beee9..033e0f07915 100644 --- a/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/spel/standard/SpelExpressionParser.java +++ b/java/ql/test/stubs/springframework-5.3.8/org/springframework/expression/spel/standard/SpelExpressionParser.java @@ -1,10 +1,26 @@ +/* + * Copyright 2002-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + package org.springframework.expression.spel.standard; -import org.springframework.expression.*; - -public class SpelExpressionParser implements ExpressionParser { +import org.springframework.expression.ParseException; +import org.springframework.expression.common.TemplateAwareExpressionParser; +public class SpelExpressionParser extends TemplateAwareExpressionParser { public SpelExpressionParser() {} - - public Expression parseExpression(String string) { return null; } -} \ No newline at end of file + + public SpelExpression parseRaw(String expressionString) throws ParseException { + return null; + } +} diff --git a/java/upgrades/8ab354e68e86100ee3abe28bd44f491ecc77c1dd/old.dbscheme b/java/upgrades/8ab354e68e86100ee3abe28bd44f491ecc77c1dd/old.dbscheme new file mode 100644 index 00000000000..8ab354e68e8 --- /dev/null +++ b/java/upgrades/8ab354e68e86100ee3abe28bd44f491ecc77c1dd/old.dbscheme @@ -0,0 +1,987 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref // deprecated +); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +classes( + unique int id: @class, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @class ref +); + +isRecord( + unique int id: @class ref +); + +interfaces( + unique int id: @interface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @interface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @interface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @class ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @typeorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @typeorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @class ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @interface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @typeorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +; + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +@exprparent = @stmt | @expr | @callable | @field | @fielddecl | @class | @interface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@typeorpackage = @type | @package; + +@typeorcallable = @type | @callable; +@classorinterface = @interface | @class; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype; +@classorarray = @class | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; +@element = @file | @package | @primitive | @class | @interface | @method | @constructor | @modifier | @param | @exception | @field | + @annotation | @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl; + +@modifiable = @member_modifiable| @param | @localvar ; + +@member_modifiable = @class | @interface | @method | @constructor | @field ; + +@member = @method | @constructor | @field | @reftype ; + +@locatable = @file | @class | @interface | @fielddecl | @field | @constructor | @method | @param | @exception + | @boundedtype | @typebound | @array | @primitive + | @import | @stmt | @expr | @localvar | @javadoc | @javadocTag | @javadocText + | @xmllocatable; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; diff --git a/java/upgrades/8ab354e68e86100ee3abe28bd44f491ecc77c1dd/semmlecode.dbscheme b/java/upgrades/8ab354e68e86100ee3abe28bd44f491ecc77c1dd/semmlecode.dbscheme new file mode 100755 index 00000000000..017ac1ed2df --- /dev/null +++ b/java/upgrades/8ab354e68e86100ee3abe28bd44f491ecc77c1dd/semmlecode.dbscheme @@ -0,0 +1,983 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +classes( + unique int id: @class, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @class ref +); + +isRecord( + unique int id: @class ref +); + +interfaces( + unique int id: @interface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @interface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @interface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @class ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @typeorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @typeorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @class ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @interface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @typeorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +; + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +@exprparent = @stmt | @expr | @callable | @field | @fielddecl | @class | @interface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@typeorpackage = @type | @package; + +@typeorcallable = @type | @callable; +@classorinterface = @interface | @class; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype; +@classorarray = @class | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; +@element = @file | @package | @primitive | @class | @interface | @method | @constructor | @modifier | @param | @exception | @field | + @annotation | @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl; + +@modifiable = @member_modifiable| @param | @localvar ; + +@member_modifiable = @class | @interface | @method | @constructor | @field ; + +@member = @method | @constructor | @field | @reftype ; + +@locatable = @file | @class | @interface | @fielddecl | @field | @constructor | @method | @param | @exception + | @boundedtype | @typebound | @array | @primitive + | @import | @stmt | @expr | @localvar | @javadoc | @javadocTag | @javadocText + | @xmllocatable; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; diff --git a/java/upgrades/8ab354e68e86100ee3abe28bd44f491ecc77c1dd/upgrade.properties b/java/upgrades/8ab354e68e86100ee3abe28bd44f491ecc77c1dd/upgrade.properties new file mode 100644 index 00000000000..a0c4ba602a1 --- /dev/null +++ b/java/upgrades/8ab354e68e86100ee3abe28bd44f491ecc77c1dd/upgrade.properties @@ -0,0 +1,4 @@ +description: Removed unused column from the `folders` and `files` relations +compatibility: full +files.rel: reorder files.rel (int id, string name, string simple, string ext, int fromSource) id name +folders.rel: reorder folders.rel (int id, string name, string simple) id name \ No newline at end of file diff --git a/javascript/change-notes/2021-09-01-clipboard-data.md b/javascript/change-notes/2021-09-01-clipboard-data.md new file mode 100644 index 00000000000..2d8e6775428 --- /dev/null +++ b/javascript/change-notes/2021-09-01-clipboard-data.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The security queries now recognize clipboard data as a source, enabling the queries to flag additional alerts. diff --git a/javascript/change-notes/2021-09-01-typescript-4.4.md b/javascript/change-notes/2021-09-01-typescript-4.4.md new file mode 100644 index 00000000000..ec5eca5193c --- /dev/null +++ b/javascript/change-notes/2021-09-01-typescript-4.4.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* TypeScript 4.4 is now supported. diff --git a/javascript/change-notes/2021-09-07-static-initializer.md b/javascript/change-notes/2021-09-07-static-initializer.md new file mode 100644 index 00000000000..f4a4dd6a9ea --- /dev/null +++ b/javascript/change-notes/2021-09-07-static-initializer.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Support for the ECMAScript proposed feature "class static initialization blocks" has been added. diff --git a/javascript/extractor/lib/typescript/package.json b/javascript/extractor/lib/typescript/package.json index 6064cc946d9..f191604e7c8 100644 --- a/javascript/extractor/lib/typescript/package.json +++ b/javascript/extractor/lib/typescript/package.json @@ -2,7 +2,7 @@ "name": "typescript-parser-wrapper", "private": true, "dependencies": { - "typescript": "4.3.5" + "typescript": "4.4.2" }, "scripts": { "build": "tsc --project tsconfig.json", diff --git a/javascript/extractor/lib/typescript/yarn.lock b/javascript/extractor/lib/typescript/yarn.lock index c1254a4e73f..639a32d261e 100644 --- a/javascript/extractor/lib/typescript/yarn.lock +++ b/javascript/extractor/lib/typescript/yarn.lock @@ -6,7 +6,7 @@ version "12.7.11" resolved node-12.7.11.tgz#be879b52031cfb5d295b047f5462d8ef1a716446 -typescript@4.3.5: - version "4.3.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" - integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== +typescript@4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.2.tgz#6d618640d430e3569a1dfb44f7d7e600ced3ee86" + integrity sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ== diff --git a/javascript/extractor/src/com/semmle/jcorn/Parser.java b/javascript/extractor/src/com/semmle/jcorn/Parser.java index 5f7383813c6..6250e9d8ed6 100644 --- a/javascript/extractor/src/com/semmle/jcorn/Parser.java +++ b/javascript/extractor/src/com/semmle/jcorn/Parser.java @@ -83,6 +83,7 @@ import com.semmle.js.ast.SequenceExpression; import com.semmle.js.ast.SourceLocation; import com.semmle.js.ast.SpreadElement; import com.semmle.js.ast.Statement; +import com.semmle.js.ast.StaticInitializer; import com.semmle.js.ast.Super; import com.semmle.js.ast.SwitchCase; import com.semmle.js.ast.SwitchStatement; @@ -3244,6 +3245,10 @@ public class Parser { PropertyInfo pi = new PropertyInfo(false, isGenerator, methodStartLoc); this.parsePropertyName(pi); boolean isStatic = isMaybeStatic && this.type != TokenType.parenL; + if (isStatic && this.type == TokenType.braceL) { + BlockStatement block = parseBlock(false); + return new StaticInitializer(block.getLoc(), block); + } if (isStatic) { if (isGenerator) this.unexpected(); isGenerator = this.eat(TokenType.star); diff --git a/javascript/extractor/src/com/semmle/js/ast/DefaultVisitor.java b/javascript/extractor/src/com/semmle/js/ast/DefaultVisitor.java index 995f580edd2..c450fdd0468 100644 --- a/javascript/extractor/src/com/semmle/js/ast/DefaultVisitor.java +++ b/javascript/extractor/src/com/semmle/js/ast/DefaultVisitor.java @@ -782,4 +782,9 @@ public class DefaultVisitor implements Visitor { public R visit(GeneratedCodeExpr nd, C c) { return visit((Expression) nd, c); } + + @Override + public R visit(StaticInitializer nd, C c) { + return visit((MemberDefinition) nd, c); + } } diff --git a/javascript/extractor/src/com/semmle/js/ast/MemberDefinition.java b/javascript/extractor/src/com/semmle/js/ast/MemberDefinition.java index 7cacafa96ed..e3bbc6a1830 100644 --- a/javascript/extractor/src/com/semmle/js/ast/MemberDefinition.java +++ b/javascript/extractor/src/com/semmle/js/ast/MemberDefinition.java @@ -9,7 +9,7 @@ import java.util.List; *

    A member definition has a name and an optional initial value, whose type is given by the type * parameter {@code V}. */ -public abstract class MemberDefinition extends Node { +public abstract class MemberDefinition extends Node { /** A bitmask of flags defined in {@linkplain DeclarationFlags}. */ private final int flags; @@ -21,7 +21,7 @@ public abstract class MemberDefinition extends Node { */ private final Expression key; - /** The initial value of the member. */ + /** The initial value / initializer of the member. */ private final V value; /** The decorators applied to this member, if any. */ diff --git a/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java b/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java index 02fd40b12d8..83a37e11534 100644 --- a/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java +++ b/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java @@ -897,6 +897,11 @@ public class NodeCopier implements Visitor { @Override public INode visit(GeneratedCodeExpr nd, Void c) { - return new GeneratedCodeExpr(visit(nd.getLoc()), nd.getOpeningDelimiter(), nd.getClosingDelimiter(), nd.getBody()); + return new GeneratedCodeExpr(visit(nd.getLoc()), nd.getOpeningDelimiter(), nd.getClosingDelimiter(), nd.getBody()); + } + + @Override + public INode visit(StaticInitializer nd, Void c) { + return new StaticInitializer(visit(nd.getLoc()), copy(nd.getValue())); } } diff --git a/javascript/extractor/src/com/semmle/js/ast/StaticInitializer.java b/javascript/extractor/src/com/semmle/js/ast/StaticInitializer.java new file mode 100644 index 00000000000..d4287cd3f49 --- /dev/null +++ b/javascript/extractor/src/com/semmle/js/ast/StaticInitializer.java @@ -0,0 +1,21 @@ +package com.semmle.js.ast; + +/** + * A static initializer block in a class. E.g. ```TypeScript class Foo { static + * bar : number; static { Foo.bar = 42; } } + */ +public class StaticInitializer extends MemberDefinition { + public StaticInitializer(SourceLocation loc, BlockStatement body) { + super("StaticInitializer", loc, DeclarationFlags.static_, null, body); + } + + @Override + public boolean isConcrete() { + return false; + } + + @Override + public R accept(Visitor v, C c) { + return v.visit(this, c); + } +} diff --git a/javascript/extractor/src/com/semmle/js/ast/Visitor.java b/javascript/extractor/src/com/semmle/js/ast/Visitor.java index f7dfbd4e3aa..3d595b981b8 100644 --- a/javascript/extractor/src/com/semmle/js/ast/Visitor.java +++ b/javascript/extractor/src/com/semmle/js/ast/Visitor.java @@ -315,4 +315,6 @@ public interface Visitor { public R visit(XMLDotDotExpression nd, C c); public R visit(GeneratedCodeExpr generatedCodeExpr, C c); + + public R visit(StaticInitializer nd, C c); } diff --git a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java index 6796f262fef..158a33030a4 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java @@ -80,6 +80,7 @@ import com.semmle.js.ast.SourceElement; import com.semmle.js.ast.SourceLocation; import com.semmle.js.ast.SpreadElement; import com.semmle.js.ast.Statement; +import com.semmle.js.ast.StaticInitializer; import com.semmle.js.ast.Super; import com.semmle.js.ast.SwitchCase; import com.semmle.js.ast.SwitchStatement; @@ -1613,6 +1614,8 @@ public class ASTExtractor { int kind; if (nd instanceof MethodDefinition) { kind = getMethodKind((MethodDefinition) nd); + } else if (nd instanceof StaticInitializer) { + kind = 10; } else { kind = getFieldKind((FieldDefinition) nd); } diff --git a/javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java index 85dd13146fb..fa8452c0b43 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java @@ -65,6 +65,7 @@ import com.semmle.js.ast.SequenceExpression; import com.semmle.js.ast.SourceLocation; import com.semmle.js.ast.SpreadElement; import com.semmle.js.ast.Statement; +import com.semmle.js.ast.StaticInitializer; import com.semmle.js.ast.Super; import com.semmle.js.ast.SwitchCase; import com.semmle.js.ast.SwitchStatement; @@ -1163,10 +1164,11 @@ public class CFGExtractor { private Map constructor2Class = new LinkedHashMap<>(); private Void visit(Node nd, AClass ac, SuccessorInfo i) { - for (MemberDefinition m : ac.getBody().getBody()) - if (m.isConstructor() && m.isConcrete()) constructor2Class.put(m.getValue(), ac); + for (MemberDefinition md : ac.getBody().getBody()) { + if (md.isConstructor() && md.isConcrete()) constructor2Class.put((Expression)md.getValue(), ac); + } visitSequence(ac.getId(), ac.getSuperClass(), ac.getBody(), nd); - writeSuccessors(nd, visitSequence(getStaticFields(ac.getBody()), getDecoratorsOfClass(ac), i.getAllSuccessors())); + writeSuccessors(nd, visitSequence(getStaticInitializers(ac.getBody()), getDecoratorsOfClass(ac), i.getAllSuccessors())); return null; } @@ -1618,19 +1620,24 @@ public class CFGExtractor { return mds; } - private List> getStaticFields(ClassBody nd) { - List> mds = new ArrayList<>(); - for (MemberDefinition md : nd.getBody()) { - if (md instanceof FieldDefinition && md.isStatic()) mds.add(md); + /** + * Gets the static fields, and static initializer blocks, from `nd`. + */ + private List getStaticInitializers(ClassBody nd) { + List nodes = new ArrayList<>(); + for (MemberDefinition node : nd.getBody()) { + if (node instanceof FieldDefinition && ((FieldDefinition)node).isStatic()) nodes.add(node); + if (node instanceof StaticInitializer) nodes.add(node.getValue()); } - return mds; + return nodes; } private List getConcreteInstanceFields(ClassBody nd) { List fds = new ArrayList<>(); - for (MemberDefinition md : nd.getBody()) + for (MemberDefinition md : nd.getBody()) { if (md instanceof FieldDefinition && !md.isStatic() && md.isConcrete()) fds.add((FieldDefinition) md); + } return fds; } diff --git a/javascript/extractor/src/com/semmle/js/extractor/Main.java b/javascript/extractor/src/com/semmle/js/extractor/Main.java index a7c3074a64e..201f918f3e4 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/Main.java +++ b/javascript/extractor/src/com/semmle/js/extractor/Main.java @@ -43,7 +43,7 @@ public class Main { * A version identifier that should be updated every time the extractor changes in such a way that * it may produce different tuples for the same file under the same {@link ExtractorConfig}. */ - public static final String EXTRACTOR_VERSION = "2021-07-28"; + public static final String EXTRACTOR_VERSION = "2021-09-01"; public static final Pattern NEWLINE = Pattern.compile("\n"); diff --git a/javascript/extractor/src/com/semmle/js/extractor/test/TrapTests.java b/javascript/extractor/src/com/semmle/js/extractor/test/TrapTests.java index 6f3f7e1e445..ae3a28cbc35 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/test/TrapTests.java +++ b/javascript/extractor/src/com/semmle/js/extractor/test/TrapTests.java @@ -11,6 +11,7 @@ import com.semmle.util.data.Pair; import com.semmle.util.data.StringUtil; import com.semmle.util.extraction.ExtractorOutputConfig; import com.semmle.util.io.WholeIO; +import com.semmle.util.process.Env; import com.semmle.util.srcarchive.DummySourceArchive; import com.semmle.util.trap.ITrapWriterFactory; import com.semmle.util.trap.TrapWriter; @@ -21,6 +22,7 @@ import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map.Entry; import org.junit.AfterClass; diff --git a/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java b/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java index f8ad99915c9..affea7490a5 100644 --- a/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java +++ b/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java @@ -82,6 +82,7 @@ import com.semmle.js.ast.SequenceExpression; import com.semmle.js.ast.SourceLocation; import com.semmle.js.ast.SpreadElement; import com.semmle.js.ast.Statement; +import com.semmle.js.ast.StaticInitializer; import com.semmle.js.ast.Super; import com.semmle.js.ast.SwitchCase; import com.semmle.js.ast.SwitchStatement; @@ -632,6 +633,8 @@ public class TypeScriptASTConverter { return convertWithStatement(node, loc); case "YieldExpression": return convertYieldExpression(node, loc); + case "ClassStaticBlockDeclaration": + return convertStaticInitializerBlock(node, loc); default: throw new ParseError( "Unsupported TypeScript syntax " + kind, getSourceLocation(node).getStart()); @@ -866,6 +869,11 @@ public class TypeScriptASTConverter { } } + private Node convertStaticInitializerBlock(JsonObject node, SourceLocation loc) throws ParseError { + BlockStatement body = new BlockStatement(loc, convertChildren(node.get("body").getAsJsonObject(), "statements")); + return new StaticInitializer(loc, body); + } + private Node convertBlock(JsonObject node, SourceLocation loc) throws ParseError { return new BlockStatement(loc, convertChildren(node, "statements")); } diff --git a/javascript/extractor/tests/cfg/output/trap/classexpr1.js.trap b/javascript/extractor/tests/cfg/output/trap/classexpr1.js.trap index 29641d5961c..36170d46ce6 100644 --- a/javascript/extractor/tests/cfg/output/trap/classexpr1.js.trap +++ b/javascript/extractor/tests/cfg/output/trap/classexpr1.js.trap @@ -1,7 +1,7 @@ #10000=@"/classexpr1.js;sourcefile" -files(#10000,"/classexpr1.js","classexpr1","js",0) +files(#10000,"/classexpr1.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/cfg/output/trap/classexpr2.js.trap b/javascript/extractor/tests/cfg/output/trap/classexpr2.js.trap index d5d9b6aafc8..7dcf1ca7625 100644 --- a/javascript/extractor/tests/cfg/output/trap/classexpr2.js.trap +++ b/javascript/extractor/tests/cfg/output/trap/classexpr2.js.trap @@ -1,7 +1,7 @@ #10000=@"/classexpr2.js;sourcefile" -files(#10000,"/classexpr2.js","classexpr2","js",0) +files(#10000,"/classexpr2.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/cfg/output/trap/classexpr3.js.trap b/javascript/extractor/tests/cfg/output/trap/classexpr3.js.trap index 936c7c58180..4e7d7c4ea30 100644 --- a/javascript/extractor/tests/cfg/output/trap/classexpr3.js.trap +++ b/javascript/extractor/tests/cfg/output/trap/classexpr3.js.trap @@ -1,7 +1,7 @@ #10000=@"/classexpr3.js;sourcefile" -files(#10000,"/classexpr3.js","classexpr3","js",0) +files(#10000,"/classexpr3.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/cfg/output/trap/classexpr4.js.trap b/javascript/extractor/tests/cfg/output/trap/classexpr4.js.trap index a7f654473b3..db4c964d45e 100644 --- a/javascript/extractor/tests/cfg/output/trap/classexpr4.js.trap +++ b/javascript/extractor/tests/cfg/output/trap/classexpr4.js.trap @@ -1,7 +1,7 @@ #10000=@"/classexpr4.js;sourcefile" -files(#10000,"/classexpr4.js","classexpr4","js",0) +files(#10000,"/classexpr4.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/cfg/output/trap/fields.js.trap b/javascript/extractor/tests/cfg/output/trap/fields.js.trap index 14486f99c7e..a1892dea841 100644 --- a/javascript/extractor/tests/cfg/output/trap/fields.js.trap +++ b/javascript/extractor/tests/cfg/output/trap/fields.js.trap @@ -1,7 +1,7 @@ #10000=@"/fields.js;sourcefile" -files(#10000,"/fields.js","fields","js",0) +files(#10000,"/fields.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/cfg/output/trap/seq.js.trap b/javascript/extractor/tests/cfg/output/trap/seq.js.trap index bf660301f8e..e9aee318c82 100644 --- a/javascript/extractor/tests/cfg/output/trap/seq.js.trap +++ b/javascript/extractor/tests/cfg/output/trap/seq.js.trap @@ -1,7 +1,7 @@ #10000=@"/seq.js;sourcefile" -files(#10000,"/seq.js","seq","js",0) +files(#10000,"/seq.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/cfg/output/trap/short-circuit.js.trap b/javascript/extractor/tests/cfg/output/trap/short-circuit.js.trap index 563d7c3a428..63e56bb5c49 100644 --- a/javascript/extractor/tests/cfg/output/trap/short-circuit.js.trap +++ b/javascript/extractor/tests/cfg/output/trap/short-circuit.js.trap @@ -1,7 +1,7 @@ #10000=@"/short-circuit.js;sourcefile" -files(#10000,"/short-circuit.js","short-circuit","js",0) +files(#10000,"/short-circuit.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/cfg/output/trap/ternary.js.trap b/javascript/extractor/tests/cfg/output/trap/ternary.js.trap index 7b534184219..57230ac39cd 100644 --- a/javascript/extractor/tests/cfg/output/trap/ternary.js.trap +++ b/javascript/extractor/tests/cfg/output/trap/ternary.js.trap @@ -1,7 +1,7 @@ #10000=@"/ternary.js;sourcefile" -files(#10000,"/ternary.js","ternary","js",0) +files(#10000,"/ternary.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/cfg/output/trap/tst.js.trap b/javascript/extractor/tests/cfg/output/trap/tst.js.trap index c857f564069..7f7fc1ea383 100644 --- a/javascript/extractor/tests/cfg/output/trap/tst.js.trap +++ b/javascript/extractor/tests/cfg/output/trap/tst.js.trap @@ -1,7 +1,7 @@ #10000=@"/tst.js;sourcefile" -files(#10000,"/tst.js","tst","js",0) +files(#10000,"/tst.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/closure/output/trap/googDotDeclareModuleId.js.trap b/javascript/extractor/tests/closure/output/trap/googDotDeclareModuleId.js.trap index 64d67a4e74b..09719bdae19 100644 --- a/javascript/extractor/tests/closure/output/trap/googDotDeclareModuleId.js.trap +++ b/javascript/extractor/tests/closure/output/trap/googDotDeclareModuleId.js.trap @@ -1,7 +1,7 @@ #10000=@"/googDotDeclareModuleId.js;sourcefile" -files(#10000,"/googDotDeclareModuleId.js","googDotDeclareModuleId","js",0) +files(#10000,"/googDotDeclareModuleId.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/closure/output/trap/googDotModule.js.trap b/javascript/extractor/tests/closure/output/trap/googDotModule.js.trap index 55558520eb4..c38628f6a37 100644 --- a/javascript/extractor/tests/closure/output/trap/googDotModule.js.trap +++ b/javascript/extractor/tests/closure/output/trap/googDotModule.js.trap @@ -1,7 +1,7 @@ #10000=@"/googDotModule.js;sourcefile" -files(#10000,"/googDotModule.js","googDotModule","js",0) +files(#10000,"/googDotModule.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/closure/output/trap/googDotProvide.js.trap b/javascript/extractor/tests/closure/output/trap/googDotProvide.js.trap index 10a4d03bcfa..99979f50c2c 100644 --- a/javascript/extractor/tests/closure/output/trap/googDotProvide.js.trap +++ b/javascript/extractor/tests/closure/output/trap/googDotProvide.js.trap @@ -1,7 +1,7 @@ #10000=@"/googDotProvide.js;sourcefile" -files(#10000,"/googDotProvide.js","googDotProvide","js",0) +files(#10000,"/googDotProvide.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/comments/output/trap/comments.js.trap b/javascript/extractor/tests/comments/output/trap/comments.js.trap index 279e1aaba17..79a199f90ec 100644 --- a/javascript/extractor/tests/comments/output/trap/comments.js.trap +++ b/javascript/extractor/tests/comments/output/trap/comments.js.trap @@ -1,7 +1,7 @@ #10000=@"/comments.js;sourcefile" -files(#10000,"/comments.js","comments","js",0) +files(#10000,"/comments.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/comments/output/trap/empty_comment.js.trap b/javascript/extractor/tests/comments/output/trap/empty_comment.js.trap index b90f89ab061..51e9652b166 100644 --- a/javascript/extractor/tests/comments/output/trap/empty_comment.js.trap +++ b/javascript/extractor/tests/comments/output/trap/empty_comment.js.trap @@ -1,7 +1,7 @@ #10000=@"/empty_comment.js;sourcefile" -files(#10000,"/empty_comment.js","empty_comment","js",0) +files(#10000,"/empty_comment.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/comments/output/trap/jsdoc.js.trap b/javascript/extractor/tests/comments/output/trap/jsdoc.js.trap index f6e797abd13..736a6b2d19f 100644 --- a/javascript/extractor/tests/comments/output/trap/jsdoc.js.trap +++ b/javascript/extractor/tests/comments/output/trap/jsdoc.js.trap @@ -1,7 +1,7 @@ #10000=@"/jsdoc.js;sourcefile" -files(#10000,"/jsdoc.js","jsdoc","js",0) +files(#10000,"/jsdoc.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/default-encoding/output/trap/latin1.js.trap b/javascript/extractor/tests/default-encoding/output/trap/latin1.js.trap index 305d467baa2..1b2c513def0 100644 --- a/javascript/extractor/tests/default-encoding/output/trap/latin1.js.trap +++ b/javascript/extractor/tests/default-encoding/output/trap/latin1.js.trap @@ -1,7 +1,7 @@ #10000=@"/latin1.js;sourcefile" -files(#10000,"/latin1.js","latin1","js",0) +files(#10000,"/latin1.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/e4x/output/trap/regress.js.trap b/javascript/extractor/tests/e4x/output/trap/regress.js.trap index 42830ffef1d..1f14daae973 100644 --- a/javascript/extractor/tests/e4x/output/trap/regress.js.trap +++ b/javascript/extractor/tests/e4x/output/trap/regress.js.trap @@ -1,7 +1,7 @@ #10000=@"/regress.js;sourcefile" -files(#10000,"/regress.js","regress","js",0) +files(#10000,"/regress.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/e4x/output/trap/tst.js.trap b/javascript/extractor/tests/e4x/output/trap/tst.js.trap index 518cde0ecb8..a9636dd5fa4 100644 --- a/javascript/extractor/tests/e4x/output/trap/tst.js.trap +++ b/javascript/extractor/tests/e4x/output/trap/tst.js.trap @@ -1,7 +1,7 @@ #10000=@"/tst.js;sourcefile" -files(#10000,"/tst.js","tst","js",0) +files(#10000,"/tst.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/encoding/output/trap/surrogates.js.trap b/javascript/extractor/tests/encoding/output/trap/surrogates.js.trap index 47fdcdd7f8e..1e83bf1920e 100644 --- a/javascript/extractor/tests/encoding/output/trap/surrogates.js.trap +++ b/javascript/extractor/tests/encoding/output/trap/surrogates.js.trap @@ -1,7 +1,7 @@ #10000=@"/surrogates.js;sourcefile" -files(#10000,"/surrogates.js","surrogates","js",0) +files(#10000,"/surrogates.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/encoding/output/trap/unicode.js.trap b/javascript/extractor/tests/encoding/output/trap/unicode.js.trap index 1f4bf71cbb8..e30e1de8143 100644 --- a/javascript/extractor/tests/encoding/output/trap/unicode.js.trap +++ b/javascript/extractor/tests/encoding/output/trap/unicode.js.trap @@ -1,7 +1,7 @@ #10000=@"/unicode.js;sourcefile" -files(#10000,"/unicode.js","unicode","js",0) +files(#10000,"/unicode.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/encoding/output/trap/zwsp.js.trap b/javascript/extractor/tests/encoding/output/trap/zwsp.js.trap index f74356384ba..c9bab7a017d 100644 --- a/javascript/extractor/tests/encoding/output/trap/zwsp.js.trap +++ b/javascript/extractor/tests/encoding/output/trap/zwsp.js.trap @@ -1,7 +1,7 @@ #10000=@"/zwsp.js;sourcefile" -files(#10000,"/zwsp.js","zwsp","js",0) +files(#10000,"/zwsp.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/errors/output/trap/empty.js.trap b/javascript/extractor/tests/errors/output/trap/empty.js.trap index 977fc8c44af..c686cd023f4 100644 --- a/javascript/extractor/tests/errors/output/trap/empty.js.trap +++ b/javascript/extractor/tests/errors/output/trap/empty.js.trap @@ -1,7 +1,7 @@ #10000=@"/empty.js;sourcefile" -files(#10000,"/empty.js","empty","js",0) +files(#10000,"/empty.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/errors/output/trap/errors.js.trap b/javascript/extractor/tests/errors/output/trap/errors.js.trap index 56265a4cceb..87858ae4846 100644 --- a/javascript/extractor/tests/errors/output/trap/errors.js.trap +++ b/javascript/extractor/tests/errors/output/trap/errors.js.trap @@ -1,7 +1,7 @@ #10000=@"/errors.js;sourcefile" -files(#10000,"/errors.js","errors","js",0) +files(#10000,"/errors.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/errors/output/trap/incomplete.js.trap b/javascript/extractor/tests/errors/output/trap/incomplete.js.trap index 3e950d57691..5a8c0ad2f36 100644 --- a/javascript/extractor/tests/errors/output/trap/incomplete.js.trap +++ b/javascript/extractor/tests/errors/output/trap/incomplete.js.trap @@ -1,7 +1,7 @@ #10000=@"/incomplete.js;sourcefile" -files(#10000,"/incomplete.js","incomplete","js",0) +files(#10000,"/incomplete.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/errors/output/trap/invalid-assignment-pattern.js.trap b/javascript/extractor/tests/errors/output/trap/invalid-assignment-pattern.js.trap index 4d01e4e9373..108c822691b 100644 --- a/javascript/extractor/tests/errors/output/trap/invalid-assignment-pattern.js.trap +++ b/javascript/extractor/tests/errors/output/trap/invalid-assignment-pattern.js.trap @@ -1,7 +1,7 @@ #10000=@"/invalid-assignment-pattern.js;sourcefile" -files(#10000,"/invalid-assignment-pattern.js","invalid-assignment-pattern","js",0) +files(#10000,"/invalid-assignment-pattern.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/errors/output/trap/json.js.trap b/javascript/extractor/tests/errors/output/trap/json.js.trap index c0762090623..66eeec6d36a 100644 --- a/javascript/extractor/tests/errors/output/trap/json.js.trap +++ b/javascript/extractor/tests/errors/output/trap/json.js.trap @@ -1,7 +1,7 @@ #10000=@"/json.js;sourcefile" -files(#10000,"/json.js","json","js",0) +files(#10000,"/json.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/errors/output/trap/kwident.js.trap b/javascript/extractor/tests/errors/output/trap/kwident.js.trap index 14d3767ff8a..10b0e9ec392 100644 --- a/javascript/extractor/tests/errors/output/trap/kwident.js.trap +++ b/javascript/extractor/tests/errors/output/trap/kwident.js.trap @@ -1,7 +1,7 @@ #10000=@"/kwident.js;sourcefile" -files(#10000,"/kwident.js","kwident","js",0) +files(#10000,"/kwident.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/errors/output/trap/weirdassign.js.trap b/javascript/extractor/tests/errors/output/trap/weirdassign.js.trap index 9569931fc2a..314caccacae 100644 --- a/javascript/extractor/tests/errors/output/trap/weirdassign.js.trap +++ b/javascript/extractor/tests/errors/output/trap/weirdassign.js.trap @@ -1,7 +1,7 @@ #10000=@"/weirdassign.js;sourcefile" -files(#10000,"/weirdassign.js","weirdassign","js",0) +files(#10000,"/weirdassign.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/array_pattern_with_default.js.trap b/javascript/extractor/tests/es2015/output/trap/array_pattern_with_default.js.trap index 590dd38c38f..2351f1fa347 100644 --- a/javascript/extractor/tests/es2015/output/trap/array_pattern_with_default.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/array_pattern_with_default.js.trap @@ -1,7 +1,7 @@ #10000=@"/array_pattern_with_default.js;sourcefile" -files(#10000,"/array_pattern_with_default.js","array_pattern_with_default","js",0) +files(#10000,"/array_pattern_with_default.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/array_pattern_with_rest.js.trap b/javascript/extractor/tests/es2015/output/trap/array_pattern_with_rest.js.trap index db47ff2def7..7f8c2257eee 100644 --- a/javascript/extractor/tests/es2015/output/trap/array_pattern_with_rest.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/array_pattern_with_rest.js.trap @@ -1,7 +1,7 @@ #10000=@"/array_pattern_with_rest.js;sourcefile" -files(#10000,"/array_pattern_with_rest.js","array_pattern_with_rest","js",0) +files(#10000,"/array_pattern_with_rest.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/arrowfn.js.trap b/javascript/extractor/tests/es2015/output/trap/arrowfn.js.trap index 8224e9c70ad..44fe9bba129 100644 --- a/javascript/extractor/tests/es2015/output/trap/arrowfn.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/arrowfn.js.trap @@ -1,7 +1,7 @@ #10000=@"/arrowfn.js;sourcefile" -files(#10000,"/arrowfn.js","arrowfn","js",0) +files(#10000,"/arrowfn.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/class_accessors.js.trap b/javascript/extractor/tests/es2015/output/trap/class_accessors.js.trap index 87381be5e25..5c5c137c72d 100644 --- a/javascript/extractor/tests/es2015/output/trap/class_accessors.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/class_accessors.js.trap @@ -1,7 +1,7 @@ #10000=@"/class_accessors.js;sourcefile" -files(#10000,"/class_accessors.js","class_accessors","js",0) +files(#10000,"/class_accessors.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/class_ctor.js.trap b/javascript/extractor/tests/es2015/output/trap/class_ctor.js.trap index 834f78bc437..6ee7194f2b3 100644 --- a/javascript/extractor/tests/es2015/output/trap/class_ctor.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/class_ctor.js.trap @@ -1,7 +1,7 @@ #10000=@"/class_ctor.js;sourcefile" -files(#10000,"/class_ctor.js","class_ctor","js",0) +files(#10000,"/class_ctor.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/class_extends.js.trap b/javascript/extractor/tests/es2015/output/trap/class_extends.js.trap index c97a4abe506..8c15a580955 100644 --- a/javascript/extractor/tests/es2015/output/trap/class_extends.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/class_extends.js.trap @@ -1,7 +1,7 @@ #10000=@"/class_extends.js;sourcefile" -files(#10000,"/class_extends.js","class_extends","js",0) +files(#10000,"/class_extends.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/class_extends2.js.trap b/javascript/extractor/tests/es2015/output/trap/class_extends2.js.trap index d63cd3de396..faa9e6abbec 100644 --- a/javascript/extractor/tests/es2015/output/trap/class_extends2.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/class_extends2.js.trap @@ -1,7 +1,7 @@ #10000=@"/class_extends2.js;sourcefile" -files(#10000,"/class_extends2.js","class_extends2","js",0) +files(#10000,"/class_extends2.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/class_method.js.trap b/javascript/extractor/tests/es2015/output/trap/class_method.js.trap index 31fcacadab9..d0ccaee9508 100644 --- a/javascript/extractor/tests/es2015/output/trap/class_method.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/class_method.js.trap @@ -1,7 +1,7 @@ #10000=@"/class_method.js;sourcefile" -files(#10000,"/class_method.js","class_method","js",0) +files(#10000,"/class_method.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/class_static.js.trap b/javascript/extractor/tests/es2015/output/trap/class_static.js.trap index 74f7752d617..5c0d8f20d87 100644 --- a/javascript/extractor/tests/es2015/output/trap/class_static.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/class_static.js.trap @@ -1,7 +1,7 @@ #10000=@"/class_static.js;sourcefile" -files(#10000,"/class_static.js","class_static","js",0) +files(#10000,"/class_static.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/classdecl.js.trap b/javascript/extractor/tests/es2015/output/trap/classdecl.js.trap index b5617754b33..e5a40dab400 100644 --- a/javascript/extractor/tests/es2015/output/trap/classdecl.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/classdecl.js.trap @@ -1,7 +1,7 @@ #10000=@"/classdecl.js;sourcefile" -files(#10000,"/classdecl.js","classdecl","js",0) +files(#10000,"/classdecl.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/classexpr.js.trap b/javascript/extractor/tests/es2015/output/trap/classexpr.js.trap index 839909db531..ad02e4ce6e3 100644 --- a/javascript/extractor/tests/es2015/output/trap/classexpr.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/classexpr.js.trap @@ -1,7 +1,7 @@ #10000=@"/classexpr.js;sourcefile" -files(#10000,"/classexpr.js","classexpr","js",0) +files(#10000,"/classexpr.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/classexpr2.js.trap b/javascript/extractor/tests/es2015/output/trap/classexpr2.js.trap index 8bb09ea4bb9..0380ce770f4 100644 --- a/javascript/extractor/tests/es2015/output/trap/classexpr2.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/classexpr2.js.trap @@ -1,7 +1,7 @@ #10000=@"/classexpr2.js;sourcefile" -files(#10000,"/classexpr2.js","classexpr2","js",0) +files(#10000,"/classexpr2.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/complex_array_pattern.js.trap b/javascript/extractor/tests/es2015/output/trap/complex_array_pattern.js.trap index 1a8e3663ffd..2d46f91bfbb 100644 --- a/javascript/extractor/tests/es2015/output/trap/complex_array_pattern.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/complex_array_pattern.js.trap @@ -1,7 +1,7 @@ #10000=@"/complex_array_pattern.js;sourcefile" -files(#10000,"/complex_array_pattern.js","complex_array_pattern","js",0) +files(#10000,"/complex_array_pattern.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/complex_object_pattern.js.trap b/javascript/extractor/tests/es2015/output/trap/complex_object_pattern.js.trap index 3eb51acea42..aff5d4f9957 100644 --- a/javascript/extractor/tests/es2015/output/trap/complex_object_pattern.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/complex_object_pattern.js.trap @@ -1,7 +1,7 @@ #10000=@"/complex_object_pattern.js;sourcefile" -files(#10000,"/complex_object_pattern.js","complex_object_pattern","js",0) +files(#10000,"/complex_object_pattern.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/const.js.trap b/javascript/extractor/tests/es2015/output/trap/const.js.trap index 54080375486..08a72521d89 100644 --- a/javascript/extractor/tests/es2015/output/trap/const.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/const.js.trap @@ -1,7 +1,7 @@ #10000=@"/const.js;sourcefile" -files(#10000,"/const.js","const","js",0) +files(#10000,"/const.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/defaultargs.js.trap b/javascript/extractor/tests/es2015/output/trap/defaultargs.js.trap index c6303460489..00a6d7b38a5 100644 --- a/javascript/extractor/tests/es2015/output/trap/defaultargs.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/defaultargs.js.trap @@ -1,7 +1,7 @@ #10000=@"/defaultargs.js;sourcefile" -files(#10000,"/defaultargs.js","defaultargs","js",0) +files(#10000,"/defaultargs.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/delegating_yield.js.trap b/javascript/extractor/tests/es2015/output/trap/delegating_yield.js.trap index beb491f7738..6106dff7bdc 100644 --- a/javascript/extractor/tests/es2015/output/trap/delegating_yield.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/delegating_yield.js.trap @@ -1,7 +1,7 @@ #10000=@"/delegating_yield.js;sourcefile" -files(#10000,"/delegating_yield.js","delegating_yield","js",0) +files(#10000,"/delegating_yield.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/destructuring.js.trap b/javascript/extractor/tests/es2015/output/trap/destructuring.js.trap index 4021fd51b95..6f4bc769f19 100644 --- a/javascript/extractor/tests/es2015/output/trap/destructuring.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/destructuring.js.trap @@ -1,7 +1,7 @@ #10000=@"/destructuring.js;sourcefile" -files(#10000,"/destructuring.js","destructuring","js",0) +files(#10000,"/destructuring.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/export1.js.trap b/javascript/extractor/tests/es2015/output/trap/export1.js.trap index cf5eb993956..c1a7da9c4f4 100644 --- a/javascript/extractor/tests/es2015/output/trap/export1.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/export1.js.trap @@ -1,7 +1,7 @@ #10000=@"/export1.js;sourcefile" -files(#10000,"/export1.js","export1","js",0) +files(#10000,"/export1.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/export10.js.trap b/javascript/extractor/tests/es2015/output/trap/export10.js.trap index 38eb62634e4..518cb55c45c 100644 --- a/javascript/extractor/tests/es2015/output/trap/export10.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/export10.js.trap @@ -1,7 +1,7 @@ #10000=@"/export10.js;sourcefile" -files(#10000,"/export10.js","export10","js",0) +files(#10000,"/export10.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/export11.js.trap b/javascript/extractor/tests/es2015/output/trap/export11.js.trap index 05d580a2cdc..57c45f044a1 100644 --- a/javascript/extractor/tests/es2015/output/trap/export11.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/export11.js.trap @@ -1,7 +1,7 @@ #10000=@"/export11.js;sourcefile" -files(#10000,"/export11.js","export11","js",0) +files(#10000,"/export11.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/export2.js.trap b/javascript/extractor/tests/es2015/output/trap/export2.js.trap index 90c95bae4d0..27a07ed5c9e 100644 --- a/javascript/extractor/tests/es2015/output/trap/export2.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/export2.js.trap @@ -1,7 +1,7 @@ #10000=@"/export2.js;sourcefile" -files(#10000,"/export2.js","export2","js",0) +files(#10000,"/export2.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/export3.js.trap b/javascript/extractor/tests/es2015/output/trap/export3.js.trap index 01d09fe4d99..df259c34824 100644 --- a/javascript/extractor/tests/es2015/output/trap/export3.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/export3.js.trap @@ -1,7 +1,7 @@ #10000=@"/export3.js;sourcefile" -files(#10000,"/export3.js","export3","js",0) +files(#10000,"/export3.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/export4.js.trap b/javascript/extractor/tests/es2015/output/trap/export4.js.trap index ef826aaaf27..50a6952b59e 100644 --- a/javascript/extractor/tests/es2015/output/trap/export4.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/export4.js.trap @@ -1,7 +1,7 @@ #10000=@"/export4.js;sourcefile" -files(#10000,"/export4.js","export4","js",0) +files(#10000,"/export4.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/export5.js.trap b/javascript/extractor/tests/es2015/output/trap/export5.js.trap index 91989e69a7c..861ea6d12c1 100644 --- a/javascript/extractor/tests/es2015/output/trap/export5.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/export5.js.trap @@ -1,7 +1,7 @@ #10000=@"/export5.js;sourcefile" -files(#10000,"/export5.js","export5","js",0) +files(#10000,"/export5.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/export6.js.trap b/javascript/extractor/tests/es2015/output/trap/export6.js.trap index 9084fcda400..58381bfa820 100644 --- a/javascript/extractor/tests/es2015/output/trap/export6.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/export6.js.trap @@ -1,7 +1,7 @@ #10000=@"/export6.js;sourcefile" -files(#10000,"/export6.js","export6","js",0) +files(#10000,"/export6.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/export7.js.trap b/javascript/extractor/tests/es2015/output/trap/export7.js.trap index 5fe587f6dac..37370b5d502 100644 --- a/javascript/extractor/tests/es2015/output/trap/export7.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/export7.js.trap @@ -1,7 +1,7 @@ #10000=@"/export7.js;sourcefile" -files(#10000,"/export7.js","export7","js",0) +files(#10000,"/export7.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/export8.js.trap b/javascript/extractor/tests/es2015/output/trap/export8.js.trap index 6a38455df42..d79edbb8826 100644 --- a/javascript/extractor/tests/es2015/output/trap/export8.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/export8.js.trap @@ -1,7 +1,7 @@ #10000=@"/export8.js;sourcefile" -files(#10000,"/export8.js","export8","js",0) +files(#10000,"/export8.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/export9.js.trap b/javascript/extractor/tests/es2015/output/trap/export9.js.trap index 538bff491c5..7bfdace6530 100644 --- a/javascript/extractor/tests/es2015/output/trap/export9.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/export9.js.trap @@ -1,7 +1,7 @@ #10000=@"/export9.js;sourcefile" -files(#10000,"/export9.js","export9","js",0) +files(#10000,"/export9.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/forof.js.trap b/javascript/extractor/tests/es2015/output/trap/forof.js.trap index f0e1ea6a103..12ea8980cab 100644 --- a/javascript/extractor/tests/es2015/output/trap/forof.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/forof.js.trap @@ -1,7 +1,7 @@ #10000=@"/forof.js;sourcefile" -files(#10000,"/forof.js","forof","js",0) +files(#10000,"/forof.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/import1.js.trap b/javascript/extractor/tests/es2015/output/trap/import1.js.trap index 7be30f7c51b..b02b3375bba 100644 --- a/javascript/extractor/tests/es2015/output/trap/import1.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/import1.js.trap @@ -1,7 +1,7 @@ #10000=@"/import1.js;sourcefile" -files(#10000,"/import1.js","import1","js",0) +files(#10000,"/import1.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/import2.js.trap b/javascript/extractor/tests/es2015/output/trap/import2.js.trap index 2f0d9245d97..360b201cdc8 100644 --- a/javascript/extractor/tests/es2015/output/trap/import2.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/import2.js.trap @@ -1,7 +1,7 @@ #10000=@"/import2.js;sourcefile" -files(#10000,"/import2.js","import2","js",0) +files(#10000,"/import2.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/import3.js.trap b/javascript/extractor/tests/es2015/output/trap/import3.js.trap index c072fb40b7d..5d2c1a7c676 100644 --- a/javascript/extractor/tests/es2015/output/trap/import3.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/import3.js.trap @@ -1,7 +1,7 @@ #10000=@"/import3.js;sourcefile" -files(#10000,"/import3.js","import3","js",0) +files(#10000,"/import3.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/import4.js.trap b/javascript/extractor/tests/es2015/output/trap/import4.js.trap index 388e12fdef2..3d0694f2e03 100644 --- a/javascript/extractor/tests/es2015/output/trap/import4.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/import4.js.trap @@ -1,7 +1,7 @@ #10000=@"/import4.js;sourcefile" -files(#10000,"/import4.js","import4","js",0) +files(#10000,"/import4.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/import5.js.trap b/javascript/extractor/tests/es2015/output/trap/import5.js.trap index f4acf84ddfa..a410731eff4 100644 --- a/javascript/extractor/tests/es2015/output/trap/import5.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/import5.js.trap @@ -1,7 +1,7 @@ #10000=@"/import5.js;sourcefile" -files(#10000,"/import5.js","import5","js",0) +files(#10000,"/import5.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/import6.js.trap b/javascript/extractor/tests/es2015/output/trap/import6.js.trap index 40ae625b9f9..429035fa6ed 100644 --- a/javascript/extractor/tests/es2015/output/trap/import6.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/import6.js.trap @@ -1,7 +1,7 @@ #10000=@"/import6.js;sourcefile" -files(#10000,"/import6.js","import6","js",0) +files(#10000,"/import6.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/import7.js.trap b/javascript/extractor/tests/es2015/output/trap/import7.js.trap index c5174514a8f..315afa6d01b 100644 --- a/javascript/extractor/tests/es2015/output/trap/import7.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/import7.js.trap @@ -1,7 +1,7 @@ #10000=@"/import7.js;sourcefile" -files(#10000,"/import7.js","import7","js",0) +files(#10000,"/import7.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/let.js.trap b/javascript/extractor/tests/es2015/output/trap/let.js.trap index 674da07ba56..d02c8e0bd8d 100644 --- a/javascript/extractor/tests/es2015/output/trap/let.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/let.js.trap @@ -1,7 +1,7 @@ #10000=@"/let.js;sourcefile" -files(#10000,"/let.js","let","js",0) +files(#10000,"/let.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/let2.js.trap b/javascript/extractor/tests/es2015/output/trap/let2.js.trap index e04ee0bfa8a..a05cddac410 100644 --- a/javascript/extractor/tests/es2015/output/trap/let2.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/let2.js.trap @@ -1,7 +1,7 @@ #10000=@"/let2.js;sourcefile" -files(#10000,"/let2.js","let2","js",0) +files(#10000,"/let2.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/nested_import.js.trap b/javascript/extractor/tests/es2015/output/trap/nested_import.js.trap index f60d33bd0c9..8542482671d 100644 --- a/javascript/extractor/tests/es2015/output/trap/nested_import.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/nested_import.js.trap @@ -1,7 +1,7 @@ #10000=@"/nested_import.js;sourcefile" -files(#10000,"/nested_import.js","nested_import","js",0) +files(#10000,"/nested_import.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/new_target.js.trap b/javascript/extractor/tests/es2015/output/trap/new_target.js.trap index d716cf44fdb..4635fe2e09c 100644 --- a/javascript/extractor/tests/es2015/output/trap/new_target.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/new_target.js.trap @@ -1,7 +1,7 @@ #10000=@"/new_target.js;sourcefile" -files(#10000,"/new_target.js","new_target","js",0) +files(#10000,"/new_target.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/no-substitution.js.trap b/javascript/extractor/tests/es2015/output/trap/no-substitution.js.trap index 5f56469bb45..b7c9df13a7f 100644 --- a/javascript/extractor/tests/es2015/output/trap/no-substitution.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/no-substitution.js.trap @@ -1,7 +1,7 @@ #10000=@"/no-substitution.js;sourcefile" -files(#10000,"/no-substitution.js","no-substitution","js",0) +files(#10000,"/no-substitution.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/nullMethodName.js.trap b/javascript/extractor/tests/es2015/output/trap/nullMethodName.js.trap index 6988ef14232..21547848299 100644 --- a/javascript/extractor/tests/es2015/output/trap/nullMethodName.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/nullMethodName.js.trap @@ -1,7 +1,7 @@ #10000=@"/nullMethodName.js;sourcefile" -files(#10000,"/nullMethodName.js","nullMethodName","js",0) +files(#10000,"/nullMethodName.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/odasa-2593.js.trap b/javascript/extractor/tests/es2015/output/trap/odasa-2593.js.trap index 3e46083ca86..23711b8d6e3 100644 --- a/javascript/extractor/tests/es2015/output/trap/odasa-2593.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/odasa-2593.js.trap @@ -1,7 +1,7 @@ #10000=@"/odasa-2593.js;sourcefile" -files(#10000,"/odasa-2593.js","odasa-2593","js",0) +files(#10000,"/odasa-2593.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/properties.js.trap b/javascript/extractor/tests/es2015/output/trap/properties.js.trap index ab37310808a..bcc637655b3 100644 --- a/javascript/extractor/tests/es2015/output/trap/properties.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/properties.js.trap @@ -1,7 +1,7 @@ #10000=@"/properties.js;sourcefile" -files(#10000,"/properties.js","properties","js",0) +files(#10000,"/properties.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/property_pattern_with_default.js.trap b/javascript/extractor/tests/es2015/output/trap/property_pattern_with_default.js.trap index ce82f7c7e51..2cc1015094f 100644 --- a/javascript/extractor/tests/es2015/output/trap/property_pattern_with_default.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/property_pattern_with_default.js.trap @@ -1,7 +1,7 @@ #10000=@"/property_pattern_with_default.js;sourcefile" -files(#10000,"/property_pattern_with_default.js","property_pattern_with_default","js",0) +files(#10000,"/property_pattern_with_default.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/restparms.js.trap b/javascript/extractor/tests/es2015/output/trap/restparms.js.trap index 8a848b74cd7..627aaa15bcb 100644 --- a/javascript/extractor/tests/es2015/output/trap/restparms.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/restparms.js.trap @@ -1,7 +1,7 @@ #10000=@"/restparms.js;sourcefile" -files(#10000,"/restparms.js","restparms","js",0) +files(#10000,"/restparms.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/restparms2.js.trap b/javascript/extractor/tests/es2015/output/trap/restparms2.js.trap index d1ace3d0446..e6faa776dd5 100644 --- a/javascript/extractor/tests/es2015/output/trap/restparms2.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/restparms2.js.trap @@ -1,7 +1,7 @@ #10000=@"/restparms2.js;sourcefile" -files(#10000,"/restparms2.js","restparms2","js",0) +files(#10000,"/restparms2.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/spreadelement.js.trap b/javascript/extractor/tests/es2015/output/trap/spreadelement.js.trap index 05311f206ff..8c5c7723280 100644 --- a/javascript/extractor/tests/es2015/output/trap/spreadelement.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/spreadelement.js.trap @@ -1,7 +1,7 @@ #10000=@"/spreadelement.js;sourcefile" -files(#10000,"/spreadelement.js","spreadelement","js",0) +files(#10000,"/spreadelement.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/super_call.js.trap b/javascript/extractor/tests/es2015/output/trap/super_call.js.trap index 3580b430c07..e92324e4b75 100644 --- a/javascript/extractor/tests/es2015/output/trap/super_call.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/super_call.js.trap @@ -1,7 +1,7 @@ #10000=@"/super_call.js;sourcefile" -files(#10000,"/super_call.js","super_call","js",0) +files(#10000,"/super_call.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/super_ctor.js.trap b/javascript/extractor/tests/es2015/output/trap/super_ctor.js.trap index c4cdbb2b941..e96ad048d60 100644 --- a/javascript/extractor/tests/es2015/output/trap/super_ctor.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/super_ctor.js.trap @@ -1,7 +1,7 @@ #10000=@"/super_ctor.js;sourcefile" -files(#10000,"/super_ctor.js","super_ctor","js",0) +files(#10000,"/super_ctor.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/templates.js.trap b/javascript/extractor/tests/es2015/output/trap/templates.js.trap index 9926e3c42cd..452ac61c6f5 100644 --- a/javascript/extractor/tests/es2015/output/trap/templates.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/templates.js.trap @@ -1,7 +1,7 @@ #10000=@"/templates.js;sourcefile" -files(#10000,"/templates.js","templates","js",0) +files(#10000,"/templates.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/unknown_meta_property.js.trap b/javascript/extractor/tests/es2015/output/trap/unknown_meta_property.js.trap index abaddc6dba2..7599d6eb87e 100644 --- a/javascript/extractor/tests/es2015/output/trap/unknown_meta_property.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/unknown_meta_property.js.trap @@ -1,7 +1,7 @@ #10000=@"/unknown_meta_property.js;sourcefile" -files(#10000,"/unknown_meta_property.js","unknown_meta_property","js",0) +files(#10000,"/unknown_meta_property.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/yield.js.trap b/javascript/extractor/tests/es2015/output/trap/yield.js.trap index 569bd957de7..6ebac9325d2 100644 --- a/javascript/extractor/tests/es2015/output/trap/yield.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/yield.js.trap @@ -1,7 +1,7 @@ #10000=@"/yield.js;sourcefile" -files(#10000,"/yield.js","yield","js",0) +files(#10000,"/yield.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2015/output/trap/yield2.js.trap b/javascript/extractor/tests/es2015/output/trap/yield2.js.trap index 6316227a2e3..70a3c2464f1 100644 --- a/javascript/extractor/tests/es2015/output/trap/yield2.js.trap +++ b/javascript/extractor/tests/es2015/output/trap/yield2.js.trap @@ -1,7 +1,7 @@ #10000=@"/yield2.js;sourcefile" -files(#10000,"/yield2.js","yield2","js",0) +files(#10000,"/yield2.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2016/output/trap/exp.js.trap b/javascript/extractor/tests/es2016/output/trap/exp.js.trap index ff512e1fd2a..c5103a7932f 100644 --- a/javascript/extractor/tests/es2016/output/trap/exp.js.trap +++ b/javascript/extractor/tests/es2016/output/trap/exp.js.trap @@ -1,7 +1,7 @@ #10000=@"/exp.js;sourcefile" -files(#10000,"/exp.js","exp","js",0) +files(#10000,"/exp.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2016/output/trap/usestrict.js.trap b/javascript/extractor/tests/es2016/output/trap/usestrict.js.trap index 77c7f003cd4..a1e1b27cd25 100644 --- a/javascript/extractor/tests/es2016/output/trap/usestrict.js.trap +++ b/javascript/extractor/tests/es2016/output/trap/usestrict.js.trap @@ -1,7 +1,7 @@ #10000=@"/usestrict.js;sourcefile" -files(#10000,"/usestrict.js","usestrict","js",0) +files(#10000,"/usestrict.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2017/output/trap/async-await.js.trap b/javascript/extractor/tests/es2017/output/trap/async-await.js.trap index cd79c3985ef..6330dce7940 100644 --- a/javascript/extractor/tests/es2017/output/trap/async-await.js.trap +++ b/javascript/extractor/tests/es2017/output/trap/async-await.js.trap @@ -1,7 +1,7 @@ #10000=@"/async-await.js;sourcefile" -files(#10000,"/async-await.js","async-await","js",0) +files(#10000,"/async-await.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2017/output/trap/export-async-1.js.trap b/javascript/extractor/tests/es2017/output/trap/export-async-1.js.trap index 86da62095d0..62404dcc656 100644 --- a/javascript/extractor/tests/es2017/output/trap/export-async-1.js.trap +++ b/javascript/extractor/tests/es2017/output/trap/export-async-1.js.trap @@ -1,7 +1,7 @@ #10000=@"/export-async-1.js;sourcefile" -files(#10000,"/export-async-1.js","export-async-1","js",0) +files(#10000,"/export-async-1.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2017/output/trap/export-async-2.js.trap b/javascript/extractor/tests/es2017/output/trap/export-async-2.js.trap index d13cc444d29..1fb2e0a1419 100644 --- a/javascript/extractor/tests/es2017/output/trap/export-async-2.js.trap +++ b/javascript/extractor/tests/es2017/output/trap/export-async-2.js.trap @@ -1,7 +1,7 @@ #10000=@"/export-async-2.js;sourcefile" -files(#10000,"/export-async-2.js","export-async-2","js",0) +files(#10000,"/export-async-2.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2017/output/trap/invalid-async-fn.js.trap b/javascript/extractor/tests/es2017/output/trap/invalid-async-fn.js.trap index 03b1c5fb16c..9572541ae8d 100644 --- a/javascript/extractor/tests/es2017/output/trap/invalid-async-fn.js.trap +++ b/javascript/extractor/tests/es2017/output/trap/invalid-async-fn.js.trap @@ -1,7 +1,7 @@ #10000=@"/invalid-async-fn.js;sourcefile" -files(#10000,"/invalid-async-fn.js","invalid-async-fn","js",0) +files(#10000,"/invalid-async-fn.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2017/output/trap/shorthand-prop-async.js.trap b/javascript/extractor/tests/es2017/output/trap/shorthand-prop-async.js.trap index c70e37f425d..1c62daca205 100644 --- a/javascript/extractor/tests/es2017/output/trap/shorthand-prop-async.js.trap +++ b/javascript/extractor/tests/es2017/output/trap/shorthand-prop-async.js.trap @@ -1,7 +1,7 @@ #10000=@"/shorthand-prop-async.js;sourcefile" -files(#10000,"/shorthand-prop-async.js","shorthand-prop-async","js",0) +files(#10000,"/shorthand-prop-async.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2018/output/trap/asyncIter.js.trap b/javascript/extractor/tests/es2018/output/trap/asyncIter.js.trap index cd9b4fbd27e..dcb18552587 100644 --- a/javascript/extractor/tests/es2018/output/trap/asyncIter.js.trap +++ b/javascript/extractor/tests/es2018/output/trap/asyncIter.js.trap @@ -1,7 +1,7 @@ #10000=@"/asyncIter.js;sourcefile" -files(#10000,"/asyncIter.js","asyncIter","js",0) +files(#10000,"/asyncIter.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2018/output/trap/templates.js.trap b/javascript/extractor/tests/es2018/output/trap/templates.js.trap index e9fefd43ae1..5f5ef870acd 100644 --- a/javascript/extractor/tests/es2018/output/trap/templates.js.trap +++ b/javascript/extractor/tests/es2018/output/trap/templates.js.trap @@ -1,7 +1,7 @@ #10000=@"/templates.js;sourcefile" -files(#10000,"/templates.js","templates","js",0) +files(#10000,"/templates.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2019/output/trap/json-superset.js.trap b/javascript/extractor/tests/es2019/output/trap/json-superset.js.trap index 8b3fdb48e3f..afc0749206a 100644 --- a/javascript/extractor/tests/es2019/output/trap/json-superset.js.trap +++ b/javascript/extractor/tests/es2019/output/trap/json-superset.js.trap @@ -1,7 +1,7 @@ #10000=@"/json-superset.js;sourcefile" -files(#10000,"/json-superset.js","json-superset","js",0) +files(#10000,"/json-superset.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2021/output/trap/assign.js.trap b/javascript/extractor/tests/es2021/output/trap/assign.js.trap index f844eb1ccfb..d0aaa18558b 100644 --- a/javascript/extractor/tests/es2021/output/trap/assign.js.trap +++ b/javascript/extractor/tests/es2021/output/trap/assign.js.trap @@ -1,7 +1,7 @@ #10000=@"/assign.js;sourcefile" -files(#10000,"/assign.js","assign","js",0) +files(#10000,"/assign.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/es2021/output/trap/numeric.js.trap b/javascript/extractor/tests/es2021/output/trap/numeric.js.trap index afcf1627f2d..f6f86e94853 100644 --- a/javascript/extractor/tests/es2021/output/trap/numeric.js.trap +++ b/javascript/extractor/tests/es2021/output/trap/numeric.js.trap @@ -1,7 +1,7 @@ #10000=@"/numeric.js;sourcefile" -files(#10000,"/numeric.js","numeric","js",0) +files(#10000,"/numeric.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/esnext/output/trap/async-generators.js.trap b/javascript/extractor/tests/esnext/output/trap/async-generators.js.trap index 67f29efe9f8..058ac988fac 100644 --- a/javascript/extractor/tests/esnext/output/trap/async-generators.js.trap +++ b/javascript/extractor/tests/esnext/output/trap/async-generators.js.trap @@ -1,7 +1,7 @@ #10000=@"/async-generators.js;sourcefile" -files(#10000,"/async-generators.js","async-generators","js",0) +files(#10000,"/async-generators.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/esnext/output/trap/catchGuardAndNoBinding.js.trap b/javascript/extractor/tests/esnext/output/trap/catchGuardAndNoBinding.js.trap index 664211c9a42..49ae2b30eb0 100644 --- a/javascript/extractor/tests/esnext/output/trap/catchGuardAndNoBinding.js.trap +++ b/javascript/extractor/tests/esnext/output/trap/catchGuardAndNoBinding.js.trap @@ -1,7 +1,7 @@ #10000=@"/catchGuardAndNoBinding.js;sourcefile" -files(#10000,"/catchGuardAndNoBinding.js","catchGuardAndNoBinding","js",0) +files(#10000,"/catchGuardAndNoBinding.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/esnext/output/trap/catchNoBinding.js.trap b/javascript/extractor/tests/esnext/output/trap/catchNoBinding.js.trap index 67df355b2bc..aa264fa302a 100644 --- a/javascript/extractor/tests/esnext/output/trap/catchNoBinding.js.trap +++ b/javascript/extractor/tests/esnext/output/trap/catchNoBinding.js.trap @@ -1,7 +1,7 @@ #10000=@"/catchNoBinding.js;sourcefile" -files(#10000,"/catchNoBinding.js","catchNoBinding","js",0) +files(#10000,"/catchNoBinding.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/esnext/output/trap/dynamic-import.js.trap b/javascript/extractor/tests/esnext/output/trap/dynamic-import.js.trap index a4028832386..5e5b460a756 100644 --- a/javascript/extractor/tests/esnext/output/trap/dynamic-import.js.trap +++ b/javascript/extractor/tests/esnext/output/trap/dynamic-import.js.trap @@ -1,7 +1,7 @@ #10000=@"/dynamic-import.js;sourcefile" -files(#10000,"/dynamic-import.js","dynamic-import","js",0) +files(#10000,"/dynamic-import.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/esnext/output/trap/fields.js.trap b/javascript/extractor/tests/esnext/output/trap/fields.js.trap index 7245dcb37d6..f73fd5fa6ba 100644 --- a/javascript/extractor/tests/esnext/output/trap/fields.js.trap +++ b/javascript/extractor/tests/esnext/output/trap/fields.js.trap @@ -1,7 +1,7 @@ #10000=@"/fields.js;sourcefile" -files(#10000,"/fields.js","fields","js",0) +files(#10000,"/fields.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/esnext/output/trap/nullish-coalescing.js.trap b/javascript/extractor/tests/esnext/output/trap/nullish-coalescing.js.trap index 1e8793de0a1..234c05a9446 100644 --- a/javascript/extractor/tests/esnext/output/trap/nullish-coalescing.js.trap +++ b/javascript/extractor/tests/esnext/output/trap/nullish-coalescing.js.trap @@ -1,7 +1,7 @@ #10000=@"/nullish-coalescing.js;sourcefile" -files(#10000,"/nullish-coalescing.js","nullish-coalescing","js",0) +files(#10000,"/nullish-coalescing.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/esnext/output/trap/optional-chaining.js.trap b/javascript/extractor/tests/esnext/output/trap/optional-chaining.js.trap index 9f38ea14f81..fb44a997170 100644 --- a/javascript/extractor/tests/esnext/output/trap/optional-chaining.js.trap +++ b/javascript/extractor/tests/esnext/output/trap/optional-chaining.js.trap @@ -1,7 +1,7 @@ #10000=@"/optional-chaining.js;sourcefile" -files(#10000,"/optional-chaining.js","optional-chaining","js",0) +files(#10000,"/optional-chaining.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad1.js.trap b/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad1.js.trap index 5e4dc3945c1..d3853a902e4 100644 --- a/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad1.js.trap +++ b/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad1.js.trap @@ -1,7 +1,7 @@ #10000=@"/optional-chaining_bad1.js;sourcefile" -files(#10000,"/optional-chaining_bad1.js","optional-chaining_bad1","js",0) +files(#10000,"/optional-chaining_bad1.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad2.js.trap b/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad2.js.trap index 49cf106dca3..e0a8491e8cf 100644 --- a/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad2.js.trap +++ b/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad2.js.trap @@ -1,7 +1,7 @@ #10000=@"/optional-chaining_bad2.js;sourcefile" -files(#10000,"/optional-chaining_bad2.js","optional-chaining_bad2","js",0) +files(#10000,"/optional-chaining_bad2.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad3.js.trap b/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad3.js.trap index b697e0f4da1..d0eaaadb172 100644 --- a/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad3.js.trap +++ b/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad3.js.trap @@ -1,7 +1,7 @@ #10000=@"/optional-chaining_bad3.js;sourcefile" -files(#10000,"/optional-chaining_bad3.js","optional-chaining_bad3","js",0) +files(#10000,"/optional-chaining_bad3.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad4.js.trap b/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad4.js.trap index 05a06c72b23..a046c8a9c92 100644 --- a/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad4.js.trap +++ b/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad4.js.trap @@ -1,7 +1,7 @@ #10000=@"/optional-chaining_bad4.js;sourcefile" -files(#10000,"/optional-chaining_bad4.js","optional-chaining_bad4","js",0) +files(#10000,"/optional-chaining_bad4.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad5.js.trap b/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad5.js.trap index 6e5c528aa5f..3605fa2dc73 100644 --- a/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad5.js.trap +++ b/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad5.js.trap @@ -1,7 +1,7 @@ #10000=@"/optional-chaining_bad5.js;sourcefile" -files(#10000,"/optional-chaining_bad5.js","optional-chaining_bad5","js",0) +files(#10000,"/optional-chaining_bad5.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad6.js.trap b/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad6.js.trap index cb078002809..34c257b9bcd 100644 --- a/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad6.js.trap +++ b/javascript/extractor/tests/esnext/output/trap/optional-chaining_bad6.js.trap @@ -1,7 +1,7 @@ #10000=@"/optional-chaining_bad6.js;sourcefile" -files(#10000,"/optional-chaining_bad6.js","optional-chaining_bad6","js",0) +files(#10000,"/optional-chaining_bad6.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/esnext/output/trap/optional-chaining_short-circuiting.js.trap b/javascript/extractor/tests/esnext/output/trap/optional-chaining_short-circuiting.js.trap index e253ec8fa5f..1ae6f531362 100644 --- a/javascript/extractor/tests/esnext/output/trap/optional-chaining_short-circuiting.js.trap +++ b/javascript/extractor/tests/esnext/output/trap/optional-chaining_short-circuiting.js.trap @@ -1,7 +1,7 @@ #10000=@"/optional-chaining_short-circuiting.js;sourcefile" -files(#10000,"/optional-chaining_short-circuiting.js","optional-chaining_short-circuiting","js",0) +files(#10000,"/optional-chaining_short-circuiting.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/esnext/output/trap/top-level-await.js.trap b/javascript/extractor/tests/esnext/output/trap/top-level-await.js.trap index 98d5bd56131..1b436f9a6b8 100644 --- a/javascript/extractor/tests/esnext/output/trap/top-level-await.js.trap +++ b/javascript/extractor/tests/esnext/output/trap/top-level-await.js.trap @@ -1,7 +1,7 @@ #10000=@"/top-level-await.js;sourcefile" -files(#10000,"/top-level-await.js","top-level-await","js",0) +files(#10000,"/top-level-await.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/esnext/output/trap/yield-import.js.trap b/javascript/extractor/tests/esnext/output/trap/yield-import.js.trap index c25e397bc29..4f2b6485042 100644 --- a/javascript/extractor/tests/esnext/output/trap/yield-import.js.trap +++ b/javascript/extractor/tests/esnext/output/trap/yield-import.js.trap @@ -1,7 +1,7 @@ #10000=@"/yield-import.js;sourcefile" -files(#10000,"/yield-import.js","yield-import","js",0) +files(#10000,"/yield-import.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/exprs/output/trap/assignment.js.trap b/javascript/extractor/tests/exprs/output/trap/assignment.js.trap index 895731068cc..42df8f6fe5b 100644 --- a/javascript/extractor/tests/exprs/output/trap/assignment.js.trap +++ b/javascript/extractor/tests/exprs/output/trap/assignment.js.trap @@ -1,7 +1,7 @@ #10000=@"/assignment.js;sourcefile" -files(#10000,"/assignment.js","assignment","js",0) +files(#10000,"/assignment.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/exprs/output/trap/binary.js.trap b/javascript/extractor/tests/exprs/output/trap/binary.js.trap index 49b7a4461e4..0b29d03b73a 100644 --- a/javascript/extractor/tests/exprs/output/trap/binary.js.trap +++ b/javascript/extractor/tests/exprs/output/trap/binary.js.trap @@ -1,7 +1,7 @@ #10000=@"/binary.js;sourcefile" -files(#10000,"/binary.js","binary","js",0) +files(#10000,"/binary.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/exprs/output/trap/comparison.js.trap b/javascript/extractor/tests/exprs/output/trap/comparison.js.trap index c2ab0c3958f..40cd1291c1d 100644 --- a/javascript/extractor/tests/exprs/output/trap/comparison.js.trap +++ b/javascript/extractor/tests/exprs/output/trap/comparison.js.trap @@ -1,7 +1,7 @@ #10000=@"/comparison.js;sourcefile" -files(#10000,"/comparison.js","comparison","js",0) +files(#10000,"/comparison.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/exprs/output/trap/fnnesting.js.trap b/javascript/extractor/tests/exprs/output/trap/fnnesting.js.trap index 98fc3347002..c2b52eb4df8 100644 --- a/javascript/extractor/tests/exprs/output/trap/fnnesting.js.trap +++ b/javascript/extractor/tests/exprs/output/trap/fnnesting.js.trap @@ -1,7 +1,7 @@ #10000=@"/fnnesting.js;sourcefile" -files(#10000,"/fnnesting.js","fnnesting","js",0) +files(#10000,"/fnnesting.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/exprs/output/trap/others.js.trap b/javascript/extractor/tests/exprs/output/trap/others.js.trap index 80173fba1fe..5fc397235e8 100644 --- a/javascript/extractor/tests/exprs/output/trap/others.js.trap +++ b/javascript/extractor/tests/exprs/output/trap/others.js.trap @@ -1,7 +1,7 @@ #10000=@"/others.js;sourcefile" -files(#10000,"/others.js","others","js",0) +files(#10000,"/others.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/exprs/output/trap/parens.js.trap b/javascript/extractor/tests/exprs/output/trap/parens.js.trap index 06dc43f1d79..8b8d9b592ba 100644 --- a/javascript/extractor/tests/exprs/output/trap/parens.js.trap +++ b/javascript/extractor/tests/exprs/output/trap/parens.js.trap @@ -1,7 +1,7 @@ #10000=@"/parens.js;sourcefile" -files(#10000,"/parens.js","parens","js",0) +files(#10000,"/parens.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/exprs/output/trap/primaries.js.trap b/javascript/extractor/tests/exprs/output/trap/primaries.js.trap index 6c3d10a84f9..034ff1c98c0 100644 --- a/javascript/extractor/tests/exprs/output/trap/primaries.js.trap +++ b/javascript/extractor/tests/exprs/output/trap/primaries.js.trap @@ -1,7 +1,7 @@ #10000=@"/primaries.js;sourcefile" -files(#10000,"/primaries.js","primaries","js",0) +files(#10000,"/primaries.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/exprs/output/trap/regexp.js.trap b/javascript/extractor/tests/exprs/output/trap/regexp.js.trap index 854393c7bfd..3b58a28545b 100644 --- a/javascript/extractor/tests/exprs/output/trap/regexp.js.trap +++ b/javascript/extractor/tests/exprs/output/trap/regexp.js.trap @@ -1,7 +1,7 @@ #10000=@"/regexp.js;sourcefile" -files(#10000,"/regexp.js","regexp","js",0) +files(#10000,"/regexp.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/exprs/output/trap/unary.js.trap b/javascript/extractor/tests/exprs/output/trap/unary.js.trap index 06529bd4e21..aca29eb7033 100644 --- a/javascript/extractor/tests/exprs/output/trap/unary.js.trap +++ b/javascript/extractor/tests/exprs/output/trap/unary.js.trap @@ -1,7 +1,7 @@ #10000=@"/unary.js;sourcefile" -files(#10000,"/unary.js","unary","js",0) +files(#10000,"/unary.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/exprs/output/trap/update.js.trap b/javascript/extractor/tests/exprs/output/trap/update.js.trap index ae4dc55d514..dba8253323f 100644 --- a/javascript/extractor/tests/exprs/output/trap/update.js.trap +++ b/javascript/extractor/tests/exprs/output/trap/update.js.trap @@ -1,7 +1,7 @@ #10000=@"/update.js;sourcefile" -files(#10000,"/update.js","update","js",0) +files(#10000,"/update.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/extensions/output/trap/tst.es6.trap b/javascript/extractor/tests/extensions/output/trap/tst.es6.trap index c8df5a4bbf8..1f8496da9b0 100644 --- a/javascript/extractor/tests/extensions/output/trap/tst.es6.trap +++ b/javascript/extractor/tests/extensions/output/trap/tst.es6.trap @@ -1,7 +1,7 @@ #10000=@"/tst.es6;sourcefile" -files(#10000,"/tst.es6","tst","es6",0) +files(#10000,"/tst.es6") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/extensions/output/trap/tst2.es.trap b/javascript/extractor/tests/extensions/output/trap/tst2.es.trap index 2241616144e..e07f93a1571 100644 --- a/javascript/extractor/tests/extensions/output/trap/tst2.es.trap +++ b/javascript/extractor/tests/extensions/output/trap/tst2.es.trap @@ -1,7 +1,7 @@ #10000=@"/tst2.es;sourcefile" -files(#10000,"/tst2.es","tst2","es",0) +files(#10000,"/tst2.es") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/extensions/output/trap/tst4.cjs.trap b/javascript/extractor/tests/extensions/output/trap/tst4.cjs.trap index 13a0a7225da..4323614bf4d 100644 --- a/javascript/extractor/tests/extensions/output/trap/tst4.cjs.trap +++ b/javascript/extractor/tests/extensions/output/trap/tst4.cjs.trap @@ -1,7 +1,7 @@ #10000=@"/tst4.cjs;sourcefile" -files(#10000,"/tst4.cjs","tst4","cjs",0) +files(#10000,"/tst4.cjs") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/externs/output/trap/Point.js.trap b/javascript/extractor/tests/externs/output/trap/Point.js.trap index 5d5cd7e9b76..d69c901ea89 100644 --- a/javascript/extractor/tests/externs/output/trap/Point.js.trap +++ b/javascript/extractor/tests/externs/output/trap/Point.js.trap @@ -1,7 +1,7 @@ #10000=@"/Point.js;sourcefile" -files(#10000,"/Point.js","Point","js",0) +files(#10000,"/Point.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/ambig.js.trap b/javascript/extractor/tests/flow/output/trap/ambig.js.trap index e340560e4a6..5c03f0309c2 100644 --- a/javascript/extractor/tests/flow/output/trap/ambig.js.trap +++ b/javascript/extractor/tests/flow/output/trap/ambig.js.trap @@ -1,7 +1,7 @@ #10000=@"/ambig.js;sourcefile" -files(#10000,"/ambig.js","ambig","js",0) +files(#10000,"/ambig.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/anonFunctionOptionalParm.js.trap b/javascript/extractor/tests/flow/output/trap/anonFunctionOptionalParm.js.trap index 3b9210e53da..8a5bb69f6ab 100644 --- a/javascript/extractor/tests/flow/output/trap/anonFunctionOptionalParm.js.trap +++ b/javascript/extractor/tests/flow/output/trap/anonFunctionOptionalParm.js.trap @@ -1,7 +1,7 @@ #10000=@"/anonFunctionOptionalParm.js;sourcefile" -files(#10000,"/anonFunctionOptionalParm.js","anonFunctionOptionalParm","js",0) +files(#10000,"/anonFunctionOptionalParm.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/anonFunctionReturnType.js.trap b/javascript/extractor/tests/flow/output/trap/anonFunctionReturnType.js.trap index b35eb8c87e3..6118bba7388 100644 --- a/javascript/extractor/tests/flow/output/trap/anonFunctionReturnType.js.trap +++ b/javascript/extractor/tests/flow/output/trap/anonFunctionReturnType.js.trap @@ -1,7 +1,7 @@ #10000=@"/anonFunctionReturnType.js;sourcefile" -files(#10000,"/anonFunctionReturnType.js","anonFunctionReturnType","js",0) +files(#10000,"/anonFunctionReturnType.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/anonFunctionWithoutParens.js.trap b/javascript/extractor/tests/flow/output/trap/anonFunctionWithoutParens.js.trap index 9134ec656db..999173d6a30 100644 --- a/javascript/extractor/tests/flow/output/trap/anonFunctionWithoutParens.js.trap +++ b/javascript/extractor/tests/flow/output/trap/anonFunctionWithoutParens.js.trap @@ -1,7 +1,7 @@ #10000=@"/anonFunctionWithoutParens.js;sourcefile" -files(#10000,"/anonFunctionWithoutParens.js","anonFunctionWithoutParens","js",0) +files(#10000,"/anonFunctionWithoutParens.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/anonIndexer.js.trap b/javascript/extractor/tests/flow/output/trap/anonIndexer.js.trap index 7299e6ff1fb..fbfaf50aaee 100644 --- a/javascript/extractor/tests/flow/output/trap/anonIndexer.js.trap +++ b/javascript/extractor/tests/flow/output/trap/anonIndexer.js.trap @@ -1,7 +1,7 @@ #10000=@"/anonIndexer.js;sourcefile" -files(#10000,"/anonIndexer.js","anonIndexer","js",0) +files(#10000,"/anonIndexer.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/array-types.js.trap b/javascript/extractor/tests/flow/output/trap/array-types.js.trap index cf3f193d686..de8a4aa77d9 100644 --- a/javascript/extractor/tests/flow/output/trap/array-types.js.trap +++ b/javascript/extractor/tests/flow/output/trap/array-types.js.trap @@ -1,7 +1,7 @@ #10000=@"/array-types.js;sourcefile" -files(#10000,"/array-types.js","array-types","js",0) +files(#10000,"/array-types.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/async.js.trap b/javascript/extractor/tests/flow/output/trap/async.js.trap index b53ba8247ff..c1a1fbdaa7f 100644 --- a/javascript/extractor/tests/flow/output/trap/async.js.trap +++ b/javascript/extractor/tests/flow/output/trap/async.js.trap @@ -1,7 +1,7 @@ #10000=@"/async.js;sourcefile" -files(#10000,"/async.js","async","js",0) +files(#10000,"/async.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/atAtIteratorProp.js.trap b/javascript/extractor/tests/flow/output/trap/atAtIteratorProp.js.trap index c735c3ae0eb..3e4fbaa2bec 100644 --- a/javascript/extractor/tests/flow/output/trap/atAtIteratorProp.js.trap +++ b/javascript/extractor/tests/flow/output/trap/atAtIteratorProp.js.trap @@ -1,7 +1,7 @@ #10000=@"/atAtIteratorProp.js;sourcefile" -files(#10000,"/atAtIteratorProp.js","atAtIteratorProp","js",0) +files(#10000,"/atAtIteratorProp.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/boundExplicitTypeParameters.js.trap b/javascript/extractor/tests/flow/output/trap/boundExplicitTypeParameters.js.trap index 64fd25704ad..b7a4873216a 100644 --- a/javascript/extractor/tests/flow/output/trap/boundExplicitTypeParameters.js.trap +++ b/javascript/extractor/tests/flow/output/trap/boundExplicitTypeParameters.js.trap @@ -1,7 +1,7 @@ #10000=@"/boundExplicitTypeParameters.js;sourcefile" -files(#10000,"/boundExplicitTypeParameters.js","boundExplicitTypeParameters","js",0) +files(#10000,"/boundExplicitTypeParameters.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/complexParamTypes.js.trap b/javascript/extractor/tests/flow/output/trap/complexParamTypes.js.trap index 9292cb46dbb..d6b8e03674e 100644 --- a/javascript/extractor/tests/flow/output/trap/complexParamTypes.js.trap +++ b/javascript/extractor/tests/flow/output/trap/complexParamTypes.js.trap @@ -1,7 +1,7 @@ #10000=@"/complexParamTypes.js;sourcefile" -files(#10000,"/complexParamTypes.js","complexParamTypes","js",0) +files(#10000,"/complexParamTypes.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/complexParamTypes2.js.trap b/javascript/extractor/tests/flow/output/trap/complexParamTypes2.js.trap index 9ba6f8f8f0f..e03ae461c44 100644 --- a/javascript/extractor/tests/flow/output/trap/complexParamTypes2.js.trap +++ b/javascript/extractor/tests/flow/output/trap/complexParamTypes2.js.trap @@ -1,7 +1,7 @@ #10000=@"/complexParamTypes2.js;sourcefile" -files(#10000,"/complexParamTypes2.js","complexParamTypes2","js",0) +files(#10000,"/complexParamTypes2.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/declareExport.js.trap b/javascript/extractor/tests/flow/output/trap/declareExport.js.trap index 9e34dd0ddfc..5a01cf475c0 100644 --- a/javascript/extractor/tests/flow/output/trap/declareExport.js.trap +++ b/javascript/extractor/tests/flow/output/trap/declareExport.js.trap @@ -1,7 +1,7 @@ #10000=@"/declareExport.js;sourcefile" -files(#10000,"/declareExport.js","declareExport","js",0) +files(#10000,"/declareExport.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/declareModuleExports.js.trap b/javascript/extractor/tests/flow/output/trap/declareModuleExports.js.trap index 2c92f20b158..b65fd64d976 100644 --- a/javascript/extractor/tests/flow/output/trap/declareModuleExports.js.trap +++ b/javascript/extractor/tests/flow/output/trap/declareModuleExports.js.trap @@ -1,7 +1,7 @@ #10000=@"/declareModuleExports.js;sourcefile" -files(#10000,"/declareModuleExports.js","declareModuleExports","js",0) +files(#10000,"/declareModuleExports.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/declared-module-imports.js.trap b/javascript/extractor/tests/flow/output/trap/declared-module-imports.js.trap index 8d9bc30f647..1eedda348e3 100644 --- a/javascript/extractor/tests/flow/output/trap/declared-module-imports.js.trap +++ b/javascript/extractor/tests/flow/output/trap/declared-module-imports.js.trap @@ -1,7 +1,7 @@ #10000=@"/declared-module-imports.js;sourcefile" -files(#10000,"/declared-module-imports.js","declared-module-imports","js",0) +files(#10000,"/declared-module-imports.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/explicitTypeParameters.js.trap b/javascript/extractor/tests/flow/output/trap/explicitTypeParameters.js.trap index 586f1dc3aa4..0d12524a168 100644 --- a/javascript/extractor/tests/flow/output/trap/explicitTypeParameters.js.trap +++ b/javascript/extractor/tests/flow/output/trap/explicitTypeParameters.js.trap @@ -1,7 +1,7 @@ #10000=@"/explicitTypeParameters.js;sourcefile" -files(#10000,"/explicitTypeParameters.js","explicitTypeParameters","js",0) +files(#10000,"/explicitTypeParameters.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/explicitTypeParametersForArgumentlessConstructorCall.js.trap b/javascript/extractor/tests/flow/output/trap/explicitTypeParametersForArgumentlessConstructorCall.js.trap index 550f69bf88a..e96f25d995b 100644 --- a/javascript/extractor/tests/flow/output/trap/explicitTypeParametersForArgumentlessConstructorCall.js.trap +++ b/javascript/extractor/tests/flow/output/trap/explicitTypeParametersForArgumentlessConstructorCall.js.trap @@ -1,7 +1,7 @@ #10000=@"/explicitTypeParametersForArgumentlessConstructorCall.js;sourcefile" -files(#10000,"/explicitTypeParametersForArgumentlessConstructorCall.js","explicitTypeParametersForArgumentlessConstructorCall","js",0) +files(#10000,"/explicitTypeParametersForArgumentlessConstructorCall.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/export.js.trap b/javascript/extractor/tests/flow/output/trap/export.js.trap index 0e4b9242e9f..94465ac5a54 100644 --- a/javascript/extractor/tests/flow/output/trap/export.js.trap +++ b/javascript/extractor/tests/flow/output/trap/export.js.trap @@ -1,7 +1,7 @@ #10000=@"/export.js;sourcefile" -files(#10000,"/export.js","export","js",0) +files(#10000,"/export.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/exportOpaqueType.js.trap b/javascript/extractor/tests/flow/output/trap/exportOpaqueType.js.trap index 1a1a943871a..5cdd7537e30 100644 --- a/javascript/extractor/tests/flow/output/trap/exportOpaqueType.js.trap +++ b/javascript/extractor/tests/flow/output/trap/exportOpaqueType.js.trap @@ -1,7 +1,7 @@ #10000=@"/exportOpaqueType.js;sourcefile" -files(#10000,"/exportOpaqueType.js","exportOpaqueType","js",0) +files(#10000,"/exportOpaqueType.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/get-set-methods.js.trap b/javascript/extractor/tests/flow/output/trap/get-set-methods.js.trap index c347c677bb6..1a55904a396 100644 --- a/javascript/extractor/tests/flow/output/trap/get-set-methods.js.trap +++ b/javascript/extractor/tests/flow/output/trap/get-set-methods.js.trap @@ -1,7 +1,7 @@ #10000=@"/get-set-methods.js;sourcefile" -files(#10000,"/get-set-methods.js","get-set-methods","js",0) +files(#10000,"/get-set-methods.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/importNonTypeInDeclaredModule.js.trap b/javascript/extractor/tests/flow/output/trap/importNonTypeInDeclaredModule.js.trap index 6d98783360f..24a6d896086 100644 --- a/javascript/extractor/tests/flow/output/trap/importNonTypeInDeclaredModule.js.trap +++ b/javascript/extractor/tests/flow/output/trap/importNonTypeInDeclaredModule.js.trap @@ -1,7 +1,7 @@ #10000=@"/importNonTypeInDeclaredModule.js;sourcefile" -files(#10000,"/importNonTypeInDeclaredModule.js","importNonTypeInDeclaredModule","js",0) +files(#10000,"/importNonTypeInDeclaredModule.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/importType.js.trap b/javascript/extractor/tests/flow/output/trap/importType.js.trap index d323164a8b0..9e2e2885049 100644 --- a/javascript/extractor/tests/flow/output/trap/importType.js.trap +++ b/javascript/extractor/tests/flow/output/trap/importType.js.trap @@ -1,7 +1,7 @@ #10000=@"/importType.js;sourcefile" -files(#10000,"/importType.js","importType","js",0) +files(#10000,"/importType.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/importTypeInDeclaredModule.js.trap b/javascript/extractor/tests/flow/output/trap/importTypeInDeclaredModule.js.trap index d7724bfaca2..188033df9a1 100644 --- a/javascript/extractor/tests/flow/output/trap/importTypeInDeclaredModule.js.trap +++ b/javascript/extractor/tests/flow/output/trap/importTypeInDeclaredModule.js.trap @@ -1,7 +1,7 @@ #10000=@"/importTypeInDeclaredModule.js;sourcefile" -files(#10000,"/importTypeInDeclaredModule.js","importTypeInDeclaredModule","js",0) +files(#10000,"/importTypeInDeclaredModule.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/methodTypeParams.js.trap b/javascript/extractor/tests/flow/output/trap/methodTypeParams.js.trap index 926ee570de2..9b4ae6666b5 100644 --- a/javascript/extractor/tests/flow/output/trap/methodTypeParams.js.trap +++ b/javascript/extractor/tests/flow/output/trap/methodTypeParams.js.trap @@ -1,7 +1,7 @@ #10000=@"/methodTypeParams.js;sourcefile" -files(#10000,"/methodTypeParams.js","methodTypeParams","js",0) +files(#10000,"/methodTypeParams.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/notExplicitTypeParameters1.js.trap b/javascript/extractor/tests/flow/output/trap/notExplicitTypeParameters1.js.trap index 8a148b8e75c..f7fd599eb4b 100644 --- a/javascript/extractor/tests/flow/output/trap/notExplicitTypeParameters1.js.trap +++ b/javascript/extractor/tests/flow/output/trap/notExplicitTypeParameters1.js.trap @@ -1,7 +1,7 @@ #10000=@"/notExplicitTypeParameters1.js;sourcefile" -files(#10000,"/notExplicitTypeParameters1.js","notExplicitTypeParameters1","js",0) +files(#10000,"/notExplicitTypeParameters1.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/notExplicitTypeParameters2.js.trap b/javascript/extractor/tests/flow/output/trap/notExplicitTypeParameters2.js.trap index 5880cdc6798..a7d9edcc6eb 100644 --- a/javascript/extractor/tests/flow/output/trap/notExplicitTypeParameters2.js.trap +++ b/javascript/extractor/tests/flow/output/trap/notExplicitTypeParameters2.js.trap @@ -1,7 +1,7 @@ #10000=@"/notExplicitTypeParameters2.js;sourcefile" -files(#10000,"/notExplicitTypeParameters2.js","notExplicitTypeParameters2","js",0) +files(#10000,"/notExplicitTypeParameters2.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/notExplicitTypeParameters3.js.trap b/javascript/extractor/tests/flow/output/trap/notExplicitTypeParameters3.js.trap index dd07d4d9711..0758eddced7 100644 --- a/javascript/extractor/tests/flow/output/trap/notExplicitTypeParameters3.js.trap +++ b/javascript/extractor/tests/flow/output/trap/notExplicitTypeParameters3.js.trap @@ -1,7 +1,7 @@ #10000=@"/notExplicitTypeParameters3.js;sourcefile" -files(#10000,"/notExplicitTypeParameters3.js","notExplicitTypeParameters3","js",0) +files(#10000,"/notExplicitTypeParameters3.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/objectTypeSpread.js.trap b/javascript/extractor/tests/flow/output/trap/objectTypeSpread.js.trap index f7c948b9ba8..b6bb522eb5d 100644 --- a/javascript/extractor/tests/flow/output/trap/objectTypeSpread.js.trap +++ b/javascript/extractor/tests/flow/output/trap/objectTypeSpread.js.trap @@ -1,7 +1,7 @@ #10000=@"/objectTypeSpread.js;sourcefile" -files(#10000,"/objectTypeSpread.js","objectTypeSpread","js",0) +files(#10000,"/objectTypeSpread.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/optParms.js.trap b/javascript/extractor/tests/flow/output/trap/optParms.js.trap index ea0f8c09d4e..44212bfc13e 100644 --- a/javascript/extractor/tests/flow/output/trap/optParms.js.trap +++ b/javascript/extractor/tests/flow/output/trap/optParms.js.trap @@ -1,7 +1,7 @@ #10000=@"/optParms.js;sourcefile" -files(#10000,"/optParms.js","optParms","js",0) +files(#10000,"/optParms.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/parmAnonFunctionType.js.trap b/javascript/extractor/tests/flow/output/trap/parmAnonFunctionType.js.trap index aab0d8a6e56..ab1e66273cd 100644 --- a/javascript/extractor/tests/flow/output/trap/parmAnonFunctionType.js.trap +++ b/javascript/extractor/tests/flow/output/trap/parmAnonFunctionType.js.trap @@ -1,7 +1,7 @@ #10000=@"/parmAnonFunctionType.js;sourcefile" -files(#10000,"/parmAnonFunctionType.js","parmAnonFunctionType","js",0) +files(#10000,"/parmAnonFunctionType.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/practicallyAmbigiousExplicitTypeParameters.js.trap b/javascript/extractor/tests/flow/output/trap/practicallyAmbigiousExplicitTypeParameters.js.trap index e63bdcf39d6..8d579436330 100644 --- a/javascript/extractor/tests/flow/output/trap/practicallyAmbigiousExplicitTypeParameters.js.trap +++ b/javascript/extractor/tests/flow/output/trap/practicallyAmbigiousExplicitTypeParameters.js.trap @@ -1,7 +1,7 @@ #10000=@"/practicallyAmbigiousExplicitTypeParameters.js;sourcefile" -files(#10000,"/practicallyAmbigiousExplicitTypeParameters.js","practicallyAmbigiousExplicitTypeParameters","js",0) +files(#10000,"/practicallyAmbigiousExplicitTypeParameters.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/predicate-function-annotation.js.trap b/javascript/extractor/tests/flow/output/trap/predicate-function-annotation.js.trap index 25ef0f6f879..57e41fef661 100644 --- a/javascript/extractor/tests/flow/output/trap/predicate-function-annotation.js.trap +++ b/javascript/extractor/tests/flow/output/trap/predicate-function-annotation.js.trap @@ -1,7 +1,7 @@ #10000=@"/predicate-function-annotation.js;sourcefile" -files(#10000,"/predicate-function-annotation.js","predicate-function-annotation","js",0) +files(#10000,"/predicate-function-annotation.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/qualifiedInterface.js.trap b/javascript/extractor/tests/flow/output/trap/qualifiedInterface.js.trap index 30e2744f7c1..e384b03c9d3 100644 --- a/javascript/extractor/tests/flow/output/trap/qualifiedInterface.js.trap +++ b/javascript/extractor/tests/flow/output/trap/qualifiedInterface.js.trap @@ -1,7 +1,7 @@ #10000=@"/qualifiedInterface.js;sourcefile" -files(#10000,"/qualifiedInterface.js","qualifiedInterface","js",0) +files(#10000,"/qualifiedInterface.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/tst.js.trap b/javascript/extractor/tests/flow/output/trap/tst.js.trap index 69ddbb3cc52..dac8b56dea0 100644 --- a/javascript/extractor/tests/flow/output/trap/tst.js.trap +++ b/javascript/extractor/tests/flow/output/trap/tst.js.trap @@ -1,7 +1,7 @@ #10000=@"/tst.js;sourcefile" -files(#10000,"/tst.js","tst","js",0) +files(#10000,"/tst.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/flow/output/trap/variance.js.trap b/javascript/extractor/tests/flow/output/trap/variance.js.trap index b739bf79598..b6955639fe9 100644 --- a/javascript/extractor/tests/flow/output/trap/variance.js.trap +++ b/javascript/extractor/tests/flow/output/trap/variance.js.trap @@ -1,7 +1,7 @@ #10000=@"/variance.js;sourcefile" -files(#10000,"/variance.js","variance","js",0) +files(#10000,"/variance.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/functionbind/output/trap/tst.js.trap b/javascript/extractor/tests/functionbind/output/trap/tst.js.trap index ccbadc43d8c..8ec6dfe8c8a 100644 --- a/javascript/extractor/tests/functionbind/output/trap/tst.js.trap +++ b/javascript/extractor/tests/functionbind/output/trap/tst.js.trap @@ -1,7 +1,7 @@ #10000=@"/tst.js;sourcefile" -files(#10000,"/tst.js","tst","js",0) +files(#10000,"/tst.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/generatedcode/output/trap/ejs.js.trap b/javascript/extractor/tests/generatedcode/output/trap/ejs.js.trap index 78151c8ca2d..ac5756b042e 100644 --- a/javascript/extractor/tests/generatedcode/output/trap/ejs.js.trap +++ b/javascript/extractor/tests/generatedcode/output/trap/ejs.js.trap @@ -1,7 +1,7 @@ #10000=@"/ejs.js;sourcefile" -files(#10000,"/ejs.js","ejs","js",0) +files(#10000,"/ejs.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/generatedcode/output/trap/test.html.trap b/javascript/extractor/tests/generatedcode/output/trap/test.html.trap index 1cb0292dd84..2446f220c7e 100644 --- a/javascript/extractor/tests/generatedcode/output/trap/test.html.trap +++ b/javascript/extractor/tests/generatedcode/output/trap/test.html.trap @@ -1,7 +1,7 @@ #10000=@"/test.html;sourcefile" -files(#10000,"/test.html","test","html",0) +files(#10000,"/test.html") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/generatedcode/output/trap/tst.js.trap b/javascript/extractor/tests/generatedcode/output/trap/tst.js.trap index 852d0001206..b9f05be663c 100644 --- a/javascript/extractor/tests/generatedcode/output/trap/tst.js.trap +++ b/javascript/extractor/tests/generatedcode/output/trap/tst.js.trap @@ -1,7 +1,7 @@ #10000=@"/tst.js;sourcefile" -files(#10000,"/tst.js","tst","js",0) +files(#10000,"/tst.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/helloworld/output/trap/hello.js.trap b/javascript/extractor/tests/helloworld/output/trap/hello.js.trap index e04c9e06faf..610ae0392b4 100644 --- a/javascript/extractor/tests/helloworld/output/trap/hello.js.trap +++ b/javascript/extractor/tests/helloworld/output/trap/hello.js.trap @@ -1,7 +1,7 @@ #10000=@"/hello.js;sourcefile" -files(#10000,"/hello.js","hello","js",0) +files(#10000,"/hello.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/html-text-extraction/output/trap/text-examples.html.trap b/javascript/extractor/tests/html-text-extraction/output/trap/text-examples.html.trap index ed529bef3c3..f318f201006 100644 --- a/javascript/extractor/tests/html-text-extraction/output/trap/text-examples.html.trap +++ b/javascript/extractor/tests/html-text-extraction/output/trap/text-examples.html.trap @@ -1,7 +1,7 @@ #10000=@"/text-examples.html;sourcefile" -files(#10000,"/text-examples.html","text-examples","html",0) +files(#10000,"/text-examples.html") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/html/output/trap/doctype.html.trap b/javascript/extractor/tests/html/output/trap/doctype.html.trap index 2624d53f031..983c8c168f8 100644 --- a/javascript/extractor/tests/html/output/trap/doctype.html.trap +++ b/javascript/extractor/tests/html/output/trap/doctype.html.trap @@ -1,7 +1,7 @@ #10000=@"/doctype.html;sourcefile" -files(#10000,"/doctype.html","doctype","html",0) +files(#10000,"/doctype.html") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/html/output/trap/empty_script.html.trap b/javascript/extractor/tests/html/output/trap/empty_script.html.trap index bcb4c5adf87..502e7267ddf 100644 --- a/javascript/extractor/tests/html/output/trap/empty_script.html.trap +++ b/javascript/extractor/tests/html/output/trap/empty_script.html.trap @@ -1,7 +1,7 @@ #10000=@"/empty_script.html;sourcefile" -files(#10000,"/empty_script.html","empty_script","html",0) +files(#10000,"/empty_script.html") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/html/output/trap/entities.html.trap b/javascript/extractor/tests/html/output/trap/entities.html.trap index 217c18f7378..2b1ad973920 100644 --- a/javascript/extractor/tests/html/output/trap/entities.html.trap +++ b/javascript/extractor/tests/html/output/trap/entities.html.trap @@ -1,7 +1,7 @@ #10000=@"/entities.html;sourcefile" -files(#10000,"/entities.html","entities","html",0) +files(#10000,"/entities.html") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/html/output/trap/json_in_script.html.trap b/javascript/extractor/tests/html/output/trap/json_in_script.html.trap index 651012c8360..439f6fcfb0b 100644 --- a/javascript/extractor/tests/html/output/trap/json_in_script.html.trap +++ b/javascript/extractor/tests/html/output/trap/json_in_script.html.trap @@ -1,7 +1,7 @@ #10000=@"/json_in_script.html;sourcefile" -files(#10000,"/json_in_script.html","json_in_script","html",0) +files(#10000,"/json_in_script.html") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/html/output/trap/module.html.trap b/javascript/extractor/tests/html/output/trap/module.html.trap index 4b497e2972e..cb4a5874429 100644 --- a/javascript/extractor/tests/html/output/trap/module.html.trap +++ b/javascript/extractor/tests/html/output/trap/module.html.trap @@ -1,7 +1,7 @@ #10000=@"/module.html;sourcefile" -files(#10000,"/module.html","module","html",0) +files(#10000,"/module.html") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/html/output/trap/q.html.trap b/javascript/extractor/tests/html/output/trap/q.html.trap index ebf42cf0b91..9f2155c4892 100644 --- a/javascript/extractor/tests/html/output/trap/q.html.trap +++ b/javascript/extractor/tests/html/output/trap/q.html.trap @@ -1,7 +1,7 @@ #10000=@"/q.html;sourcefile" -files(#10000,"/q.html","q","html",0) +files(#10000,"/q.html") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/html/output/trap/tst.html.trap b/javascript/extractor/tests/html/output/trap/tst.html.trap index 3f7e9362823..369947fc766 100644 --- a/javascript/extractor/tests/html/output/trap/tst.html.trap +++ b/javascript/extractor/tests/html/output/trap/tst.html.trap @@ -1,7 +1,7 @@ #10000=@"/tst.html;sourcefile" -files(#10000,"/tst.html","tst","html",0) +files(#10000,"/tst.html") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/html/output/trap/tst.xhtml.trap b/javascript/extractor/tests/html/output/trap/tst.xhtml.trap index 286c6f0175c..def8d3b124d 100644 --- a/javascript/extractor/tests/html/output/trap/tst.xhtml.trap +++ b/javascript/extractor/tests/html/output/trap/tst.xhtml.trap @@ -1,7 +1,7 @@ #10000=@"/tst.xhtml;sourcefile" -files(#10000,"/tst.xhtml","tst","xhtml",0) +files(#10000,"/tst.xhtml") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/html/output/trap/tst2.html.trap b/javascript/extractor/tests/html/output/trap/tst2.html.trap index d47d40c899d..bff75920f0b 100644 --- a/javascript/extractor/tests/html/output/trap/tst2.html.trap +++ b/javascript/extractor/tests/html/output/trap/tst2.html.trap @@ -1,7 +1,7 @@ #10000=@"/tst2.html;sourcefile" -files(#10000,"/tst2.html","tst2","html",0) +files(#10000,"/tst2.html") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/html/output/trap/tst2.xhtml.trap b/javascript/extractor/tests/html/output/trap/tst2.xhtml.trap index 0b8bd6ff552..bd10b9de6ab 100644 --- a/javascript/extractor/tests/html/output/trap/tst2.xhtml.trap +++ b/javascript/extractor/tests/html/output/trap/tst2.xhtml.trap @@ -1,7 +1,7 @@ #10000=@"/tst2.xhtml;sourcefile" -files(#10000,"/tst2.xhtml","tst2","xhtml",0) +files(#10000,"/tst2.xhtml") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/jscript/output/trap/tst.js.trap b/javascript/extractor/tests/jscript/output/trap/tst.js.trap index 1e74407bd62..91510d288bb 100644 --- a/javascript/extractor/tests/jscript/output/trap/tst.js.trap +++ b/javascript/extractor/tests/jscript/output/trap/tst.js.trap @@ -1,7 +1,7 @@ #10000=@"/tst.js;sourcefile" -files(#10000,"/tst.js","tst","js",0) +files(#10000,"/tst.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/json/output/trap/array.json.trap b/javascript/extractor/tests/json/output/trap/array.json.trap index 090161de744..51f73d2d216 100644 --- a/javascript/extractor/tests/json/output/trap/array.json.trap +++ b/javascript/extractor/tests/json/output/trap/array.json.trap @@ -1,7 +1,7 @@ #10000=@"/array.json;sourcefile" -files(#10000,"/array.json","array","json",0) +files(#10000,"/array.json") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/json/output/trap/comments.json.trap b/javascript/extractor/tests/json/output/trap/comments.json.trap index 0b2666a3e62..320a172e3df 100644 --- a/javascript/extractor/tests/json/output/trap/comments.json.trap +++ b/javascript/extractor/tests/json/output/trap/comments.json.trap @@ -1,7 +1,7 @@ #10000=@"/comments.json;sourcefile" -files(#10000,"/comments.json","comments","json",0) +files(#10000,"/comments.json") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/json/output/trap/duplicate-keys.json.trap b/javascript/extractor/tests/json/output/trap/duplicate-keys.json.trap index e537d1054a9..ddaa82a206b 100644 --- a/javascript/extractor/tests/json/output/trap/duplicate-keys.json.trap +++ b/javascript/extractor/tests/json/output/trap/duplicate-keys.json.trap @@ -1,7 +1,7 @@ #10000=@"/duplicate-keys.json;sourcefile" -files(#10000,"/duplicate-keys.json","duplicate-keys","json",0) +files(#10000,"/duplicate-keys.json") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/json/output/trap/empty.json.trap b/javascript/extractor/tests/json/output/trap/empty.json.trap index e8a3aa4d813..545672c63e2 100644 --- a/javascript/extractor/tests/json/output/trap/empty.json.trap +++ b/javascript/extractor/tests/json/output/trap/empty.json.trap @@ -1,7 +1,7 @@ #10000=@"/empty.json;sourcefile" -files(#10000,"/empty.json","empty","json",0) +files(#10000,"/empty.json") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/json/output/trap/error.json.trap b/javascript/extractor/tests/json/output/trap/error.json.trap index dd2dc094850..8b8a62726d1 100644 --- a/javascript/extractor/tests/json/output/trap/error.json.trap +++ b/javascript/extractor/tests/json/output/trap/error.json.trap @@ -1,7 +1,7 @@ #10000=@"/error.json;sourcefile" -files(#10000,"/error.json","error","json",0) +files(#10000,"/error.json") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/json/output/trap/invalid.json.trap b/javascript/extractor/tests/json/output/trap/invalid.json.trap index d607af95198..039148161f6 100644 --- a/javascript/extractor/tests/json/output/trap/invalid.json.trap +++ b/javascript/extractor/tests/json/output/trap/invalid.json.trap @@ -1,7 +1,7 @@ #10000=@"/invalid.json;sourcefile" -files(#10000,"/invalid.json","invalid","json",0) +files(#10000,"/invalid.json") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/json/output/trap/neg.json.trap b/javascript/extractor/tests/json/output/trap/neg.json.trap index 32f1a2fe752..10545cc7560 100644 --- a/javascript/extractor/tests/json/output/trap/neg.json.trap +++ b/javascript/extractor/tests/json/output/trap/neg.json.trap @@ -1,7 +1,7 @@ #10000=@"/neg.json;sourcefile" -files(#10000,"/neg.json","neg","json",0) +files(#10000,"/neg.json") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/json/output/trap/neg2.json.trap b/javascript/extractor/tests/json/output/trap/neg2.json.trap index d2bd7dde5db..4c7a157cebc 100644 --- a/javascript/extractor/tests/json/output/trap/neg2.json.trap +++ b/javascript/extractor/tests/json/output/trap/neg2.json.trap @@ -1,7 +1,7 @@ #10000=@"/neg2.json;sourcefile" -files(#10000,"/neg2.json","neg2","json",0) +files(#10000,"/neg2.json") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/json/output/trap/null.json.trap b/javascript/extractor/tests/json/output/trap/null.json.trap index f2d1bad90d5..a0025092110 100644 --- a/javascript/extractor/tests/json/output/trap/null.json.trap +++ b/javascript/extractor/tests/json/output/trap/null.json.trap @@ -1,7 +1,7 @@ #10000=@"/null.json;sourcefile" -files(#10000,"/null.json","null","json",0) +files(#10000,"/null.json") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/json/output/trap/omitted.json.trap b/javascript/extractor/tests/json/output/trap/omitted.json.trap index 581d3f2f103..2d28d1699db 100644 --- a/javascript/extractor/tests/json/output/trap/omitted.json.trap +++ b/javascript/extractor/tests/json/output/trap/omitted.json.trap @@ -1,7 +1,7 @@ #10000=@"/omitted.json;sourcefile" -files(#10000,"/omitted.json","omitted","json",0) +files(#10000,"/omitted.json") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/json/output/trap/tst.json.trap b/javascript/extractor/tests/json/output/trap/tst.json.trap index 5efbaa73228..c40cd479a63 100644 --- a/javascript/extractor/tests/json/output/trap/tst.json.trap +++ b/javascript/extractor/tests/json/output/trap/tst.json.trap @@ -1,7 +1,7 @@ #10000=@"/tst.json;sourcefile" -files(#10000,"/tst.json","tst","json",0) +files(#10000,"/tst.json") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/jsx/output/trap/err1.jsx.trap b/javascript/extractor/tests/jsx/output/trap/err1.jsx.trap index 93201c3cb72..93a6175965d 100644 --- a/javascript/extractor/tests/jsx/output/trap/err1.jsx.trap +++ b/javascript/extractor/tests/jsx/output/trap/err1.jsx.trap @@ -1,7 +1,7 @@ #10000=@"/err1.jsx;sourcefile" -files(#10000,"/err1.jsx","err1","jsx",0) +files(#10000,"/err1.jsx") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/jsx/output/trap/err2.jsx.trap b/javascript/extractor/tests/jsx/output/trap/err2.jsx.trap index 0e01749f43a..e71c04cbce2 100644 --- a/javascript/extractor/tests/jsx/output/trap/err2.jsx.trap +++ b/javascript/extractor/tests/jsx/output/trap/err2.jsx.trap @@ -1,7 +1,7 @@ #10000=@"/err2.jsx;sourcefile" -files(#10000,"/err2.jsx","err2","jsx",0) +files(#10000,"/err2.jsx") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/jsx/output/trap/err3.jsx.trap b/javascript/extractor/tests/jsx/output/trap/err3.jsx.trap index 9105d2a0dcd..caf6e92c5aa 100644 --- a/javascript/extractor/tests/jsx/output/trap/err3.jsx.trap +++ b/javascript/extractor/tests/jsx/output/trap/err3.jsx.trap @@ -1,7 +1,7 @@ #10000=@"/err3.jsx;sourcefile" -files(#10000,"/err3.jsx","err3","jsx",0) +files(#10000,"/err3.jsx") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/jsx/output/trap/err4.jsx.trap b/javascript/extractor/tests/jsx/output/trap/err4.jsx.trap index 7b73628781e..aa92643a05c 100644 --- a/javascript/extractor/tests/jsx/output/trap/err4.jsx.trap +++ b/javascript/extractor/tests/jsx/output/trap/err4.jsx.trap @@ -1,7 +1,7 @@ #10000=@"/err4.jsx;sourcefile" -files(#10000,"/err4.jsx","err4","jsx",0) +files(#10000,"/err4.jsx") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/jsx/output/trap/tst.js.trap b/javascript/extractor/tests/jsx/output/trap/tst.js.trap index 1c8307b25c9..874901be084 100644 --- a/javascript/extractor/tests/jsx/output/trap/tst.js.trap +++ b/javascript/extractor/tests/jsx/output/trap/tst.js.trap @@ -1,7 +1,7 @@ #10000=@"/tst.js;sourcefile" -files(#10000,"/tst.js","tst","js",0) +files(#10000,"/tst.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/jsx/output/trap/tst.jsx.trap b/javascript/extractor/tests/jsx/output/trap/tst.jsx.trap index 52253369d16..2f5d17f2332 100644 --- a/javascript/extractor/tests/jsx/output/trap/tst.jsx.trap +++ b/javascript/extractor/tests/jsx/output/trap/tst.jsx.trap @@ -1,7 +1,7 @@ #10000=@"/tst.jsx;sourcefile" -files(#10000,"/tst.jsx","tst","jsx",0) +files(#10000,"/tst.jsx") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/jsx/output/trap/tst2.js.trap b/javascript/extractor/tests/jsx/output/trap/tst2.js.trap index 7acae1995e7..48e8891b95d 100644 --- a/javascript/extractor/tests/jsx/output/trap/tst2.js.trap +++ b/javascript/extractor/tests/jsx/output/trap/tst2.js.trap @@ -1,7 +1,7 @@ #10000=@"/tst2.js;sourcefile" -files(#10000,"/tst2.js","tst2","js",0) +files(#10000,"/tst2.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/keywords/output/trap/tst.js.trap b/javascript/extractor/tests/keywords/output/trap/tst.js.trap index 749aad7d305..9526d353d8f 100644 --- a/javascript/extractor/tests/keywords/output/trap/tst.js.trap +++ b/javascript/extractor/tests/keywords/output/trap/tst.js.trap @@ -1,7 +1,7 @@ #10000=@"/tst.js;sourcefile" -files(#10000,"/tst.js","tst","js",0) +files(#10000,"/tst.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/moduleTypes1/output/trap/package.json.trap b/javascript/extractor/tests/moduleTypes1/output/trap/package.json.trap index 2f945dcaaf2..28c4c087216 100644 --- a/javascript/extractor/tests/moduleTypes1/output/trap/package.json.trap +++ b/javascript/extractor/tests/moduleTypes1/output/trap/package.json.trap @@ -1,7 +1,7 @@ #10000=@"/package.json;sourcefile" -files(#10000,"/package.json","package","json",0) +files(#10000,"/package.json") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/moduleTypes1/output/trap/tst.js.trap b/javascript/extractor/tests/moduleTypes1/output/trap/tst.js.trap index cedeb436b92..1896ecff4b3 100644 --- a/javascript/extractor/tests/moduleTypes1/output/trap/tst.js.trap +++ b/javascript/extractor/tests/moduleTypes1/output/trap/tst.js.trap @@ -1,7 +1,7 @@ #10000=@"/tst.js;sourcefile" -files(#10000,"/tst.js","tst","js",0) +files(#10000,"/tst.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/moduleTypes2/output/trap/package.json.trap b/javascript/extractor/tests/moduleTypes2/output/trap/package.json.trap index 71e31b4820d..1f090b6eacc 100644 --- a/javascript/extractor/tests/moduleTypes2/output/trap/package.json.trap +++ b/javascript/extractor/tests/moduleTypes2/output/trap/package.json.trap @@ -1,7 +1,7 @@ #10000=@"/package.json;sourcefile" -files(#10000,"/package.json","package","json",0) +files(#10000,"/package.json") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/moduleTypes2/output/trap/tst2.js.trap b/javascript/extractor/tests/moduleTypes2/output/trap/tst2.js.trap index 31ab093a62b..84299e50279 100644 --- a/javascript/extractor/tests/moduleTypes2/output/trap/tst2.js.trap +++ b/javascript/extractor/tests/moduleTypes2/output/trap/tst2.js.trap @@ -1,7 +1,7 @@ #10000=@"/tst2.js;sourcefile" -files(#10000,"/tst2.js","tst2","js",0) +files(#10000,"/tst2.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/moduleTypes3/output/trap/package.json.trap b/javascript/extractor/tests/moduleTypes3/output/trap/package.json.trap index eed0d0523d5..2d207d55c7a 100644 --- a/javascript/extractor/tests/moduleTypes3/output/trap/package.json.trap +++ b/javascript/extractor/tests/moduleTypes3/output/trap/package.json.trap @@ -1,7 +1,7 @@ #10000=@"/package.json;sourcefile" -files(#10000,"/package.json","package","json",0) +files(#10000,"/package.json") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/moduleTypes3/output/trap/tst.js.trap b/javascript/extractor/tests/moduleTypes3/output/trap/tst.js.trap index cedeb436b92..1896ecff4b3 100644 --- a/javascript/extractor/tests/moduleTypes3/output/trap/tst.js.trap +++ b/javascript/extractor/tests/moduleTypes3/output/trap/tst.js.trap @@ -1,7 +1,7 @@ #10000=@"/tst.js;sourcefile" -files(#10000,"/tst.js","tst","js",0) +files(#10000,"/tst.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/mozilla/output/trap/array_comprehensions.js.trap b/javascript/extractor/tests/mozilla/output/trap/array_comprehensions.js.trap index cf80f8e18be..ab2e9e4a1ab 100644 --- a/javascript/extractor/tests/mozilla/output/trap/array_comprehensions.js.trap +++ b/javascript/extractor/tests/mozilla/output/trap/array_comprehensions.js.trap @@ -1,7 +1,7 @@ #10000=@"/array_comprehensions.js;sourcefile" -files(#10000,"/array_comprehensions.js","array_comprehensions","js",0) +files(#10000,"/array_comprehensions.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/mozilla/output/trap/exprfns.js.trap b/javascript/extractor/tests/mozilla/output/trap/exprfns.js.trap index 8a4feb66d03..db738b83deb 100644 --- a/javascript/extractor/tests/mozilla/output/trap/exprfns.js.trap +++ b/javascript/extractor/tests/mozilla/output/trap/exprfns.js.trap @@ -1,7 +1,7 @@ #10000=@"/exprfns.js;sourcefile" -files(#10000,"/exprfns.js","exprfns","js",0) +files(#10000,"/exprfns.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/mozilla/output/trap/foreach.js.trap b/javascript/extractor/tests/mozilla/output/trap/foreach.js.trap index 0d2e7bc4a56..28f0598a994 100644 --- a/javascript/extractor/tests/mozilla/output/trap/foreach.js.trap +++ b/javascript/extractor/tests/mozilla/output/trap/foreach.js.trap @@ -1,7 +1,7 @@ #10000=@"/foreach.js;sourcefile" -files(#10000,"/foreach.js","foreach","js",0) +files(#10000,"/foreach.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/mozilla/output/trap/generator_expressions.js.trap b/javascript/extractor/tests/mozilla/output/trap/generator_expressions.js.trap index f8da052b6f8..e1abfa519c7 100644 --- a/javascript/extractor/tests/mozilla/output/trap/generator_expressions.js.trap +++ b/javascript/extractor/tests/mozilla/output/trap/generator_expressions.js.trap @@ -1,7 +1,7 @@ #10000=@"/generator_expressions.js;sourcefile" -files(#10000,"/generator_expressions.js","generator_expressions","js",0) +files(#10000,"/generator_expressions.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/mozilla/output/trap/guardedCatch.js.trap b/javascript/extractor/tests/mozilla/output/trap/guardedCatch.js.trap index fe588ef567e..28200e7e028 100644 --- a/javascript/extractor/tests/mozilla/output/trap/guardedCatch.js.trap +++ b/javascript/extractor/tests/mozilla/output/trap/guardedCatch.js.trap @@ -1,7 +1,7 @@ #10000=@"/guardedCatch.js;sourcefile" -files(#10000,"/guardedCatch.js","guardedCatch","js",0) +files(#10000,"/guardedCatch.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/mozilla/output/trap/letExpr.js.trap b/javascript/extractor/tests/mozilla/output/trap/letExpr.js.trap index 703e9e69cbf..28e3fd45bf9 100644 --- a/javascript/extractor/tests/mozilla/output/trap/letExpr.js.trap +++ b/javascript/extractor/tests/mozilla/output/trap/letExpr.js.trap @@ -1,7 +1,7 @@ #10000=@"/letExpr.js;sourcefile" -files(#10000,"/letExpr.js","letExpr","js",0) +files(#10000,"/letExpr.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/mozilla/output/trap/letStmt.js.trap b/javascript/extractor/tests/mozilla/output/trap/letStmt.js.trap index 6925f668b3f..38bed9aeab6 100644 --- a/javascript/extractor/tests/mozilla/output/trap/letStmt.js.trap +++ b/javascript/extractor/tests/mozilla/output/trap/letStmt.js.trap @@ -1,7 +1,7 @@ #10000=@"/letStmt.js;sourcefile" -files(#10000,"/letStmt.js","letStmt","js",0) +files(#10000,"/letStmt.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/mozilla/output/trap/letStmt2.js.trap b/javascript/extractor/tests/mozilla/output/trap/letStmt2.js.trap index baeeb086f72..d81fb77a243 100644 --- a/javascript/extractor/tests/mozilla/output/trap/letStmt2.js.trap +++ b/javascript/extractor/tests/mozilla/output/trap/letStmt2.js.trap @@ -1,7 +1,7 @@ #10000=@"/letStmt2.js;sourcefile" -files(#10000,"/letStmt2.js","letStmt2","js",0) +files(#10000,"/letStmt2.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/mozilla/output/trap/new-with-trailing-arg.js.trap b/javascript/extractor/tests/mozilla/output/trap/new-with-trailing-arg.js.trap index 05b4e28d159..a2a88241cd2 100644 --- a/javascript/extractor/tests/mozilla/output/trap/new-with-trailing-arg.js.trap +++ b/javascript/extractor/tests/mozilla/output/trap/new-with-trailing-arg.js.trap @@ -1,7 +1,7 @@ #10000=@"/new-with-trailing-arg.js;sourcefile" -files(#10000,"/new-with-trailing-arg.js","new-with-trailing-arg","js",0) +files(#10000,"/new-with-trailing-arg.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/mozilla/output/trap/odasa-2593.js.trap b/javascript/extractor/tests/mozilla/output/trap/odasa-2593.js.trap index abe232b6e7f..cc974f12339 100644 --- a/javascript/extractor/tests/mozilla/output/trap/odasa-2593.js.trap +++ b/javascript/extractor/tests/mozilla/output/trap/odasa-2593.js.trap @@ -1,7 +1,7 @@ #10000=@"/odasa-2593.js;sourcefile" -files(#10000,"/odasa-2593.js","odasa-2593","js",0) +files(#10000,"/odasa-2593.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ng-templates/output/trap/component.js.trap b/javascript/extractor/tests/ng-templates/output/trap/component.js.trap index 0d475cc7080..3f03793bcc2 100644 --- a/javascript/extractor/tests/ng-templates/output/trap/component.js.trap +++ b/javascript/extractor/tests/ng-templates/output/trap/component.js.trap @@ -1,7 +1,7 @@ #10000=@"/component.js;sourcefile" -files(#10000,"/component.js","component","js",0) +files(#10000,"/component.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/node/output/trap/constlet.js.trap b/javascript/extractor/tests/node/output/trap/constlet.js.trap index 659ac0a76de..c7080134983 100644 --- a/javascript/extractor/tests/node/output/trap/constlet.js.trap +++ b/javascript/extractor/tests/node/output/trap/constlet.js.trap @@ -1,7 +1,7 @@ #10000=@"/constlet.js;sourcefile" -files(#10000,"/constlet.js","constlet","js",0) +files(#10000,"/constlet.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/node/output/trap/hello.trap b/javascript/extractor/tests/node/output/trap/hello.trap index 83ba4b94239..8c083879437 100644 --- a/javascript/extractor/tests/node/output/trap/hello.trap +++ b/javascript/extractor/tests/node/output/trap/hello.trap @@ -1,9 +1,9 @@ #10000=@"/g/hello;sourcefile" -files(#10000,"/g/hello","hello","",0) +files(#10000,"/g/hello") #10001=@"/g;folder" -folders(#10001,"/g","g") +folders(#10001,"/g") #10002=@"/;folder" -folders(#10002,"/","") +folders(#10002,"/") containerparent(#10002,#10001) containerparent(#10001,#10000) #10003=@"loc,{#10000},0,0,0,0" diff --git a/javascript/extractor/tests/node/output/trap/package.json.trap b/javascript/extractor/tests/node/output/trap/package.json.trap index f35a6af005a..80f58515e69 100644 --- a/javascript/extractor/tests/node/output/trap/package.json.trap +++ b/javascript/extractor/tests/node/output/trap/package.json.trap @@ -1,9 +1,9 @@ #10000=@"/f/package.json;sourcefile" -files(#10000,"/f/package.json","package","json",0) +files(#10000,"/f/package.json") #10001=@"/f;folder" -folders(#10001,"/f","f") +folders(#10001,"/f") #10002=@"/;folder" -folders(#10002,"/","") +folders(#10002,"/") containerparent(#10002,#10001) containerparent(#10001,#10000) #10003=@"loc,{#10000},0,0,0,0" diff --git a/javascript/extractor/tests/node/output/trap/tst.html.trap b/javascript/extractor/tests/node/output/trap/tst.html.trap index 7f045ba240a..56817f8f03a 100644 --- a/javascript/extractor/tests/node/output/trap/tst.html.trap +++ b/javascript/extractor/tests/node/output/trap/tst.html.trap @@ -1,7 +1,7 @@ #10000=@"/tst.html;sourcefile" -files(#10000,"/tst.html","tst","html",0) +files(#10000,"/tst.html") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/node/output/trap/tst.js.trap b/javascript/extractor/tests/node/output/trap/tst.js.trap index d53970788a3..58f71f4717b 100644 --- a/javascript/extractor/tests/node/output/trap/tst.js.trap +++ b/javascript/extractor/tests/node/output/trap/tst.js.trap @@ -1,7 +1,7 @@ #10000=@"/tst.js;sourcefile" -files(#10000,"/tst.js","tst","js",0) +files(#10000,"/tst.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/node/output/trap/tst.mjs.trap b/javascript/extractor/tests/node/output/trap/tst.mjs.trap index 81ea919abfb..f097709a21a 100644 --- a/javascript/extractor/tests/node/output/trap/tst.mjs.trap +++ b/javascript/extractor/tests/node/output/trap/tst.mjs.trap @@ -1,7 +1,7 @@ #10000=@"/tst.mjs;sourcefile" -files(#10000,"/tst.mjs","tst","mjs",0) +files(#10000,"/tst.mjs") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/rcfiles/output/trap/.babelrc.trap b/javascript/extractor/tests/rcfiles/output/trap/.babelrc.trap index ba9b6ada1b6..6f2bd6b61d5 100644 --- a/javascript/extractor/tests/rcfiles/output/trap/.babelrc.trap +++ b/javascript/extractor/tests/rcfiles/output/trap/.babelrc.trap @@ -1,7 +1,7 @@ #10000=@"/.babelrc;sourcefile" -files(#10000,"/.babelrc",".babelrc","",0) +files(#10000,"/.babelrc") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/rcfiles/output/trap/.eslintrc.trap b/javascript/extractor/tests/rcfiles/output/trap/.eslintrc.trap index 756d841bdb4..f9a74acff80 100644 --- a/javascript/extractor/tests/rcfiles/output/trap/.eslintrc.trap +++ b/javascript/extractor/tests/rcfiles/output/trap/.eslintrc.trap @@ -1,7 +1,7 @@ #10000=@"/.eslintrc;sourcefile" -files(#10000,"/.eslintrc",".eslintrc","",0) +files(#10000,"/.eslintrc") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/regexp/output/trap/es2018.js.trap b/javascript/extractor/tests/regexp/output/trap/es2018.js.trap index 44cccd78fec..0e4dbc5d3aa 100644 --- a/javascript/extractor/tests/regexp/output/trap/es2018.js.trap +++ b/javascript/extractor/tests/regexp/output/trap/es2018.js.trap @@ -1,7 +1,7 @@ #10000=@"/es2018.js;sourcefile" -files(#10000,"/es2018.js","es2018","js",0) +files(#10000,"/es2018.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/regexp/output/trap/nonstandard.js.trap b/javascript/extractor/tests/regexp/output/trap/nonstandard.js.trap index e6038ba4580..e0b648118d9 100644 --- a/javascript/extractor/tests/regexp/output/trap/nonstandard.js.trap +++ b/javascript/extractor/tests/regexp/output/trap/nonstandard.js.trap @@ -1,7 +1,7 @@ #10000=@"/nonstandard.js;sourcefile" -files(#10000,"/nonstandard.js","nonstandard","js",0) +files(#10000,"/nonstandard.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/regexp/output/trap/odasa-1934.js.trap b/javascript/extractor/tests/regexp/output/trap/odasa-1934.js.trap index 416c92e2594..6e90c62e6a6 100644 --- a/javascript/extractor/tests/regexp/output/trap/odasa-1934.js.trap +++ b/javascript/extractor/tests/regexp/output/trap/odasa-1934.js.trap @@ -1,7 +1,7 @@ #10000=@"/odasa-1934.js;sourcefile" -files(#10000,"/odasa-1934.js","odasa-1934","js",0) +files(#10000,"/odasa-1934.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/regexp/output/trap/tst.js.trap b/javascript/extractor/tests/regexp/output/trap/tst.js.trap index be1f55ad776..80ab7ab1ed7 100644 Binary files a/javascript/extractor/tests/regexp/output/trap/tst.js.trap and b/javascript/extractor/tests/regexp/output/trap/tst.js.trap differ diff --git a/javascript/extractor/tests/restprops/output/trap/tst.js.trap b/javascript/extractor/tests/restprops/output/trap/tst.js.trap index 3c481774da3..afa92ddc8b5 100644 --- a/javascript/extractor/tests/restprops/output/trap/tst.js.trap +++ b/javascript/extractor/tests/restprops/output/trap/tst.js.trap @@ -1,7 +1,7 @@ #10000=@"/tst.js;sourcefile" -files(#10000,"/tst.js","tst","js",0) +files(#10000,"/tst.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/shebang/output/trap/tst.html.trap b/javascript/extractor/tests/shebang/output/trap/tst.html.trap index 08d0f35bc2f..8588fd8be55 100644 --- a/javascript/extractor/tests/shebang/output/trap/tst.html.trap +++ b/javascript/extractor/tests/shebang/output/trap/tst.html.trap @@ -1,7 +1,7 @@ #10000=@"/tst.html;sourcefile" -files(#10000,"/tst.html","tst","html",0) +files(#10000,"/tst.html") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/shebang/output/trap/tst.js.trap b/javascript/extractor/tests/shebang/output/trap/tst.js.trap index 7c5ded4aead..59f7c049bfe 100644 --- a/javascript/extractor/tests/shebang/output/trap/tst.js.trap +++ b/javascript/extractor/tests/shebang/output/trap/tst.js.trap @@ -1,7 +1,7 @@ #10000=@"/tst.js;sourcefile" -files(#10000,"/tst.js","tst","js",0) +files(#10000,"/tst.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/shebang/output/trap/typescript-with-shebang.ts.trap b/javascript/extractor/tests/shebang/output/trap/typescript-with-shebang.ts.trap index 20220279fe5..82ba041bb8b 100644 --- a/javascript/extractor/tests/shebang/output/trap/typescript-with-shebang.ts.trap +++ b/javascript/extractor/tests/shebang/output/trap/typescript-with-shebang.ts.trap @@ -1,7 +1,7 @@ #10000=@"/typescript-with-shebang.ts;sourcefile" -files(#10000,"/typescript-with-shebang.ts","typescript-with-shebang","ts",0) +files(#10000,"/typescript-with-shebang.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/shebang/output/trap/typescript.ts.trap b/javascript/extractor/tests/shebang/output/trap/typescript.ts.trap index b987065937e..ea81b8525ee 100644 --- a/javascript/extractor/tests/shebang/output/trap/typescript.ts.trap +++ b/javascript/extractor/tests/shebang/output/trap/typescript.ts.trap @@ -1,7 +1,7 @@ #10000=@"/typescript.ts;sourcefile" -files(#10000,"/typescript.ts","typescript","ts",0) +files(#10000,"/typescript.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/stmts/output/trap/conditionals.js.trap b/javascript/extractor/tests/stmts/output/trap/conditionals.js.trap index 38f4d596c67..9e96f57790e 100644 --- a/javascript/extractor/tests/stmts/output/trap/conditionals.js.trap +++ b/javascript/extractor/tests/stmts/output/trap/conditionals.js.trap @@ -1,7 +1,7 @@ #10000=@"/conditionals.js;sourcefile" -files(#10000,"/conditionals.js","conditionals","js",0) +files(#10000,"/conditionals.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/stmts/output/trap/forvardefault.js.trap b/javascript/extractor/tests/stmts/output/trap/forvardefault.js.trap index d0a9f15240a..1e676b70d98 100644 --- a/javascript/extractor/tests/stmts/output/trap/forvardefault.js.trap +++ b/javascript/extractor/tests/stmts/output/trap/forvardefault.js.trap @@ -1,7 +1,7 @@ #10000=@"/forvardefault.js;sourcefile" -files(#10000,"/forvardefault.js","forvardefault","js",0) +files(#10000,"/forvardefault.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/stmts/output/trap/functions.js.trap b/javascript/extractor/tests/stmts/output/trap/functions.js.trap index 30a902de478..7eb1f5a04c1 100644 --- a/javascript/extractor/tests/stmts/output/trap/functions.js.trap +++ b/javascript/extractor/tests/stmts/output/trap/functions.js.trap @@ -1,7 +1,7 @@ #10000=@"/functions.js;sourcefile" -files(#10000,"/functions.js","functions","js",0) +files(#10000,"/functions.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/stmts/output/trap/loops.js.trap b/javascript/extractor/tests/stmts/output/trap/loops.js.trap index a06fd852b42..3b6519e9479 100644 --- a/javascript/extractor/tests/stmts/output/trap/loops.js.trap +++ b/javascript/extractor/tests/stmts/output/trap/loops.js.trap @@ -1,7 +1,7 @@ #10000=@"/loops.js;sourcefile" -files(#10000,"/loops.js","loops","js",0) +files(#10000,"/loops.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/stmts/output/trap/others.js.trap b/javascript/extractor/tests/stmts/output/trap/others.js.trap index 2015fc6fad8..cbb132ca1b2 100644 --- a/javascript/extractor/tests/stmts/output/trap/others.js.trap +++ b/javascript/extractor/tests/stmts/output/trap/others.js.trap @@ -1,7 +1,7 @@ #10000=@"/others.js;sourcefile" -files(#10000,"/others.js","others","js",0) +files(#10000,"/others.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/stmts/output/trap/switch.js.trap b/javascript/extractor/tests/stmts/output/trap/switch.js.trap index a6e5f8cbd2b..7e6d831b38f 100644 --- a/javascript/extractor/tests/stmts/output/trap/switch.js.trap +++ b/javascript/extractor/tests/stmts/output/trap/switch.js.trap @@ -1,7 +1,7 @@ #10000=@"/switch.js;sourcefile" -files(#10000,"/switch.js","switch","js",0) +files(#10000,"/switch.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/stmts/output/trap/switch2.js.trap b/javascript/extractor/tests/stmts/output/trap/switch2.js.trap index 28e97b932a7..bd5de336d09 100644 --- a/javascript/extractor/tests/stmts/output/trap/switch2.js.trap +++ b/javascript/extractor/tests/stmts/output/trap/switch2.js.trap @@ -1,7 +1,7 @@ #10000=@"/switch2.js;sourcefile" -files(#10000,"/switch2.js","switch2","js",0) +files(#10000,"/switch2.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/stmts/output/trap/trivial-switch.js.trap b/javascript/extractor/tests/stmts/output/trap/trivial-switch.js.trap index 46acbaefbbd..5eda7dbc53d 100644 --- a/javascript/extractor/tests/stmts/output/trap/trivial-switch.js.trap +++ b/javascript/extractor/tests/stmts/output/trap/trivial-switch.js.trap @@ -1,7 +1,7 @@ #10000=@"/trivial-switch.js;sourcefile" -files(#10000,"/trivial-switch.js","trivial-switch","js",0) +files(#10000,"/trivial-switch.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/stmts/output/trap/try.js.trap b/javascript/extractor/tests/stmts/output/trap/try.js.trap index a439edd69a8..607d91d6f64 100644 --- a/javascript/extractor/tests/stmts/output/trap/try.js.trap +++ b/javascript/extractor/tests/stmts/output/trap/try.js.trap @@ -1,7 +1,7 @@ #10000=@"/try.js;sourcefile" -files(#10000,"/try.js","try","js",0) +files(#10000,"/try.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/strictmode/output/trap/assignargs.js.trap b/javascript/extractor/tests/strictmode/output/trap/assignargs.js.trap index c40d0118989..8b34d3f5ad6 100644 --- a/javascript/extractor/tests/strictmode/output/trap/assignargs.js.trap +++ b/javascript/extractor/tests/strictmode/output/trap/assignargs.js.trap @@ -1,7 +1,7 @@ #10000=@"/assignargs.js;sourcefile" -files(#10000,"/assignargs.js","assignargs","js",0) +files(#10000,"/assignargs.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/strictmode/output/trap/tst.js.trap b/javascript/extractor/tests/strictmode/output/trap/tst.js.trap index 8b45e865618..ac5f9e60cdb 100644 --- a/javascript/extractor/tests/strictmode/output/trap/tst.js.trap +++ b/javascript/extractor/tests/strictmode/output/trap/tst.js.trap @@ -1,7 +1,7 @@ #10000=@"/tst.js;sourcefile" -files(#10000,"/tst.js","tst","js",0) +files(#10000,"/tst.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/arrayBindingPattern.ts.trap b/javascript/extractor/tests/ts/output/trap/arrayBindingPattern.ts.trap index 4436f4cdf8a..dfd38cc13c4 100644 --- a/javascript/extractor/tests/ts/output/trap/arrayBindingPattern.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/arrayBindingPattern.ts.trap @@ -1,7 +1,7 @@ #10000=@"/arrayBindingPattern.ts;sourcefile" -files(#10000,"/arrayBindingPattern.ts","arrayBindingPattern","ts",0) +files(#10000,"/arrayBindingPattern.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/badimport.ts.trap b/javascript/extractor/tests/ts/output/trap/badimport.ts.trap index e6a8f014dd9..e0f6b16abe3 100644 --- a/javascript/extractor/tests/ts/output/trap/badimport.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/badimport.ts.trap @@ -1,7 +1,7 @@ #10000=@"/badimport.ts;sourcefile" -files(#10000,"/badimport.ts","badimport","ts",0) +files(#10000,"/badimport.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/bindingpattern.ts.trap b/javascript/extractor/tests/ts/output/trap/bindingpattern.ts.trap index 16709a9b5c6..b0b28377295 100644 --- a/javascript/extractor/tests/ts/output/trap/bindingpattern.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/bindingpattern.ts.trap @@ -1,7 +1,7 @@ #10000=@"/bindingpattern.ts;sourcefile" -files(#10000,"/bindingpattern.ts","bindingpattern","ts",0) +files(#10000,"/bindingpattern.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/bom.ts.trap b/javascript/extractor/tests/ts/output/trap/bom.ts.trap index 166d8c30704..3049dd9aa91 100644 --- a/javascript/extractor/tests/ts/output/trap/bom.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/bom.ts.trap @@ -1,7 +1,7 @@ #10000=@"/bom.ts;sourcefile" -files(#10000,"/bom.ts","bom","ts",0) +files(#10000,"/bom.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/classes.ts.trap b/javascript/extractor/tests/ts/output/trap/classes.ts.trap index ce17a42019e..e91be374bf0 100644 --- a/javascript/extractor/tests/ts/output/trap/classes.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/classes.ts.trap @@ -1,7 +1,7 @@ #10000=@"/classes.ts;sourcefile" -files(#10000,"/classes.ts","classes","ts",0) +files(#10000,"/classes.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/comments.ts.trap b/javascript/extractor/tests/ts/output/trap/comments.ts.trap index 495b0656a82..4898c710e95 100644 --- a/javascript/extractor/tests/ts/output/trap/comments.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/comments.ts.trap @@ -1,7 +1,7 @@ #10000=@"/comments.ts;sourcefile" -files(#10000,"/comments.ts","comments","ts",0) +files(#10000,"/comments.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/conditionalTypes.ts.trap b/javascript/extractor/tests/ts/output/trap/conditionalTypes.ts.trap index 744b1f7e9dd..c8d26a9b983 100644 --- a/javascript/extractor/tests/ts/output/trap/conditionalTypes.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/conditionalTypes.ts.trap @@ -1,7 +1,7 @@ #10000=@"/conditionalTypes.ts;sourcefile" -files(#10000,"/conditionalTypes.ts","conditionalTypes","ts",0) +files(#10000,"/conditionalTypes.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/ctordecl.ts.trap b/javascript/extractor/tests/ts/output/trap/ctordecl.ts.trap index 99f891a12a0..9653669e31f 100644 --- a/javascript/extractor/tests/ts/output/trap/ctordecl.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/ctordecl.ts.trap @@ -1,7 +1,7 @@ #10000=@"/ctordecl.ts;sourcefile" -files(#10000,"/ctordecl.ts","ctordecl","ts",0) +files(#10000,"/ctordecl.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/declareClass.ts.trap b/javascript/extractor/tests/ts/output/trap/declareClass.ts.trap index f43447e82df..6bc9fb5ffb2 100644 --- a/javascript/extractor/tests/ts/output/trap/declareClass.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/declareClass.ts.trap @@ -1,7 +1,7 @@ #10000=@"/declareClass.ts;sourcefile" -files(#10000,"/declareClass.ts","declareClass","ts",0) +files(#10000,"/declareClass.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/decorators.ts.trap b/javascript/extractor/tests/ts/output/trap/decorators.ts.trap index a538cf72b5e..de7745b6427 100644 --- a/javascript/extractor/tests/ts/output/trap/decorators.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/decorators.ts.trap @@ -1,7 +1,7 @@ #10000=@"/decorators.ts;sourcefile" -files(#10000,"/decorators.ts","decorators","ts",0) +files(#10000,"/decorators.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/emptydecls.ts.trap b/javascript/extractor/tests/ts/output/trap/emptydecls.ts.trap index 29c9d49c18f..5a1b6c45cdf 100644 --- a/javascript/extractor/tests/ts/output/trap/emptydecls.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/emptydecls.ts.trap @@ -1,7 +1,7 @@ #10000=@"/emptydecls.ts;sourcefile" -files(#10000,"/emptydecls.ts","emptydecls","ts",0) +files(#10000,"/emptydecls.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/enum.ts.trap b/javascript/extractor/tests/ts/output/trap/enum.ts.trap index 3f9eab0e26d..146d34fb6cc 100644 --- a/javascript/extractor/tests/ts/output/trap/enum.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/enum.ts.trap @@ -1,7 +1,7 @@ #10000=@"/enum.ts;sourcefile" -files(#10000,"/enum.ts","enum","ts",0) +files(#10000,"/enum.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/export.ts.trap b/javascript/extractor/tests/ts/output/trap/export.ts.trap index dbc791ea5cc..18fdbb8f7c2 100644 --- a/javascript/extractor/tests/ts/output/trap/export.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/export.ts.trap @@ -1,7 +1,7 @@ #10000=@"/export.ts;sourcefile" -files(#10000,"/export.ts","export","ts",0) +files(#10000,"/export.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/export2.ts.trap b/javascript/extractor/tests/ts/output/trap/export2.ts.trap index 27610aaa6a6..7b433d0d1d3 100644 --- a/javascript/extractor/tests/ts/output/trap/export2.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/export2.ts.trap @@ -1,7 +1,7 @@ #10000=@"/export2.ts;sourcefile" -files(#10000,"/export2.ts","export2","ts",0) +files(#10000,"/export2.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/exportasnamespace.d.ts.trap b/javascript/extractor/tests/ts/output/trap/exportasnamespace.d.ts.trap index adb7bffc606..441258563a3 100644 --- a/javascript/extractor/tests/ts/output/trap/exportasnamespace.d.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/exportasnamespace.d.ts.trap @@ -1,7 +1,7 @@ #10000=@"/exportasnamespace.d.ts;sourcefile" -files(#10000,"/exportasnamespace.d.ts","exportasnamespace.d","ts",0) +files(#10000,"/exportasnamespace.d.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/exportassign.ts.trap b/javascript/extractor/tests/ts/output/trap/exportassign.ts.trap index c6b8a8f3557..792efab2932 100644 --- a/javascript/extractor/tests/ts/output/trap/exportassign.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/exportassign.ts.trap @@ -1,7 +1,7 @@ #10000=@"/exportassign.ts;sourcefile" -files(#10000,"/exportassign.ts","exportassign","ts",0) +files(#10000,"/exportassign.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/exportclass.ts.trap b/javascript/extractor/tests/ts/output/trap/exportclass.ts.trap index a22f30820b0..7c8bd5baf2d 100644 --- a/javascript/extractor/tests/ts/output/trap/exportclass.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/exportclass.ts.trap @@ -1,7 +1,7 @@ #10000=@"/exportclass.ts;sourcefile" -files(#10000,"/exportclass.ts","exportclass","ts",0) +files(#10000,"/exportclass.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/exprs.ts.trap b/javascript/extractor/tests/ts/output/trap/exprs.ts.trap index c87826abd82..fdd477046a5 100644 --- a/javascript/extractor/tests/ts/output/trap/exprs.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/exprs.ts.trap @@ -1,7 +1,7 @@ #10000=@"/exprs.ts;sourcefile" -files(#10000,"/exprs.ts","exprs","ts",0) +files(#10000,"/exprs.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/externalmodule.ts.trap b/javascript/extractor/tests/ts/output/trap/externalmodule.ts.trap index c778ac25d4c..0c2d918cd91 100644 --- a/javascript/extractor/tests/ts/output/trap/externalmodule.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/externalmodule.ts.trap @@ -1,7 +1,7 @@ #10000=@"/externalmodule.ts;sourcefile" -files(#10000,"/externalmodule.ts","externalmodule","ts",0) +files(#10000,"/externalmodule.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/functiondecorators.ts.trap b/javascript/extractor/tests/ts/output/trap/functiondecorators.ts.trap index efabc3e8dcb..89cd1760443 100644 --- a/javascript/extractor/tests/ts/output/trap/functiondecorators.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/functiondecorators.ts.trap @@ -1,7 +1,7 @@ #10000=@"/functiondecorators.ts;sourcefile" -files(#10000,"/functiondecorators.ts","functiondecorators","ts",0) +files(#10000,"/functiondecorators.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/hello.ts.trap b/javascript/extractor/tests/ts/output/trap/hello.ts.trap index 049108cd90a..73c0ba7df7c 100644 --- a/javascript/extractor/tests/ts/output/trap/hello.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/hello.ts.trap @@ -1,7 +1,7 @@ #10000=@"/hello.ts;sourcefile" -files(#10000,"/hello.ts","hello","ts",0) +files(#10000,"/hello.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/importExport.ts.trap b/javascript/extractor/tests/ts/output/trap/importExport.ts.trap index 9c36c4b973e..5b4b6d1cdcf 100644 --- a/javascript/extractor/tests/ts/output/trap/importExport.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/importExport.ts.trap @@ -1,7 +1,7 @@ #10000=@"/importExport.ts;sourcefile" -files(#10000,"/importExport.ts","importExport","ts",0) +files(#10000,"/importExport.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/importNonStrings.ts.trap b/javascript/extractor/tests/ts/output/trap/importNonStrings.ts.trap index af044be98c8..82e087ceca7 100644 --- a/javascript/extractor/tests/ts/output/trap/importNonStrings.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/importNonStrings.ts.trap @@ -1,7 +1,7 @@ #10000=@"/importNonStrings.ts;sourcefile" -files(#10000,"/importNonStrings.ts","importNonStrings","ts",0) +files(#10000,"/importNonStrings.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/importassign.ts.trap b/javascript/extractor/tests/ts/output/trap/importassign.ts.trap index 993e69d0bb9..6b1400b59fb 100644 --- a/javascript/extractor/tests/ts/output/trap/importassign.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/importassign.ts.trap @@ -1,7 +1,7 @@ #10000=@"/importassign.ts;sourcefile" -files(#10000,"/importassign.ts","importassign","ts",0) +files(#10000,"/importassign.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/interfaces.ts.trap b/javascript/extractor/tests/ts/output/trap/interfaces.ts.trap index 5176fb38002..5ceae62d1ba 100644 --- a/javascript/extractor/tests/ts/output/trap/interfaces.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/interfaces.ts.trap @@ -1,7 +1,7 @@ #10000=@"/interfaces.ts;sourcefile" -files(#10000,"/interfaces.ts","interfaces","ts",0) +files(#10000,"/interfaces.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/invalidModuleSpecifier.ts.trap b/javascript/extractor/tests/ts/output/trap/invalidModuleSpecifier.ts.trap index a6f530abf78..68cc255f7c5 100644 --- a/javascript/extractor/tests/ts/output/trap/invalidModuleSpecifier.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/invalidModuleSpecifier.ts.trap @@ -1,7 +1,7 @@ #10000=@"/invalidModuleSpecifier.ts;sourcefile" -files(#10000,"/invalidModuleSpecifier.ts","invalidModuleSpecifier","ts",0) +files(#10000,"/invalidModuleSpecifier.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/let.ts.trap b/javascript/extractor/tests/ts/output/trap/let.ts.trap index fe3482ffb96..cdc760eb16c 100644 --- a/javascript/extractor/tests/ts/output/trap/let.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/let.ts.trap @@ -1,7 +1,7 @@ #10000=@"/let.ts;sourcefile" -files(#10000,"/let.ts","let","ts",0) +files(#10000,"/let.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/logicalOr.ts.trap b/javascript/extractor/tests/ts/output/trap/logicalOr.ts.trap index 14ad91bef9d..abd1cbd3be5 100644 --- a/javascript/extractor/tests/ts/output/trap/logicalOr.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/logicalOr.ts.trap @@ -1,7 +1,7 @@ #10000=@"/logicalOr.ts;sourcefile" -files(#10000,"/logicalOr.ts","logicalOr","ts",0) +files(#10000,"/logicalOr.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/mappedTypeModifiers.ts.trap b/javascript/extractor/tests/ts/output/trap/mappedTypeModifiers.ts.trap index c04e8462a40..536d31ce459 100644 --- a/javascript/extractor/tests/ts/output/trap/mappedTypeModifiers.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/mappedTypeModifiers.ts.trap @@ -1,7 +1,7 @@ #10000=@"/mappedTypeModifiers.ts;sourcefile" -files(#10000,"/mappedTypeModifiers.ts","mappedTypeModifiers","ts",0) +files(#10000,"/mappedTypeModifiers.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/namespaces.ts.trap b/javascript/extractor/tests/ts/output/trap/namespaces.ts.trap index 5c21d441a15..fa7d897c6ff 100644 --- a/javascript/extractor/tests/ts/output/trap/namespaces.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/namespaces.ts.trap @@ -1,7 +1,7 @@ #10000=@"/namespaces.ts;sourcefile" -files(#10000,"/namespaces.ts","namespaces","ts",0) +files(#10000,"/namespaces.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/nestedNamespace.ts.trap b/javascript/extractor/tests/ts/output/trap/nestedNamespace.ts.trap index b47c45b1ae2..72f567e6ebb 100644 --- a/javascript/extractor/tests/ts/output/trap/nestedNamespace.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/nestedNamespace.ts.trap @@ -1,7 +1,7 @@ #10000=@"/nestedNamespace.ts;sourcefile" -files(#10000,"/nestedNamespace.ts","nestedNamespace","ts",0) +files(#10000,"/nestedNamespace.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/nobody.ts.trap b/javascript/extractor/tests/ts/output/trap/nobody.ts.trap index 1aa25844b45..44a32603e09 100644 --- a/javascript/extractor/tests/ts/output/trap/nobody.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/nobody.ts.trap @@ -1,7 +1,7 @@ #10000=@"/nobody.ts;sourcefile" -files(#10000,"/nobody.ts","nobody","ts",0) +files(#10000,"/nobody.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/objectLiteralAccessor.ts.trap b/javascript/extractor/tests/ts/output/trap/objectLiteralAccessor.ts.trap index feb4e8fb3d9..4ee94b2a313 100644 --- a/javascript/extractor/tests/ts/output/trap/objectLiteralAccessor.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/objectLiteralAccessor.ts.trap @@ -1,7 +1,7 @@ #10000=@"/objectLiteralAccessor.ts;sourcefile" -files(#10000,"/objectLiteralAccessor.ts","objectLiteralAccessor","ts",0) +files(#10000,"/objectLiteralAccessor.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/omitted.ts.trap b/javascript/extractor/tests/ts/output/trap/omitted.ts.trap index 35d92b897fd..ad6845df6f8 100644 --- a/javascript/extractor/tests/ts/output/trap/omitted.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/omitted.ts.trap @@ -1,7 +1,7 @@ #10000=@"/omitted.ts;sourcefile" -files(#10000,"/omitted.ts","omitted","ts",0) +files(#10000,"/omitted.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/optionalChaining.ts.trap b/javascript/extractor/tests/ts/output/trap/optionalChaining.ts.trap index 3e819798690..754aae68649 100644 --- a/javascript/extractor/tests/ts/output/trap/optionalChaining.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/optionalChaining.ts.trap @@ -1,7 +1,7 @@ #10000=@"/optionalChaining.ts;sourcefile" -files(#10000,"/optionalChaining.ts","optionalChaining","ts",0) +files(#10000,"/optionalChaining.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/privateField.ts.trap b/javascript/extractor/tests/ts/output/trap/privateField.ts.trap index 5fca9ab2ec7..334f1de6f83 100644 --- a/javascript/extractor/tests/ts/output/trap/privateField.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/privateField.ts.trap @@ -1,7 +1,7 @@ #10000=@"/privateField.ts;sourcefile" -files(#10000,"/privateField.ts","privateField","ts",0) +files(#10000,"/privateField.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/regexp.ts.trap b/javascript/extractor/tests/ts/output/trap/regexp.ts.trap index f461efc6f39..9b26fb5f75a 100644 --- a/javascript/extractor/tests/ts/output/trap/regexp.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/regexp.ts.trap @@ -1,7 +1,7 @@ #10000=@"/regexp.ts;sourcefile" -files(#10000,"/regexp.ts","regexp","ts",0) +files(#10000,"/regexp.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/restPatternWithDefault.ts.trap b/javascript/extractor/tests/ts/output/trap/restPatternWithDefault.ts.trap index ca7c7ca97bc..53629b31304 100644 --- a/javascript/extractor/tests/ts/output/trap/restPatternWithDefault.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/restPatternWithDefault.ts.trap @@ -1,7 +1,7 @@ #10000=@"/restPatternWithDefault.ts;sourcefile" -files(#10000,"/restPatternWithDefault.ts","restPatternWithDefault","ts",0) +files(#10000,"/restPatternWithDefault.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/templates.ts.trap b/javascript/extractor/tests/ts/output/trap/templates.ts.trap index f0040b384d9..5193508e1ed 100644 --- a/javascript/extractor/tests/ts/output/trap/templates.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/templates.ts.trap @@ -1,7 +1,7 @@ #10000=@"/templates.ts;sourcefile" -files(#10000,"/templates.ts","templates","ts",0) +files(#10000,"/templates.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/thisparameter.ts.trap b/javascript/extractor/tests/ts/output/trap/thisparameter.ts.trap index ba715d4498f..0e766cf77b9 100644 --- a/javascript/extractor/tests/ts/output/trap/thisparameter.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/thisparameter.ts.trap @@ -1,7 +1,7 @@ #10000=@"/thisparameter.ts;sourcefile" -files(#10000,"/thisparameter.ts","thisparameter","ts",0) +files(#10000,"/thisparameter.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/tryfinally.ts.trap b/javascript/extractor/tests/ts/output/trap/tryfinally.ts.trap index f65dd18d42c..d3c660c7d6e 100644 --- a/javascript/extractor/tests/ts/output/trap/tryfinally.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/tryfinally.ts.trap @@ -1,7 +1,7 @@ #10000=@"/tryfinally.ts;sourcefile" -files(#10000,"/tryfinally.ts","tryfinally","ts",0) +files(#10000,"/tryfinally.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/tsx.tsx.trap b/javascript/extractor/tests/ts/output/trap/tsx.tsx.trap index 64533b92396..3bcca05687c 100644 --- a/javascript/extractor/tests/ts/output/trap/tsx.tsx.trap +++ b/javascript/extractor/tests/ts/output/trap/tsx.tsx.trap @@ -1,7 +1,7 @@ #10000=@"/tsx.tsx;sourcefile" -files(#10000,"/tsx.tsx","tsx","tsx",0) +files(#10000,"/tsx.tsx") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/typeannotations.ts.trap b/javascript/extractor/tests/ts/output/trap/typeannotations.ts.trap index d1186ba2a40..ccedb72e42f 100644 --- a/javascript/extractor/tests/ts/output/trap/typeannotations.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/typeannotations.ts.trap @@ -1,7 +1,7 @@ #10000=@"/typeannotations.ts;sourcefile" -files(#10000,"/typeannotations.ts","typeannotations","ts",0) +files(#10000,"/typeannotations.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/unicode.ts.trap b/javascript/extractor/tests/ts/output/trap/unicode.ts.trap index 5eb51f0c4b5..749725d9a46 100644 --- a/javascript/extractor/tests/ts/output/trap/unicode.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/unicode.ts.trap @@ -1,7 +1,7 @@ #10000=@"/unicode.ts;sourcefile" -files(#10000,"/unicode.ts","unicode","ts",0) +files(#10000,"/unicode.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/unicodeId.ts.trap b/javascript/extractor/tests/ts/output/trap/unicodeId.ts.trap index 52a8099534a..d5655de7c32 100644 --- a/javascript/extractor/tests/ts/output/trap/unicodeId.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/unicodeId.ts.trap @@ -1,7 +1,7 @@ #10000=@"/unicodeId.ts;sourcefile" -files(#10000,"/unicodeId.ts","unicodeId","ts",0) +files(#10000,"/unicodeId.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/ts/output/trap/uninstantiatedNamespace.ts.trap b/javascript/extractor/tests/ts/output/trap/uninstantiatedNamespace.ts.trap index ad546cdc0fa..7cc993e08e3 100644 --- a/javascript/extractor/tests/ts/output/trap/uninstantiatedNamespace.ts.trap +++ b/javascript/extractor/tests/ts/output/trap/uninstantiatedNamespace.ts.trap @@ -1,7 +1,7 @@ #10000=@"/uninstantiatedNamespace.ts;sourcefile" -files(#10000,"/uninstantiatedNamespace.ts","uninstantiatedNamespace","ts",0) +files(#10000,"/uninstantiatedNamespace.ts") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/v8/output/trap/tst.js.trap b/javascript/extractor/tests/v8/output/trap/tst.js.trap index 9496f4b4533..4eb025bd9d3 100644 --- a/javascript/extractor/tests/v8/output/trap/tst.js.trap +++ b/javascript/extractor/tests/v8/output/trap/tst.js.trap @@ -1,7 +1,7 @@ #10000=@"/tst.js;sourcefile" -files(#10000,"/tst.js","tst","js",0) +files(#10000,"/tst.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/variables/output/trap/const.js.trap b/javascript/extractor/tests/variables/output/trap/const.js.trap index 8ad53c7fbb1..6b4f41cd0b8 100644 --- a/javascript/extractor/tests/variables/output/trap/const.js.trap +++ b/javascript/extractor/tests/variables/output/trap/const.js.trap @@ -1,7 +1,7 @@ #10000=@"/const.js;sourcefile" -files(#10000,"/const.js","const","js",0) +files(#10000,"/const.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/variables/output/trap/finally.js.trap b/javascript/extractor/tests/variables/output/trap/finally.js.trap index d0926525120..0b20c915634 100644 --- a/javascript/extractor/tests/variables/output/trap/finally.js.trap +++ b/javascript/extractor/tests/variables/output/trap/finally.js.trap @@ -1,7 +1,7 @@ #10000=@"/finally.js;sourcefile" -files(#10000,"/finally.js","finally","js",0) +files(#10000,"/finally.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/variables/output/trap/switch.js.trap b/javascript/extractor/tests/variables/output/trap/switch.js.trap index 2e0c2f85544..9127e02831a 100644 --- a/javascript/extractor/tests/variables/output/trap/switch.js.trap +++ b/javascript/extractor/tests/variables/output/trap/switch.js.trap @@ -1,7 +1,7 @@ #10000=@"/switch.js;sourcefile" -files(#10000,"/switch.js","switch","js",0) +files(#10000,"/switch.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/variables/output/trap/try.js.trap b/javascript/extractor/tests/variables/output/trap/try.js.trap index f6c502439ed..062b593b72d 100644 --- a/javascript/extractor/tests/variables/output/trap/try.js.trap +++ b/javascript/extractor/tests/variables/output/trap/try.js.trap @@ -1,7 +1,7 @@ #10000=@"/try.js;sourcefile" -files(#10000,"/try.js","try","js",0) +files(#10000,"/try.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/variables/output/trap/variables.js.trap b/javascript/extractor/tests/variables/output/trap/variables.js.trap index b4c5c6f4b23..ebc1bc00e19 100644 --- a/javascript/extractor/tests/variables/output/trap/variables.js.trap +++ b/javascript/extractor/tests/variables/output/trap/variables.js.trap @@ -1,7 +1,7 @@ #10000=@"/variables.js;sourcefile" -files(#10000,"/variables.js","variables","js",0) +files(#10000,"/variables.js") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/vue/output/trap/test.vue.trap b/javascript/extractor/tests/vue/output/trap/test.vue.trap index 8b2e7e79195..c5be0998bc7 100644 --- a/javascript/extractor/tests/vue/output/trap/test.vue.trap +++ b/javascript/extractor/tests/vue/output/trap/test.vue.trap @@ -1,7 +1,7 @@ #10000=@"/test.vue;sourcefile" -files(#10000,"/test.vue","test","vue",0) +files(#10000,"/test.vue") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/yaml/output/trap/bad_1022_1_1.yml.trap b/javascript/extractor/tests/yaml/output/trap/bad_1022_1_1.yml.trap index 1f29931bddd..378c0faa514 100644 --- a/javascript/extractor/tests/yaml/output/trap/bad_1022_1_1.yml.trap +++ b/javascript/extractor/tests/yaml/output/trap/bad_1022_1_1.yml.trap @@ -1,7 +1,7 @@ #10000=@"/bad_1022_1_1.yml;sourcefile" -files(#10000,"/bad_1022_1_1.yml","bad_1022_1_1","yml",0) +files(#10000,"/bad_1022_1_1.yml") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/yaml/output/trap/cyclic.yaml.trap b/javascript/extractor/tests/yaml/output/trap/cyclic.yaml.trap index 3e6350b33ee..7410b8eef7d 100644 --- a/javascript/extractor/tests/yaml/output/trap/cyclic.yaml.trap +++ b/javascript/extractor/tests/yaml/output/trap/cyclic.yaml.trap @@ -1,7 +1,7 @@ #10000=@"/cyclic.yaml;sourcefile" -files(#10000,"/cyclic.yaml","cyclic","yaml",0) +files(#10000,"/cyclic.yaml") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/yaml/output/trap/good_1021_1_1.yml.trap b/javascript/extractor/tests/yaml/output/trap/good_1021_1_1.yml.trap index 14263fee8ae..b55660d0043 100644 --- a/javascript/extractor/tests/yaml/output/trap/good_1021_1_1.yml.trap +++ b/javascript/extractor/tests/yaml/output/trap/good_1021_1_1.yml.trap @@ -1,7 +1,7 @@ #10000=@"/good_1021_1_1.yml;sourcefile" -files(#10000,"/good_1021_1_1.yml","good_1021_1_1","yml",0) +files(#10000,"/good_1021_1_1.yml") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/yaml/output/trap/good_1_1_1021.yml.trap b/javascript/extractor/tests/yaml/output/trap/good_1_1_1021.yml.trap index 1dfc7236156..b41b53c33f3 100644 --- a/javascript/extractor/tests/yaml/output/trap/good_1_1_1021.yml.trap +++ b/javascript/extractor/tests/yaml/output/trap/good_1_1_1021.yml.trap @@ -1,7 +1,7 @@ #10000=@"/good_1_1_1021.yml;sourcefile" -files(#10000,"/good_1_1_1021.yml","good_1_1_1021","yml",0) +files(#10000,"/good_1_1_1021.yml") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/yaml/output/trap/merge.yaml.trap b/javascript/extractor/tests/yaml/output/trap/merge.yaml.trap index 7fda9367720..b083875f4e0 100644 --- a/javascript/extractor/tests/yaml/output/trap/merge.yaml.trap +++ b/javascript/extractor/tests/yaml/output/trap/merge.yaml.trap @@ -1,7 +1,7 @@ #10000=@"/merge.yaml;sourcefile" -files(#10000,"/merge.yaml","merge","yaml",0) +files(#10000,"/merge.yaml") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/yaml/output/trap/orig.yml.trap b/javascript/extractor/tests/yaml/output/trap/orig.yml.trap index fe8da2ea09f..b7b72d425d5 100644 --- a/javascript/extractor/tests/yaml/output/trap/orig.yml.trap +++ b/javascript/extractor/tests/yaml/output/trap/orig.yml.trap @@ -1,7 +1,7 @@ #10000=@"/orig.yml;sourcefile" -files(#10000,"/orig.yml","orig","yml",0) +files(#10000,"/orig.yml") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/yaml/output/trap/tst.yml.trap b/javascript/extractor/tests/yaml/output/trap/tst.yml.trap index e119ddc19aa..cc92c452438 100644 --- a/javascript/extractor/tests/yaml/output/trap/tst.yml.trap +++ b/javascript/extractor/tests/yaml/output/trap/tst.yml.trap @@ -1,7 +1,7 @@ #10000=@"/tst.yml;sourcefile" -files(#10000,"/tst.yml","tst","yml",0) +files(#10000,"/tst.yml") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/extractor/tests/yaml/output/trap/x_bad_1_1_1022.yml.trap b/javascript/extractor/tests/yaml/output/trap/x_bad_1_1_1022.yml.trap index 4bab6838e52..5f6a0e1e0e3 100644 --- a/javascript/extractor/tests/yaml/output/trap/x_bad_1_1_1022.yml.trap +++ b/javascript/extractor/tests/yaml/output/trap/x_bad_1_1_1022.yml.trap @@ -1,7 +1,7 @@ #10000=@"/x_bad_1_1_1022.yml;sourcefile" -files(#10000,"/x_bad_1_1_1022.yml","x_bad_1_1_1022","yml",0) +files(#10000,"/x_bad_1_1_1022.yml") #10001=@"/;folder" -folders(#10001,"/","") +folders(#10001,"/") containerparent(#10001,#10000) #10002=@"loc,{#10000},0,0,0,0" locations_default(#10002,#10000,0,0,0,0) diff --git a/javascript/ql/src/Declarations/UnusedVariable.qll b/javascript/ql/lib/Declarations/UnusedVariable.qll similarity index 100% rename from javascript/ql/src/Declarations/UnusedVariable.qll rename to javascript/ql/lib/Declarations/UnusedVariable.qll diff --git a/javascript/ql/src/Expressions/DOMProperties.qll b/javascript/ql/lib/Expressions/DOMProperties.qll similarity index 100% rename from javascript/ql/src/Expressions/DOMProperties.qll rename to javascript/ql/lib/Expressions/DOMProperties.qll diff --git a/javascript/ql/src/Expressions/ExprHasNoEffect.qll b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll similarity index 100% rename from javascript/ql/src/Expressions/ExprHasNoEffect.qll rename to javascript/ql/lib/Expressions/ExprHasNoEffect.qll diff --git a/javascript/ql/src/LanguageFeatures/UnusedIndexVariable.qll b/javascript/ql/lib/LanguageFeatures/UnusedIndexVariable.qll similarity index 100% rename from javascript/ql/src/LanguageFeatures/UnusedIndexVariable.qll rename to javascript/ql/lib/LanguageFeatures/UnusedIndexVariable.qll diff --git a/javascript/ql/lib/javascript.qll b/javascript/ql/lib/javascript.qll index eed95edcd7d..3a0aa544348 100644 --- a/javascript/ql/lib/javascript.qll +++ b/javascript/ql/lib/javascript.qll @@ -78,6 +78,7 @@ import semmle.javascript.frameworks.ComposedFunctions import semmle.javascript.frameworks.Classnames import semmle.javascript.frameworks.ClassValidator import semmle.javascript.frameworks.ClientRequests +import semmle.javascript.frameworks.Clipboard import semmle.javascript.frameworks.ClosureLibrary import semmle.javascript.frameworks.CookieLibraries import semmle.javascript.frameworks.Credentials diff --git a/javascript/ql/lib/semmle/javascript/Base64.qll b/javascript/ql/lib/semmle/javascript/Base64.qll index f2e91a7060c..b9743fb4ec2 100644 --- a/javascript/ql/lib/semmle/javascript/Base64.qll +++ b/javascript/ql/lib/semmle/javascript/Base64.qll @@ -6,16 +6,12 @@ import javascript module Base64 { /** A call to a base64 encoder. */ - class Encode extends DataFlow::Node { - Encode::Range encode; - - Encode() { this = encode } - + class Encode extends DataFlow::Node instanceof Encode::Range { /** Gets the input passed to the encoder. */ - DataFlow::Node getInput() { result = encode.getInput() } + DataFlow::Node getInput() { result = super.getInput() } /** Gets the base64-encoded output of the encoder. */ - DataFlow::Node getOutput() { result = encode.getOutput() } + DataFlow::Node getOutput() { result = super.getOutput() } } module Encode { @@ -34,16 +30,12 @@ module Base64 { } /** A call to a base64 decoder. */ - class Decode extends DataFlow::Node { - Decode::Range encode; - - Decode() { this = encode } - + class Decode extends DataFlow::Node instanceof Decode::Range { /** Gets the base64-encoded input passed to the decoder. */ - DataFlow::Node getInput() { result = encode.getInput() } + DataFlow::Node getInput() { result = super.getInput() } /** Gets the output of the decoder. */ - DataFlow::Node getOutput() { result = encode.getOutput() } + DataFlow::Node getOutput() { result = super.getOutput() } } module Decode { diff --git a/javascript/ql/lib/semmle/javascript/Classes.qll b/javascript/ql/lib/semmle/javascript/Classes.qll index 82e782c4690..eccc005e273 100644 --- a/javascript/ql/lib/semmle/javascript/Classes.qll +++ b/javascript/ql/lib/semmle/javascript/Classes.qll @@ -258,6 +258,13 @@ class ClassDefinition extends @class_definition, ClassOrInterface, AST::ValueNod } override string getAPrimaryQlClass() { result = "ClassDefinition" } + + /** + * Gets a static initializer of this class, if any. + */ + BlockStmt getAStaticInitializerBlock() { + exists(StaticInitializer init | init.getDeclaringClass() = this | result = init.getBody()) + } } /** @@ -1134,6 +1141,18 @@ class ParameterField extends FieldDeclaration, @parameter_field { override TypeAnnotation getTypeAnnotation() { result = getParameter().getTypeAnnotation() } } +/** + * A static initializer in a class. + */ +class StaticInitializer extends MemberDefinition, @static_initializer { + /** + * Gets the body of the static initializer. + */ + BlockStmt getBody() { result.getParent() = this } + + override Expr getNameExpr() { none() } +} + /** * A call signature declared in an interface. * diff --git a/javascript/ql/lib/semmle/javascript/Closure.qll b/javascript/ql/lib/semmle/javascript/Closure.qll index d517b4a07ea..37934f30af0 100644 --- a/javascript/ql/lib/semmle/javascript/Closure.qll +++ b/javascript/ql/lib/semmle/javascript/Closure.qll @@ -8,15 +8,11 @@ module Closure { /** * A reference to a Closure namespace. */ - class ClosureNamespaceRef extends DataFlow::Node { - ClosureNamespaceRef::Range range; - - ClosureNamespaceRef() { this = range } - + class ClosureNamespaceRef extends DataFlow::Node instanceof ClosureNamespaceRef::Range { /** * Gets the namespace being referenced. */ - string getClosureNamespace() { result = range.getClosureNamespace() } + string getClosureNamespace() { result = super.getClosureNamespace() } } module ClosureNamespaceRef { @@ -36,8 +32,7 @@ module Closure { /** * A data flow node that returns the value of a closure namespace. */ - class ClosureNamespaceAccess extends ClosureNamespaceRef { - override ClosureNamespaceAccess::Range range; + class ClosureNamespaceAccess extends ClosureNamespaceRef instanceof ClosureNamespaceAccess::Range { } module ClosureNamespaceAccess { @@ -81,7 +76,7 @@ module Closure { * A top-level call to `goog.provide`. */ class ClosureProvideCall extends ClosureNamespaceRef, DataFlow::MethodCallNode { - override DefaultClosureProvideCall range; + ClosureProvideCall() { this instanceof DefaultClosureProvideCall } } /** @@ -95,7 +90,7 @@ module Closure { * A call to `goog.require`. */ class ClosureRequireCall extends ClosureNamespaceAccess, DataFlow::MethodCallNode { - override DefaultClosureRequireCall range; + ClosureRequireCall() { this instanceof DefaultClosureRequireCall } } /** @@ -112,7 +107,7 @@ module Closure { * A top-level call to `goog.module` or `goog.declareModuleId`. */ class ClosureModuleDeclaration extends ClosureNamespaceRef, DataFlow::MethodCallNode { - override DefaultClosureModuleDeclaration range; + ClosureModuleDeclaration() { this instanceof DefaultClosureModuleDeclaration } } private GlobalVariable googVariable() { variables(result, "goog", any(GlobalScope sc)) } diff --git a/javascript/ql/lib/semmle/javascript/DOM.qll b/javascript/ql/lib/semmle/javascript/DOM.qll index 4956502d7d2..5d721858de8 100644 --- a/javascript/ql/lib/semmle/javascript/DOM.qll +++ b/javascript/ql/lib/semmle/javascript/DOM.qll @@ -450,6 +450,8 @@ module DOM { result = domValueRef(DataFlow::TypeTracker::end()) or result.hasUnderlyingType("Element") + or + result.hasUnderlyingType(any(string s | s.matches("HTML%Element"))) } module LocationSource { diff --git a/javascript/ql/lib/semmle/javascript/Files.qll b/javascript/ql/lib/semmle/javascript/Files.qll index 7fe0201f940..f08b0ecbd8d 100644 --- a/javascript/ql/lib/semmle/javascript/Files.qll +++ b/javascript/ql/lib/semmle/javascript/Files.qll @@ -34,7 +34,7 @@ abstract class Container extends @container { /** * Gets a URL representing the location of this container. * - * For more information see [Providing URLs](https://help.semmle.com/QL/learn-ql/ql/locations.html#providing-urls). + * For more information see [Providing URLs](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/#providing-urls). */ abstract string getURL(); @@ -156,7 +156,7 @@ abstract class Container extends @container { /** A folder. */ class Folder extends Container, @folder { - override string getAbsolutePath() { folders(this, result, _) } + override string getAbsolutePath() { folders(this, result) } /** Gets the file or subfolder in this folder that has the given `name`, if any. */ Container getChildContainer(string name) { @@ -203,7 +203,7 @@ class File extends Container, @file { */ Location getLocation() { hasLocation(this, result) } - override string getAbsolutePath() { files(this, result, _, _, _) } + override string getAbsolutePath() { files(this, result) } /** Gets the number of lines in this file. */ int getNumberOfLines() { result = sum(int loc | numlines(this, loc, _, _) | loc) } diff --git a/javascript/ql/lib/semmle/javascript/InclusionTests.qll b/javascript/ql/lib/semmle/javascript/InclusionTests.qll index 2d0cf1752a4..b714c670b19 100644 --- a/javascript/ql/lib/semmle/javascript/InclusionTests.qll +++ b/javascript/ql/lib/semmle/javascript/InclusionTests.qll @@ -16,16 +16,12 @@ private import javascript * ~A.indexOf(B) * ``` */ -class InclusionTest extends DataFlow::Node { - InclusionTest::Range range; - - InclusionTest() { this = range } - +class InclusionTest extends DataFlow::Node instanceof InclusionTest::Range { /** Gets the `A` in `A.includes(B)`. */ - DataFlow::Node getContainerNode() { result = range.getContainerNode() } + DataFlow::Node getContainerNode() { result = super.getContainerNode() } /** Gets the `B` in `A.includes(B)`. */ - DataFlow::Node getContainedNode() { result = range.getContainedNode() } + DataFlow::Node getContainedNode() { result = super.getContainedNode() } /** * Gets the polarity of the check. @@ -33,7 +29,7 @@ class InclusionTest extends DataFlow::Node { * If the polarity is `false` the check returns `true` if the container does not contain * the given element. */ - boolean getPolarity() { result = range.getPolarity() } + boolean getPolarity() { result = super.getPolarity() } } module InclusionTest { diff --git a/javascript/ql/lib/semmle/javascript/Locations.qll b/javascript/ql/lib/semmle/javascript/Locations.qll index bdf83fb395a..9bf5c341915 100644 --- a/javascript/ql/lib/semmle/javascript/Locations.qll +++ b/javascript/ql/lib/semmle/javascript/Locations.qll @@ -6,7 +6,7 @@ import javascript * A location as given by a file, a start line, a start column, * an end line, and an end column. * - * For more information about locations see [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * For more information about locations see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ class Location extends @location { /** Gets the file for this location. */ @@ -70,7 +70,7 @@ class Location extends @location { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/javascript/ql/lib/semmle/javascript/MembershipCandidates.qll b/javascript/ql/lib/semmle/javascript/MembershipCandidates.qll index 89573252ab5..fe46eff040e 100644 --- a/javascript/ql/lib/semmle/javascript/MembershipCandidates.qll +++ b/javascript/ql/lib/semmle/javascript/MembershipCandidates.qll @@ -9,27 +9,23 @@ import javascript * * Additional candidates can be added by subclassing `MembershipCandidate::Range` */ -class MembershipCandidate extends DataFlow::Node { - MembershipCandidate::Range range; - - MembershipCandidate() { this = range } - +class MembershipCandidate extends DataFlow::Node instanceof MembershipCandidate::Range { /** * Gets the expression that performs the membership test, if any. */ - DataFlow::Node getTest() { result = range.getTest() } + DataFlow::Node getTest() { result = super.getTest() } /** * Gets a string that this candidate is tested against, if * it can be determined. */ - string getAMemberString() { result = range.getAMemberString() } + string getAMemberString() { result = super.getAMemberString() } /** * Gets a node that this candidate is tested against, if * it can be determined. */ - DataFlow::Node getAMemberNode() { result = range.getAMemberNode() } + DataFlow::Node getAMemberNode() { result = super.getAMemberNode() } /** * Gets the polarity of the test. @@ -37,7 +33,7 @@ class MembershipCandidate extends DataFlow::Node { * If the polarity is `false` the test returns `true` if the * collection does not contain this candidate. */ - boolean getTestPolarity() { result = range.getTestPolarity() } + boolean getTestPolarity() { result = super.getTestPolarity() } } /** diff --git a/javascript/ql/lib/semmle/javascript/PackageExports.qll b/javascript/ql/lib/semmle/javascript/PackageExports.qll index 97009adc065..5d67b958d28 100644 --- a/javascript/ql/lib/semmle/javascript/PackageExports.qll +++ b/javascript/ql/lib/semmle/javascript/PackageExports.qll @@ -30,7 +30,11 @@ private DataFlow::Node getAValueExportedByPackage() { getAnExportFromModule(any(PackageJSON pack | exists(pack.getPackageName())).getMainModule()) or // module.exports.bar.baz = result; - result = getAValueExportedByPackage().(DataFlow::PropWrite).getRhs() + exists(DataFlow::PropWrite write | + write = getAValueExportedByPackage() and + write.getPropertyName() = publicPropertyName() and + result = write.getRhs() + ) or // class Foo { // bar() {} // <- result @@ -39,15 +43,17 @@ private DataFlow::Node getAValueExportedByPackage() { exists(DataFlow::SourceNode callee | callee = getAValueExportedByPackage().(DataFlow::NewNode).getCalleeNode().getALocalSource() | - result = callee.getAPropertyRead("prototype").getAPropertyWrite().getRhs() + result = callee.getAPropertyRead("prototype").getAPropertyWrite(publicPropertyName()).getRhs() or - result = callee.(DataFlow::ClassNode).getAnInstanceMethod() + result = callee.(DataFlow::ClassNode).getInstanceMethod(publicPropertyName()) and + not isPrivateMethodDeclaration(result) ) or result = getAValueExportedByPackage().getALocalSource() or // Nested property reads. - result = getAValueExportedByPackage().(DataFlow::SourceNode).getAPropertyReference() + result = + getAValueExportedByPackage().(DataFlow::SourceNode).getAPropertyReference(publicPropertyName()) or // module.exports.foo = require("./other-module.js"); exists(Module mod | @@ -61,9 +67,12 @@ private DataFlow::Node getAValueExportedByPackage() { // static baz() {} // <- result // constructor() {} // <- result // }; - exists(DataFlow::ClassNode cla | cla = getAValueExportedByPackage() | - result = cla.getAnInstanceMethod() or - result = cla.getAStaticMethod() or + exists(DataFlow::ClassNode cla | + cla = getAValueExportedByPackage() and + not isPrivateMethodDeclaration(result) + | + result = cla.getInstanceMethod(publicPropertyName()) or + result = cla.getStaticMethod(publicPropertyName()) or result = cla.getConstructor() ) or @@ -120,7 +129,8 @@ private DataFlow::Node getAValueExportedByPackage() { or // Object.defineProperty exists(CallToObjectDefineProperty call | - [call, call.getBaseObject()] = getAValueExportedByPackage() + [call, call.getBaseObject()] = getAValueExportedByPackage() and + call.getPropertyName() = publicPropertyName() | result = call.getPropertyDescriptor().getALocalSource().getAPropertyReference("value") or @@ -164,9 +174,31 @@ private DataFlow::Node getAValueExportedByPackage() { * Gets an exported node from the module `mod`. */ private DataFlow::Node getAnExportFromModule(Module mod) { - result = mod.getAnExportedValue(_) + result = mod.getAnExportedValue(publicPropertyName()) or result = mod.getABulkExportedNode() or result.analyze().getAValue() = TAbstractModuleObject(mod) } + +/** + * Gets a property name that we consider to be public. + * + * This only allows properties whose first character is a letter or number. + */ +bindingset[result] +private string publicPropertyName() { result.regexpMatch("[a-zA-Z0-9].*") } + +/** + * Holds if the given function is part of a private (or protected) method declaration. + */ +private predicate isPrivateMethodDeclaration(DataFlow::FunctionNode func) { + exists(MethodDeclaration decl | + decl.getBody() = func.getFunction() and + ( + decl.isPrivate() + or + decl.isProtected() + ) + ) +} diff --git a/javascript/ql/lib/semmle/javascript/Regexp.qll b/javascript/ql/lib/semmle/javascript/Regexp.qll index 5eb20b5f915..877db09c9ea 100644 --- a/javascript/ql/lib/semmle/javascript/Regexp.qll +++ b/javascript/ql/lib/semmle/javascript/Regexp.qll @@ -258,8 +258,8 @@ class RegExpConstant extends RegExpTerm, @regexp_constant { class RegExpCharEscape extends RegExpEscape, RegExpConstant, @regexp_char_escape { override predicate isCharacter() { not ( - // unencodable characters are represented as '?' in the database - getValue() = "?" and + // unencodable characters are represented as '?' or \uFFFD in the database + getValue() = ["?", 65533.toUnicode()] and exists(string s | s = toString().toLowerCase() | // only Unicode escapes give rise to unencodable characters s.matches("\\\\u%") and diff --git a/javascript/ql/lib/semmle/javascript/RestrictedLocations.qll b/javascript/ql/lib/semmle/javascript/RestrictedLocations.qll index 8c45ad533ba..9fd70ca1230 100644 --- a/javascript/ql/lib/semmle/javascript/RestrictedLocations.qll +++ b/javascript/ql/lib/semmle/javascript/RestrictedLocations.qll @@ -14,7 +14,7 @@ class FirstLineOf extends Locatable { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -43,7 +43,7 @@ class LastLineOf extends Locatable { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/javascript/ql/lib/semmle/javascript/SSA.qll b/javascript/ql/lib/semmle/javascript/SSA.qll index d55f29ee1a8..11acc7d284c 100644 --- a/javascript/ql/lib/semmle/javascript/SSA.qll +++ b/javascript/ql/lib/semmle/javascript/SSA.qll @@ -417,7 +417,7 @@ class SsaVariable extends TSsaDefinition { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -482,7 +482,7 @@ class SsaDefinition extends TSsaDefinition { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ abstract predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/javascript/ql/lib/semmle/javascript/StringOps.qll b/javascript/ql/lib/semmle/javascript/StringOps.qll index a82ffe95a13..53390c4230d 100644 --- a/javascript/ql/lib/semmle/javascript/StringOps.qll +++ b/javascript/ql/lib/semmle/javascript/StringOps.qll @@ -8,20 +8,16 @@ module StringOps { /** * A expression that is equivalent to `A.startsWith(B)` or `!A.startsWith(B)`. */ - class StartsWith extends DataFlow::Node { - StartsWith::Range range; - - StartsWith() { range = this } - + class StartsWith extends DataFlow::Node instanceof StartsWith::Range { /** * Gets the `A` in `A.startsWith(B)`. */ - DataFlow::Node getBaseString() { result = range.getBaseString() } + DataFlow::Node getBaseString() { result = super.getBaseString() } /** * Gets the `B` in `A.startsWith(B)`. */ - DataFlow::Node getSubstring() { result = range.getSubstring() } + DataFlow::Node getSubstring() { result = super.getSubstring() } /** * Gets the polarity of the check. @@ -29,7 +25,7 @@ module StringOps { * If the polarity is `false` the check returns `true` if the string does not start * with the given substring. */ - boolean getPolarity() { result = range.getPolarity() } + boolean getPolarity() { result = super.getPolarity() } } module StartsWith { @@ -237,20 +233,16 @@ module StringOps { /** * An expression that is equivalent to `A.endsWith(B)` or `!A.endsWith(B)`. */ - class EndsWith extends DataFlow::Node { - EndsWith::Range range; - - EndsWith() { this = range } - + class EndsWith extends DataFlow::Node instanceof EndsWith::Range { /** * Gets the `A` in `A.startsWith(B)`. */ - DataFlow::Node getBaseString() { result = range.getBaseString() } + DataFlow::Node getBaseString() { result = super.getBaseString() } /** * Gets the `B` in `A.startsWith(B)`. */ - DataFlow::Node getSubstring() { result = range.getSubstring() } + DataFlow::Node getSubstring() { result = super.getSubstring() } /** * Gets the polarity if the check. @@ -258,7 +250,7 @@ module StringOps { * If the polarity is `false` the check returns `true` if the string does not end * with the given substring. */ - boolean getPolarity() { result = range.getPolarity() } + boolean getPolarity() { result = super.getPolarity() } } module EndsWith { @@ -662,18 +654,14 @@ module StringOps { * if (!match) { ... } // <--- 'match' is the RegExpTest * ``` */ - class RegExpTest extends DataFlow::Node { - RegExpTest::Range range; - - RegExpTest() { this = range } - + class RegExpTest extends DataFlow::Node instanceof RegExpTest::Range { /** * Gets the AST of the regular expression used in the test, if it can be seen locally. */ RegExpTerm getRegExp() { result = getRegExpOperand().getALocalSource().(DataFlow::RegExpCreationNode).getRoot() or - result = range.getRegExpOperand(true).asExpr().(StringLiteral).asRegExp() + result = super.getRegExpOperand(true).asExpr().(StringLiteral).asRegExp() } /** @@ -681,12 +669,12 @@ module StringOps { * * In some cases this represents a string value being coerced to a RegExp object. */ - DataFlow::Node getRegExpOperand() { result = range.getRegExpOperand(_) } + DataFlow::Node getRegExpOperand() { result = super.getRegExpOperand(_) } /** * Gets the data flow node corresponding to the string being tested against the regular expression. */ - DataFlow::Node getStringOperand() { result = range.getStringOperand() } + DataFlow::Node getStringOperand() { result = super.getStringOperand() } /** * Gets the return value indicating that the string matched the regular expression. @@ -694,7 +682,7 @@ module StringOps { * For example, for `regexp.exec(str) == null`, the polarity is `false`, and for * `regexp.exec(str) != null` the polarity is `true`. */ - boolean getPolarity() { result = range.getPolarity() } + boolean getPolarity() { result = super.getPolarity() } } /** diff --git a/javascript/ql/lib/semmle/javascript/XML.qll b/javascript/ql/lib/semmle/javascript/XML.qll index 5871fed0ddd..4c762f4bf65 100755 --- a/javascript/ql/lib/semmle/javascript/XML.qll +++ b/javascript/ql/lib/semmle/javascript/XML.qll @@ -24,7 +24,7 @@ class XMLLocatable extends @xmllocatable, TXMLLocatable { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/javascript/ql/lib/semmle/javascript/dataflow/AbstractValues.qll b/javascript/ql/lib/semmle/javascript/dataflow/AbstractValues.qll index 5e4776cfdbf..b887972503e 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/AbstractValues.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/AbstractValues.qll @@ -109,7 +109,7 @@ class AbstractValue extends TAbstractValue { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `f`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo(string f, int startline, int startcolumn, int endline, int endcolumn) { f = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0 diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index 40747f56f39..f9a8f45b3a3 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -947,7 +947,7 @@ private predicate exploratoryFlowStep( isAdditionalLoadStoreStep(pred, succ, _, _, cfg) or // the following three disjuncts taken together over-approximate flow through // higher-order calls - callback(pred, succ) or + exploratoryCallbackStep(pred, succ) or succ = pred.(DataFlow::FunctionNode).getAParameter() or exploratoryBoundInvokeStep(pred, succ) } @@ -1776,7 +1776,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index c9061b5c5b9..a756f03bec7 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -148,7 +148,7 @@ module DataFlow { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ cached predicate hasLocationInfo( @@ -1591,7 +1591,7 @@ module DataFlow { */ predicate localFieldStep(DataFlow::Node pred, DataFlow::Node succ) { exists(ClassNode cls, string prop | - pred = cls.getAReceiverNode().getAPropertyWrite(prop).getRhs() or + pred = cls.getADirectSuperClass*().getAReceiverNode().getAPropertyWrite(prop).getRhs() or pred = cls.getInstanceMethod(prop) | succ = cls.getAReceiverNode().getAPropertyRead(prop) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll b/javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll index 7c832e20aed..c697c43dcce 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll @@ -702,13 +702,9 @@ class ArrayCreationNode extends DataFlow::ValueNode, DataFlow::SourceNode { * define(["fs"], function(fs) { ... }); // AMD module * ``` */ -class ModuleImportNode extends DataFlow::SourceNode { - ModuleImportNode::Range range; - - ModuleImportNode() { this = range } - +class ModuleImportNode extends DataFlow::SourceNode instanceof ModuleImportNode::Range { /** Gets the path of the imported module. */ - string getPath() { result = range.getPath() } + string getPath() { result = super.getPath() } } module ModuleImportNode { @@ -844,25 +840,21 @@ module MemberKind { * * Additional patterns can be recognized as class nodes, by extending `DataFlow::ClassNode::Range`. */ -class ClassNode extends DataFlow::SourceNode { - ClassNode::Range impl; - - ClassNode() { this = impl } - +class ClassNode extends DataFlow::SourceNode instanceof ClassNode::Range { /** * Gets the unqualified name of the class, if it has one or one can be determined from the context. */ - string getName() { result = impl.getName() } + string getName() { result = super.getName() } /** * Gets a description of the class. */ - string describe() { result = impl.describe() } + string describe() { result = super.describe() } /** * Gets the constructor function of this class. */ - FunctionNode getConstructor() { result = impl.getConstructor() } + FunctionNode getConstructor() { result = super.getConstructor() } /** * Gets an instance method declared in this class, with the given name, if any. @@ -870,7 +862,7 @@ class ClassNode extends DataFlow::SourceNode { * Does not include methods from superclasses. */ FunctionNode getInstanceMethod(string name) { - result = impl.getInstanceMember(name, MemberKind::method()) + result = super.getInstanceMember(name, MemberKind::method()) } /** @@ -880,7 +872,7 @@ class ClassNode extends DataFlow::SourceNode { * * Does not include methods from superclasses. */ - FunctionNode getAnInstanceMethod() { result = impl.getAnInstanceMember(MemberKind::method()) } + FunctionNode getAnInstanceMethod() { result = super.getAnInstanceMember(MemberKind::method()) } /** * Gets the instance method, getter, or setter with the given name and kind. @@ -888,7 +880,7 @@ class ClassNode extends DataFlow::SourceNode { * Does not include members from superclasses. */ FunctionNode getInstanceMember(string name, MemberKind kind) { - result = impl.getInstanceMember(name, kind) + result = super.getInstanceMember(name, kind) } /** @@ -896,31 +888,31 @@ class ClassNode extends DataFlow::SourceNode { * * Does not include members from superclasses. */ - FunctionNode getAnInstanceMember(MemberKind kind) { result = impl.getAnInstanceMember(kind) } + FunctionNode getAnInstanceMember(MemberKind kind) { result = super.getAnInstanceMember(kind) } /** * Gets an instance method, getter, or setter declared in this class. * * Does not include members from superclasses. */ - FunctionNode getAnInstanceMember() { result = impl.getAnInstanceMember(_) } + FunctionNode getAnInstanceMember() { result = super.getAnInstanceMember(_) } /** * Gets the static method declared in this class with the given name. */ - FunctionNode getStaticMethod(string name) { result = impl.getStaticMethod(name) } + FunctionNode getStaticMethod(string name) { result = super.getStaticMethod(name) } /** * Gets a static method declared in this class. * * The constructor is not considered a static method. */ - FunctionNode getAStaticMethod() { result = impl.getAStaticMethod() } + FunctionNode getAStaticMethod() { result = super.getAStaticMethod() } /** * Gets a dataflow node that refers to the superclass of this class. */ - DataFlow::Node getASuperClassNode() { result = impl.getASuperClassNode() } + DataFlow::Node getASuperClassNode() { result = super.getASuperClassNode() } /** * Gets a direct super class of this class. @@ -1066,13 +1058,13 @@ class ClassNode extends DataFlow::SourceNode { * Gets the type annotation for the field `fieldName`, if any. */ TypeAnnotation getFieldTypeAnnotation(string fieldName) { - result = impl.getFieldTypeAnnotation(fieldName) + result = super.getFieldTypeAnnotation(fieldName) } /** * Gets a decorator applied to this class. */ - DataFlow::Node getADecorator() { result = impl.getADecorator() } + DataFlow::Node getADecorator() { result = super.getADecorator() } } module ClassNode { @@ -1358,11 +1350,7 @@ module ClassNode { * _.partial(fn, x, y, z) * ``` */ -class PartialInvokeNode extends DataFlow::Node { - PartialInvokeNode::Range range; - - PartialInvokeNode() { this = range } - +class PartialInvokeNode extends DataFlow::Node instanceof PartialInvokeNode::Range { /** Gets a node holding a callback invoked by this partial invocation node. */ DataFlow::Node getACallbackNode() { isPartialArgument(result, _, _) @@ -1374,26 +1362,26 @@ class PartialInvokeNode extends DataFlow::Node { * Holds if `argument` is passed as argument `index` to the function in `callback`. */ predicate isPartialArgument(DataFlow::Node callback, DataFlow::Node argument, int index) { - range.isPartialArgument(callback, argument, index) + super.isPartialArgument(callback, argument, index) } /** * Gets a node referring to a bound version of `callback` with `boundArgs` arguments bound. */ DataFlow::SourceNode getBoundFunction(DataFlow::Node callback, int boundArgs) { - result = range.getBoundFunction(callback, boundArgs) + result = super.getBoundFunction(callback, boundArgs) } /** * Gets the node holding the receiver to be passed to the bound function, if specified. */ - DataFlow::Node getBoundReceiver() { result = range.getBoundReceiver(_) } + DataFlow::Node getBoundReceiver() { result = super.getBoundReceiver(_) } /** * Gets the node holding the receiver to be passed to the bound function, if specified. */ DataFlow::Node getBoundReceiver(DataFlow::Node callback) { - result = range.getBoundReceiver(callback) + result = super.getBoundReceiver(callback) } } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TrackedNodes.qll b/javascript/ql/lib/semmle/javascript/dataflow/TrackedNodes.qll index 28d9a432341..58ecb5ae54b 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TrackedNodes.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TrackedNodes.qll @@ -154,7 +154,7 @@ private module NodeTracking { or basicLoadStep(mid, nd, _) or - callback(mid, nd) + exploratoryCallbackStep(mid, nd) or nd = mid.(DataFlow::FunctionNode).getAParameter() ) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll index 50575460da7..6ba9ed3cfa2 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSteps.qll @@ -434,7 +434,7 @@ private module CachedSteps { * invocation. */ cached - predicate callback(DataFlow::Node arg, DataFlow::SourceNode cb) { + predicate exploratoryCallbackStep(DataFlow::Node arg, DataFlow::SourceNode cb) { Stages::TypeTracking::ref() and exists(DataFlow::InvokeNode invk, DataFlow::ParameterNode cbParm, DataFlow::Node cbArg | arg = invk.getAnArgument() and @@ -444,12 +444,24 @@ private module CachedSteps { ) or exists(DataFlow::ParameterNode cbParm, DataFlow::Node cbArg | - callback(arg, cbParm) and + exploratoryCallbackStep(arg, cbParm) and callStep(cbArg, cbParm) and cb.flowsTo(cbArg) ) } + /** Gets a function that flows to `parameter` via one or more parameter-passing steps. */ + cached + DataFlow::FunctionNode getACallbackSource(DataFlow::ParameterNode parameter) { + Stages::TypeTracking::ref() and + callStep(result.getALocalUse(), parameter) + or + exists(DataFlow::ParameterNode mid | + callStep(mid.getALocalUse(), parameter) and + result = getACallbackSource(mid) + ) + } + /** * Holds if `f` may return `base`, which has a write of property `prop` with right-hand side `rhs`. */ diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/StepSummary.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/StepSummary.qll index 14a6cdf0d1e..065bb1b75a8 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/StepSummary.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/StepSummary.qll @@ -156,6 +156,13 @@ private module Cached { succ = fun.getAnInvocation() ) ) + or + // Add 'return' steps from callback arguments to callback parameters + exists(DataFlow::ParameterNode parameter, int i | + pred = parameter.getAnInvocation().getArgument(i) and + succ = getACallbackSource(parameter).getParameter(i) and + summary = ReturnStep() + ) } } diff --git a/javascript/ql/src/filters/ClassifyFiles.qll b/javascript/ql/lib/semmle/javascript/filters/ClassifyFiles.qll similarity index 100% rename from javascript/ql/src/filters/ClassifyFiles.qll rename to javascript/ql/lib/semmle/javascript/filters/ClassifyFiles.qll diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Cheerio.qll b/javascript/ql/lib/semmle/javascript/frameworks/Cheerio.qll index b9705aebfbd..beffe148ee3 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Cheerio.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Cheerio.qll @@ -32,10 +32,7 @@ module Cheerio { * Creation of `cheerio` object, a collection of virtual DOM elements * with an interface similar to that of a jQuery object. */ - class CheerioObjectCreation extends DataFlow::SourceNode { - CheerioObjectCreation::Range range; - - CheerioObjectCreation() { this = range } + class CheerioObjectCreation extends DataFlow::SourceNode instanceof CheerioObjectCreation::Range { } module CheerioObjectCreation { diff --git a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll index 3d496f28177..82670947d3d 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll @@ -18,25 +18,21 @@ import javascript * To model additional APIs, extend `ClientRequest::Range` and implement its abstract member * predicates. */ -class ClientRequest extends DataFlow::InvokeNode { - ClientRequest::Range self; - - ClientRequest() { this = self } - +class ClientRequest extends DataFlow::InvokeNode instanceof ClientRequest::Range { /** * Gets the URL of the request. */ - DataFlow::Node getUrl() { result = self.getUrl() } + DataFlow::Node getUrl() { result = super.getUrl() } /** * Gets the host of the request. */ - DataFlow::Node getHost() { result = self.getHost() } + DataFlow::Node getHost() { result = super.getHost() } /** * Gets a node that contributes to the data-part this request. */ - DataFlow::Node getADataNode() { result = self.getADataNode() } + DataFlow::Node getADataNode() { result = super.getADataNode() } /** * Gets a data flow node that refers to some representation of the response, possibly @@ -60,7 +56,7 @@ class ClientRequest extends DataFlow::InvokeNode { * - Any value provided by custom implementations of `ClientRequest::Range`. */ DataFlow::Node getAResponseDataNode(string responseType, boolean promise) { - result = self.getAResponseDataNode(responseType, promise) + result = super.getAResponseDataNode(responseType, promise) } /** @@ -72,7 +68,7 @@ class ClientRequest extends DataFlow::InvokeNode { /** * Gets a data-flow node that determines where in the file-system the result of the request should be saved. */ - DataFlow::Node getASavePath() { result = self.getASavePath() } + DataFlow::Node getASavePath() { result = super.getASavePath() } } deprecated class CustomClientRequest = ClientRequest::Range; diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Clipboard.qll b/javascript/ql/lib/semmle/javascript/frameworks/Clipboard.qll new file mode 100644 index 00000000000..be7e414eb28 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/frameworks/Clipboard.qll @@ -0,0 +1,63 @@ +/** + * Provides predicates for reasoning about clipboard data. + */ + +import javascript + +/** + * Gets a jQuery "paste" event. + * E.g. `e` in `$("#foo").on("paste", function(e) { ... })`. + */ +private DataFlow::SourceNode jQueryPasteEvent(DataFlow::TypeTracker t) { + t.start() and + exists(DataFlow::CallNode call | + call = JQuery::objectRef().getAMethodCall(["bind", "on", "live", "one", "delegate"]) and + call.getArgument(0).mayHaveStringValue("paste") + | + result = call.getCallback(call.getNumArgument() - 1).getParameter(0) + ) + or + exists(DataFlow::TypeTracker t2 | result = jQueryPasteEvent(t2).track(t2, t)) +} + +/** + * Gets a DOM "paste" event. + * E.g. `e` in `document.addEventListener("paste", e => { ... })`. + */ +private DataFlow::SourceNode pasteEvent(DataFlow::TypeTracker t) { + t.start() and + exists(DataFlow::CallNode call | call = DOM::domValueRef().getAMemberCall("addEventListener") | + call.getArgument(0).mayHaveStringValue("paste") and + result = call.getCallback(1).getParameter(0) + ) + or + t.start() and + result = jQueryPasteEvent(DataFlow::TypeTracker::end()).getAPropertyRead("originalEvent") + or + exists(DataFlow::TypeTracker t2 | result = pasteEvent(t2).track(t2, t)) +} + +/** + * Gets a reference to the clipboardData DataTransfer object. + * https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent/clipboardData + */ +private DataFlow::SourceNode clipboardDataTransferSource(DataFlow::TypeTracker t) { + t.start() and + exists(DataFlow::PropRead read | read = result | + read.getPropertyName() = "clipboardData" and + read.getBase().getALocalSource() = pasteEvent(DataFlow::TypeTracker::end()) + ) + or + exists(DataFlow::TypeTracker t2 | result = clipboardDataTransferSource(t2).track(t2, t)) +} + +/** + * A reference to data from the clipboard. Seen as a source for DOM-based XSS. + */ +private class ClipboardSource extends RemoteFlowSource { + ClipboardSource() { + this = clipboardDataTransferSource(DataFlow::TypeTracker::end()).getAMethodCall("getData") + } + + override string getSourceType() { result = "Clipboard data" } +} diff --git a/javascript/ql/lib/semmle/javascript/frameworks/ComposedFunctions.qll b/javascript/ql/lib/semmle/javascript/frameworks/ComposedFunctions.qll index b1016ce56be..6887758b064 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/ComposedFunctions.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/ComposedFunctions.qll @@ -8,18 +8,14 @@ import javascript * A call to a function that constructs a function composition `f(g(h(...)))` from a * series of functions `f, g, h, ...`. */ -class FunctionCompositionCall extends DataFlow::CallNode { - FunctionCompositionCall::Range range; - - FunctionCompositionCall() { this = range } - +class FunctionCompositionCall extends DataFlow::CallNode instanceof FunctionCompositionCall::Range { /** * Gets the `i`th function in the composition `f(g(h(...)))`, counting from left to right. * * Note that this is the opposite of the order in which the function are invoked, * that is, `g` occurs later than `f` in `f(g(...))` but is invoked before `f`. */ - DataFlow::Node getOperandNode(int i) { result = range.getOperandNode(i) } + DataFlow::Node getOperandNode(int i) { result = super.getOperandNode(i) } /** Gets a node holding one of the functions to be composed. */ final DataFlow::Node getAnOperandNode() { result = getOperandNode(_) } @@ -38,7 +34,7 @@ class FunctionCompositionCall extends DataFlow::CallNode { final DataFlow::FunctionNode getAnOperandFunction() { result = getOperandFunction(_) } /** Gets the number of functions being composed. */ - int getNumOperand() { result = range.getNumOperand() } + int getNumOperand() { result = super.getNumOperand() } } /** diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Electron.qll b/javascript/ql/lib/semmle/javascript/frameworks/Electron.qll index 7d099932738..2c326e7cd31 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Electron.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Electron.qll @@ -182,7 +182,7 @@ module Electron { * A Node.js-style HTTP or HTTPS request made using an Electron module. */ class ElectronClientRequest extends NodeJSLib::NodeJSClientRequest { - override ElectronClientRequest::Range self; + ElectronClientRequest() { this instanceof ElectronClientRequest::Range } } module ElectronClientRequest { diff --git a/javascript/ql/lib/semmle/javascript/frameworks/EventEmitter.qll b/javascript/ql/lib/semmle/javascript/frameworks/EventEmitter.qll index f044d69524d..67b746e4473 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/EventEmitter.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/EventEmitter.qll @@ -68,40 +68,32 @@ module EventEmitter { * An EventEmitter instance that implements the EventEmitter API. * Extend EventEmitter::Range to mark something as being an EventEmitter. */ -class EventEmitter extends DataFlow::Node { - EventEmitter::Range range; - - EventEmitter() { this = range } -} +class EventEmitter extends DataFlow::Node instanceof EventEmitter::Range { } /** * A registration of an event handler on an EventEmitter. */ -class EventRegistration extends DataFlow::Node { - EventRegistration::Range range; - - EventRegistration() { this = range } - +class EventRegistration extends DataFlow::Node instanceof EventRegistration::Range { /** Gets the EventEmitter that the event handler is registered on. */ - final EventEmitter getEmitter() { result = range.getEmitter() } + final EventEmitter getEmitter() { result = super.getEmitter() } /** Gets the name of the channel if possible. */ - string getChannel() { result = range.getChannel() } + string getChannel() { result = super.getChannel() } /** Gets the `i`th parameter in the event handler. */ - DataFlow::Node getReceivedItem(int i) { result = range.getReceivedItem(i) } + DataFlow::Node getReceivedItem(int i) { result = super.getReceivedItem(i) } /** * Gets a value that is returned by the event handler. * The default implementation is that no value can be returned. */ - DataFlow::Node getAReturnedValue() { result = range.getAReturnedValue() } + DataFlow::Node getAReturnedValue() { result = super.getAReturnedValue() } /** * Get a dispatch that this event handler can return a value to. * The default implementation is that there exists no such dispatch. */ - EventDispatch getAReturnDispatch() { result = range.getAReturnDispatch() } + EventDispatch getAReturnDispatch() { result = super.getAReturnDispatch() } } module EventRegistration { @@ -140,26 +132,22 @@ module EventRegistration { /** * A dispatch of an event on an EventEmitter. */ -class EventDispatch extends DataFlow::Node { - EventDispatch::Range range; - - EventDispatch() { this = range } - +class EventDispatch extends DataFlow::Node instanceof EventDispatch::Range { /** Gets the emitter that the event dispatch happens on. */ - EventEmitter getEmitter() { result = range.getEmitter() } + EventEmitter getEmitter() { result = super.getEmitter() } /** Gets the name of the channel if possible. */ - string getChannel() { result = range.getChannel() } + string getChannel() { result = super.getChannel() } /** Gets the `i`th argument that is send to the event handler. */ - DataFlow::Node getSentItem(int i) { result = range.getSentItem(i) } + DataFlow::Node getSentItem(int i) { result = super.getSentItem(i) } /** * Get an EventRegistration that this event dispatch can send an event to. * The default implementation is that the emitters of the dispatch and registration have to be equal. * Channels are by default ignored. */ - EventRegistration getAReceiver() { result = range.getAReceiver() } + EventRegistration getAReceiver() { result = super.getAReceiver() } } module EventDispatch { diff --git a/javascript/ql/lib/semmle/javascript/frameworks/HTTP.qll b/javascript/ql/lib/semmle/javascript/frameworks/HTTP.qll index 9475c32eeab..94f9c4245b1 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/HTTP.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/HTTP.qll @@ -540,16 +540,12 @@ module HTTP { /** * An object that contains one or more potential route handlers. */ - class RouteHandlerCandidateContainer extends DataFlow::Node { - RouteHandlerCandidateContainer::Range self; - - RouteHandlerCandidateContainer() { this = self } - + class RouteHandlerCandidateContainer extends DataFlow::Node instanceof RouteHandlerCandidateContainer::Range { /** * Gets the route handler in this container that is accessed at `access`. */ DataFlow::SourceNode getRouteHandler(DataFlow::SourceNode access) { - result = self.getRouteHandler(access) + result = super.getRouteHandler(access) } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll index fa753220005..43fde9639c2 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll @@ -825,9 +825,7 @@ module NodeJSLib { * A data flow node that is an HTTP or HTTPS client request made by a Node.js application, * for example `http.request(url)`. */ - class NodeJSClientRequest extends ClientRequest { - override NodeJSClientRequest::Range self; - } + class NodeJSClientRequest extends ClientRequest instanceof NodeJSClientRequest::Range { } module NodeJSClientRequest { /** diff --git a/javascript/ql/lib/semmle/javascript/frameworks/PropertyProjection.qll b/javascript/ql/lib/semmle/javascript/frameworks/PropertyProjection.qll index e3fe62be164..730669abfaf 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/PropertyProjection.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/PropertyProjection.qll @@ -14,20 +14,16 @@ import javascript * To model additional APIs, extend `PropertyProjection::Range` and implement its abstract member * predicates. */ -class PropertyProjection extends DataFlow::CallNode { - PropertyProjection::Range self; - - PropertyProjection() { this = self } - +class PropertyProjection extends DataFlow::CallNode instanceof PropertyProjection::Range { /** * Gets the argument for the object to project properties from, such as `o` in `_.get(o, 'a.b')`. */ - DataFlow::Node getObject() { result = self.getObject() } + DataFlow::Node getObject() { result = super.getObject() } /** * Gets an argument that selects the properties to project, such as `'a.b'` in `_.get(o, 'a.b')`. */ - DataFlow::Node getASelector() { result = self.getASelector() } + DataFlow::Node getASelector() { result = super.getASelector() } /** * Holds if this call returns the value of a single projected property, as opposed to an object that can contain multiple projected properties. @@ -36,7 +32,7 @@ class PropertyProjection extends DataFlow::CallNode { * - This predicate holds for `_.get({a: 'b'}, 'a')`, which returns `'b'`, * - This predicate does not hold for `_.pick({a: 'b', c: 'd'}}, 'a')`, which returns `{a: 'b'}`, */ - predicate isSingletonProjection() { self.isSingletonProjection() } + predicate isSingletonProjection() { super.isSingletonProjection() } } module PropertyProjection { diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Redux.qll b/javascript/ql/lib/semmle/javascript/frameworks/Redux.qll index ad3f985c397..d26982cef7f 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Redux.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Redux.qll @@ -56,11 +56,7 @@ module Redux { /** * Creation of a redux store, usually via a call to `createStore`. */ - class StoreCreation extends DataFlow::SourceNode { - StoreCreation::Range range; - - StoreCreation() { this = range } - + class StoreCreation extends DataFlow::SourceNode instanceof StoreCreation::Range { /** Gets a reference to the store. */ DataFlow::SourceNode ref() { result = asApiNode().getAUse() } @@ -68,7 +64,7 @@ module Redux { API::Node asApiNode() { result.getAnImmediateUse() = this } /** Gets the data flow node holding the root reducer for this store. */ - DataFlow::Node getReducerArg() { result = range.getReducerArg() } + DataFlow::Node getReducerArg() { result = super.getReducerArg() } /** Gets a data flow node referring to the root reducer. */ DataFlow::SourceNode getAReducerSource() { result = getReducerArg().(ReducerArg).getASource() } @@ -423,13 +419,9 @@ module Redux { * Some action creators dispatch the action to a store, while for others, the value is returned and it is simply assumed to be dispatched * at some point. We model all action creators as if they dispatch the action they create. */ - class ActionCreator extends DataFlow::SourceNode { - ActionCreator::Range range; - - ActionCreator() { this = range } - + class ActionCreator extends DataFlow::SourceNode instanceof ActionCreator::Range { /** Gets the `type` property of actions created by this action creator, if it is known. */ - string getTypeTag() { result = range.getTypeTag() } + string getTypeTag() { result = super.getTypeTag() } /** * Gets the middleware function that transforms arguments passed to this function into the @@ -442,7 +434,7 @@ module Redux { * the action payload. Otherwise, the return value is the payload itself. */ DataFlow::FunctionNode getMiddlewareFunction(boolean async) { - result = range.getMiddlewareFunction(async) + result = super.getMiddlewareFunction(async) } /** Gets a data flow node referring to this action creator. */ diff --git a/javascript/ql/lib/semmle/javascript/frameworks/ShellJS.qll b/javascript/ql/lib/semmle/javascript/frameworks/ShellJS.qll index 3fc1644fdfd..4ba780b0480 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/ShellJS.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/ShellJS.qll @@ -14,13 +14,9 @@ module ShellJS { } /** A member of the `shelljs` library. */ - class Member extends DataFlow::SourceNode { - Member::Range range; - - Member() { this = range } - + class Member extends DataFlow::SourceNode instanceof Member::Range { /** Gets the name of `shelljs` member being referenced, such as `cat` in `shelljs.cat`. */ - string getName() { result = range.getName() } + string getName() { result = super.getName() } } module Member { diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Vue.qll b/javascript/ql/lib/semmle/javascript/frameworks/Vue.qll index 0ee45aefa11..2101f29fdab 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Vue.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Vue.qll @@ -151,7 +151,7 @@ module Vue { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -640,7 +640,7 @@ module Vue { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/javascript/ql/lib/semmle/javascript/frameworks/xUnit.qll b/javascript/ql/lib/semmle/javascript/frameworks/xUnit.qll index a897cb486aa..e07bd29b3c3 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/xUnit.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/xUnit.qll @@ -131,7 +131,7 @@ class XUnitAnnotation extends Expr { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/javascript/ql/lib/semmle/javascript/security/CryptoAlgorithms.qll b/javascript/ql/lib/semmle/javascript/security/CryptoAlgorithms.qll index d9f25b42c9a..a5bfd6696be 100644 --- a/javascript/ql/lib/semmle/javascript/security/CryptoAlgorithms.qll +++ b/javascript/ql/lib/semmle/javascript/security/CryptoAlgorithms.qll @@ -28,7 +28,11 @@ private module AlgorithmNames { name = "SHA256" or name = "SHA384" or name = "SHA512" or - name = "SHA3" + name = "SHA3" or + name = "SHA3224" or + name = "SHA3256" or + name = "SHA3384" or + name = "SHA3512" } predicate isWeakHashingAlgorithm(string name) { diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomCustomizations.qll index efedee1477d..d9222337d34 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomCustomizations.qll @@ -30,7 +30,7 @@ module XssThroughDom { /** * Gets a DOM property name that could store user-controlled data. */ - string unsafeDomPropertyName() { result = ["innerText", "textContent", "value", "name"] } + string unsafeDomPropertyName() { result = ["innerText", "textContent", "value", "name", "src"] } /** * A source for text from the DOM from a JQuery method call. diff --git a/javascript/ql/lib/semmlecode.javascript.dbscheme b/javascript/ql/lib/semmlecode.javascript.dbscheme index 9ca3692b65f..e54b35a8a12 100644 --- a/javascript/ql/lib/semmlecode.javascript.dbscheme +++ b/javascript/ql/lib/semmlecode.javascript.dbscheme @@ -20,21 +20,11 @@ numlines(int element_id: @sourceline ref, int num_comment: int ref ); - -/* - fromSource(0) = unknown, - fromSource(1) = from source, - fromSource(2) = from library -*/ files(unique int id: @file, - varchar(900) name: string ref, - varchar(900) simple: string ref, - varchar(900) ext: string ref, - int fromSource: int ref); + varchar(900) name: string ref); folders(unique int id: @folder, - varchar(900) name: string ref, - varchar(900) simple: string ref); + varchar(900) name: string ref); @container = @folder | @file ; @@ -156,7 +146,7 @@ stmt_containers (unique int stmt: @stmt ref, jump_targets (unique int jump: @stmt ref, int target: @stmt ref); -@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr; +@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr | @static_initializer; @stmt_container = @toplevel | @function | @namespace_declaration | @external_module_declaration | @global_augmentation_declaration; case @stmt.kind of @@ -531,6 +521,7 @@ case @property.kind of | 7 = @enum_member | 8 = @proper_field | 9 = @parameter_field +| 10 = @static_initializer ; @property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration; diff --git a/javascript/ql/lib/semmlecode.javascript.dbscheme.stats b/javascript/ql/lib/semmlecode.javascript.dbscheme.stats index 80d8efb088a..ed051cd16ac 100644 --- a/javascript/ql/lib/semmlecode.javascript.dbscheme.stats +++ b/javascript/ql/lib/semmlecode.javascript.dbscheme.stats @@ -774,6 +774,10 @@ 2693 +@static_initializer +100 + + @local_type_access 25491 @@ -4840,18 +4844,6 @@ name 6457 - -simple -4188 - - -ext -4 - - -fromSource -1 - @@ -4871,54 +4863,6 @@ -id -simple - - -12 - - -1 -2 -6457 - - - - - - -id -ext - - -12 - - -1 -2 -6457 - - - - - - -id -fromSource - - -12 - - -1 -2 -6457 - - - - - - name id @@ -4934,316 +4878,6 @@ - -name -simple - - -12 - - -1 -2 -6457 - - - - - - -name -ext - - -12 - - -1 -2 -6457 - - - - - - -name -fromSource - - -12 - - -1 -2 -6457 - - - - - - -simple -id - - -12 - - -1 -2 -3423 - - -2 -3 -507 - - -3 -305 -258 - - - - - - -simple -name - - -12 - - -1 -2 -3423 - - -2 -3 -507 - - -3 -305 -258 - - - - - - -simple -ext - - -12 - - -1 -2 -3960 - - -2 -4 -228 - - - - - - -simple -fromSource - - -12 - - -1 -2 -4188 - - - - - - -ext -id - - -12 - - -21 -22 -1 - - -480 -481 -1 - - -756 -757 -1 - - -5200 -5201 -1 - - - - - - -ext -name - - -12 - - -21 -22 -1 - - -480 -481 -1 - - -756 -757 -1 - - -5200 -5201 -1 - - - - - - -ext -simple - - -12 - - -21 -22 -1 - - -118 -119 -1 - - -428 -429 -1 - - -3858 -3859 -1 - - - - - - -ext -fromSource - - -12 - - -1 -2 -4 - - - - - - -fromSource -id - - -12 - - -6457 -6458 -1 - - - - - - -fromSource -name - - -12 - - -6457 -6458 -1 - - - - - - -fromSource -simple - - -12 - - -4188 -4189 -1 - - - - - - -fromSource -ext - - -12 - - -4 -5 -1 - - - - - @@ -5259,10 +4893,6 @@ name 1590 - -simple -645 - @@ -5282,22 +4912,6 @@ -id -simple - - -12 - - -1 -2 -1590 - - - - - - name id @@ -5313,84 +4927,6 @@ - -name -simple - - -12 - - -1 -2 -1590 - - - - - - -simple -id - - -12 - - -1 -2 -425 - - -2 -3 -127 - - -3 -6 -58 - - -6 -113 -35 - - - - - - -simple -name - - -12 - - -1 -2 -425 - - -2 -3 -127 - - -3 -6 -58 - - -6 -113 -35 - - - - - diff --git a/javascript/ql/src/AlertSuppression.ql b/javascript/ql/src/AlertSuppression.ql index 43bfe3a020c..4366eb3ba7e 100644 --- a/javascript/ql/src/AlertSuppression.ql +++ b/javascript/ql/src/AlertSuppression.ql @@ -63,7 +63,7 @@ class SuppressionScope extends @locatable { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/javascript/ql/src/Comments/CommentedOut.qll b/javascript/ql/src/Comments/CommentedOut.qll index 21cc27388ab..a0d00d70642 100644 --- a/javascript/ql/src/Comments/CommentedOut.qll +++ b/javascript/ql/src/Comments/CommentedOut.qll @@ -127,7 +127,7 @@ class CommentedOutCode extends Comment { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/javascript/ql/src/Declarations/UnusedProperty.ql b/javascript/ql/src/Declarations/UnusedProperty.ql index e9e38409bcb..19d43a09db2 100644 --- a/javascript/ql/src/Declarations/UnusedProperty.ql +++ b/javascript/ql/src/Declarations/UnusedProperty.ql @@ -10,7 +10,7 @@ import javascript import semmle.javascript.dataflow.LocalObjects -import UnusedVariable +import Declarations.UnusedVariable import UnusedParameter import Expressions.ExprHasNoEffect diff --git a/javascript/ql/src/Declarations/UnusedVariable.ql b/javascript/ql/src/Declarations/UnusedVariable.ql index 773672197a1..8fb405a7cf9 100644 --- a/javascript/ql/src/Declarations/UnusedVariable.ql +++ b/javascript/ql/src/Declarations/UnusedVariable.ql @@ -10,7 +10,7 @@ */ import javascript -import UnusedVariable +import Declarations.UnusedVariable /** * Holds if `v` is mentioned in a JSDoc comment in the same file, and that file diff --git a/javascript/ql/src/Expressions/ExprHasNoEffect.ql b/javascript/ql/src/Expressions/ExprHasNoEffect.ql index 5ef6be7ba14..f0cd3addcb6 100644 --- a/javascript/ql/src/Expressions/ExprHasNoEffect.ql +++ b/javascript/ql/src/Expressions/ExprHasNoEffect.ql @@ -13,7 +13,7 @@ */ import javascript -import ExprHasNoEffect +import Expressions.ExprHasNoEffect import semmle.javascript.RestrictedLocations from Expr e diff --git a/javascript/ql/src/Expressions/MisspelledIdentifier.ql b/javascript/ql/src/Expressions/MisspelledIdentifier.ql index 6eba0ede3a7..342f4072277 100644 --- a/javascript/ql/src/Expressions/MisspelledIdentifier.ql +++ b/javascript/ql/src/Expressions/MisspelledIdentifier.ql @@ -22,7 +22,7 @@ class IdentifierPart extends string { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/javascript/ql/src/Expressions/SelfAssignment.ql b/javascript/ql/src/Expressions/SelfAssignment.ql index 50d55a50bfe..6aab4c46bb2 100644 --- a/javascript/ql/src/Expressions/SelfAssignment.ql +++ b/javascript/ql/src/Expressions/SelfAssignment.ql @@ -12,7 +12,7 @@ */ import Clones -import DOMProperties +import Expressions.DOMProperties /** * Gets a description of expression `e`, which is assumed to be the left-hand @@ -43,5 +43,8 @@ where // exclude DOM properties not isDOMProperty(e.(PropAccess).getPropertyName()) and // exclude self-assignments that have been inserted to satisfy the TypeScript JS-checker - not e.getAssignment().getParent().(ExprStmt).getDocumentation().getATag().getTitle() = "type" + not e.getAssignment().getParent().(ExprStmt).getDocumentation().getATag().getTitle() = "type" and + // exclude self-assignments in speculatively parsed template files + // named arguments may be incorrectly parsed as assignments + not e.getTopLevel() instanceof Templating::TemplateTopLevel select e.getParent(), "This expression assigns " + dsc + " to itself." diff --git a/javascript/ql/src/LanguageFeatures/EmptyArrayInit.ql b/javascript/ql/src/LanguageFeatures/EmptyArrayInit.ql index eaa9ffdc1fc..9c95ec9365d 100644 --- a/javascript/ql/src/LanguageFeatures/EmptyArrayInit.ql +++ b/javascript/ql/src/LanguageFeatures/EmptyArrayInit.ql @@ -29,7 +29,7 @@ class OmittedArrayElement extends ArrayExpr { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/javascript/ql/src/LanguageFeatures/SpuriousArguments.ql b/javascript/ql/src/LanguageFeatures/SpuriousArguments.ql index b2e86524e20..29f62648956 100644 --- a/javascript/ql/src/LanguageFeatures/SpuriousArguments.ql +++ b/javascript/ql/src/LanguageFeatures/SpuriousArguments.ql @@ -68,7 +68,7 @@ class SpuriousArguments extends Expr { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/javascript/ql/src/LanguageFeatures/UnusedIndexVariable.ql b/javascript/ql/src/LanguageFeatures/UnusedIndexVariable.ql index da3c1d4b4cf..ba39738a777 100644 --- a/javascript/ql/src/LanguageFeatures/UnusedIndexVariable.ql +++ b/javascript/ql/src/LanguageFeatures/UnusedIndexVariable.ql @@ -10,7 +10,7 @@ */ import javascript -import UnusedIndexVariable +import LanguageFeatures.UnusedIndexVariable from RelationalComparison rel, Variable idx, Variable v where unusedIndexVariable(rel, idx, v) diff --git a/javascript/ql/src/Security/CWE-020/UselessRegExpCharacterEscape.ql b/javascript/ql/src/Security/CWE-020/UselessRegExpCharacterEscape.ql index 29933de7848..7bd17135e33 100644 --- a/javascript/ql/src/Security/CWE-020/UselessRegExpCharacterEscape.ql +++ b/javascript/ql/src/Security/CWE-020/UselessRegExpCharacterEscape.ql @@ -67,7 +67,7 @@ class RegExpPatternMistake extends TRegExpPatternMistake { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/javascript/ql/src/Security/CWE-078/IndirectCommandInjection.ql b/javascript/ql/src/Security/CWE-078/IndirectCommandInjection.ql index eb29b56cac3..7520a95ed9c 100644 --- a/javascript/ql/src/Security/CWE-078/IndirectCommandInjection.ql +++ b/javascript/ql/src/Security/CWE-078/IndirectCommandInjection.ql @@ -5,7 +5,7 @@ * command-line injection vulnerabilities. * @kind path-problem * @problem.severity warning - * @security-severity 9.8 + * @security-severity 6.3 * @precision medium * @id js/indirect-command-line-injection * @tags correctness diff --git a/javascript/ql/src/Security/CWE-078/ShellCommandInjectionFromEnvironment.ql b/javascript/ql/src/Security/CWE-078/ShellCommandInjectionFromEnvironment.ql index b4bd735d493..cad1039814c 100644 --- a/javascript/ql/src/Security/CWE-078/ShellCommandInjectionFromEnvironment.ql +++ b/javascript/ql/src/Security/CWE-078/ShellCommandInjectionFromEnvironment.ql @@ -4,7 +4,7 @@ * environment may cause subtle bugs or vulnerabilities. * @kind path-problem * @problem.severity warning - * @security-severity 9.8 + * @security-severity 6.3 * @precision high * @id js/shell-command-injection-from-environment * @tags correctness diff --git a/javascript/ql/src/Security/CWE-078/UnsafeShellCommandConstruction.ql b/javascript/ql/src/Security/CWE-078/UnsafeShellCommandConstruction.ql index b0b22a96704..e29a75c1163 100644 --- a/javascript/ql/src/Security/CWE-078/UnsafeShellCommandConstruction.ql +++ b/javascript/ql/src/Security/CWE-078/UnsafeShellCommandConstruction.ql @@ -4,7 +4,7 @@ * user to change the meaning of the command. * @kind path-problem * @problem.severity error - * @security-severity 9.8 + * @security-severity 6.3 * @precision high * @id js/shell-command-constructed-from-input * @tags correctness diff --git a/javascript/ql/src/Security/CWE-078/UselessUseOfCat.ql b/javascript/ql/src/Security/CWE-078/UselessUseOfCat.ql index fd29399546a..e0678b4142b 100644 --- a/javascript/ql/src/Security/CWE-078/UselessUseOfCat.ql +++ b/javascript/ql/src/Security/CWE-078/UselessUseOfCat.ql @@ -3,7 +3,7 @@ * @description Using the `cat` process to read a file is unnecessarily complex, inefficient, unportable, and can lead to subtle bugs, or even security vulnerabilities. * @kind problem * @problem.severity error - * @security-severity 9.8 + * @security-severity 6.3 * @precision high * @id js/unnecessary-use-of-cat * @tags correctness diff --git a/javascript/ql/src/Security/CWE-094/CodeInjection.ql b/javascript/ql/src/Security/CWE-094/CodeInjection.ql index 2934107f1bb..fbf39beaca4 100644 --- a/javascript/ql/src/Security/CWE-094/CodeInjection.ql +++ b/javascript/ql/src/Security/CWE-094/CodeInjection.ql @@ -4,11 +4,12 @@ * code execution. * @kind path-problem * @problem.severity error - * @security-severity 6.1 + * @security-severity 9.3 * @precision high * @id js/code-injection * @tags security * external/cwe/cwe-094 + * external/cwe/cwe-095 * external/cwe/cwe-079 * external/cwe/cwe-116 */ diff --git a/javascript/ql/src/Security/CWE-134/TaintedFormatString.ql b/javascript/ql/src/Security/CWE-134/TaintedFormatString.ql index 25cb62bd9b1..06f44703a5d 100644 --- a/javascript/ql/src/Security/CWE-134/TaintedFormatString.ql +++ b/javascript/ql/src/Security/CWE-134/TaintedFormatString.ql @@ -3,7 +3,7 @@ * @description Using external input in format strings can lead to garbled output. * @kind path-problem * @problem.severity warning - * @security-severity 9.3 + * @security-severity 7.3 * @precision high * @id js/tainted-format-string * @tags security diff --git a/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql b/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql index 45e6ab2572c..6abe955c7f0 100644 --- a/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql +++ b/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql @@ -8,6 +8,7 @@ * @id js/exposure-of-private-files * @tags security * external/cwe/cwe-200 + * external/cwe/cwe-548 * @precision high */ diff --git a/javascript/ql/src/Security/CWE-295/DisablingCertificateValidation.ql b/javascript/ql/src/Security/CWE-295/DisablingCertificateValidation.ql index 2f785bace35..0b24235801d 100644 --- a/javascript/ql/src/Security/CWE-295/DisablingCertificateValidation.ql +++ b/javascript/ql/src/Security/CWE-295/DisablingCertificateValidation.ql @@ -7,7 +7,7 @@ * @precision very-high * @id js/disabling-certificate-validation * @tags security - * external/cwe-295 + * external/cwe/cwe-295 */ import javascript diff --git a/javascript/ql/src/Security/CWE-313/PasswordInConfigurationFile.ql b/javascript/ql/src/Security/CWE-313/PasswordInConfigurationFile.ql index 4d534248f45..1418a219698 100644 --- a/javascript/ql/src/Security/CWE-313/PasswordInConfigurationFile.ql +++ b/javascript/ql/src/Security/CWE-313/PasswordInConfigurationFile.ql @@ -10,6 +10,7 @@ * external/cwe/cwe-256 * external/cwe/cwe-260 * external/cwe/cwe-313 + * external/cwe/cwe-522 */ import javascript diff --git a/javascript/ql/src/Security/CWE-834/LoopBoundInjection.ql b/javascript/ql/src/Security/CWE-834/LoopBoundInjection.ql index 028835343c1..638829de15e 100644 --- a/javascript/ql/src/Security/CWE-834/LoopBoundInjection.ql +++ b/javascript/ql/src/Security/CWE-834/LoopBoundInjection.ql @@ -4,10 +4,11 @@ * property can cause indefinite looping. * @kind path-problem * @problem.severity warning - * @security-severity 6.5 + * @security-severity 7.5 * @id js/loop-bound-injection * @tags security * external/cwe/cwe-834 + * external/cwe/cwe-730 * @precision high */ diff --git a/javascript/ql/src/Security/CWE-912/HttpToFileAccess.ql b/javascript/ql/src/Security/CWE-912/HttpToFileAccess.ql index 9a8ac7b4b73..772297dda63 100644 --- a/javascript/ql/src/Security/CWE-912/HttpToFileAccess.ql +++ b/javascript/ql/src/Security/CWE-912/HttpToFileAccess.ql @@ -3,7 +3,7 @@ * @description Writing network data directly to the file system allows arbitrary file upload and might indicate a backdoor. * @kind path-problem * @problem.severity warning - * @security-severity 9.8 + * @security-severity 6.3 * @precision medium * @id js/http-to-file-access * @tags security diff --git a/javascript/ql/src/experimental/Security/CWE-079/ClipboardXss.qhelp b/javascript/ql/src/experimental/Security/CWE-079/ClipboardXss.qhelp deleted file mode 100644 index 302dc170d37..00000000000 --- a/javascript/ql/src/experimental/Security/CWE-079/ClipboardXss.qhelp +++ /dev/null @@ -1,57 +0,0 @@ - - - - -

    -Directly pasting user input from the clipboard to a webpage -without properly sanitizing the input first, allows for a cross-site scripting vulnerability. -

    - - - -

    -To guard against cross-site scripting, consider using contextual output encoding/escaping before -writing user input to the page, or one of the other solutions that are mentioned in the -references. -

    -
    - - -

    -The following example shows a div element whose HTML content comes directly from the clipboard being written to the DOM, -leaving the website vulnerable to cross-site scripting. -

    - -
    - - -
  • -OWASP: -DOM based -XSS Prevention Cheat Sheet. -
  • -
  • -OWASP: -XSS -(Cross Site Scripting) Prevention Cheat Sheet. -
  • -
  • -OWASP -DOM Based XSS. -
  • -
  • -OWASP -Types of Cross-Site -Scripting. -
  • -
  • -Wikipedia: Cross-site scripting. -
  • -
  • -Securitum: -Clipboard security research. -
  • -
    - diff --git a/javascript/ql/src/experimental/Security/CWE-079/ClipboardXss.ql b/javascript/ql/src/experimental/Security/CWE-079/ClipboardXss.ql deleted file mode 100644 index c6ae4e1fed6..00000000000 --- a/javascript/ql/src/experimental/Security/CWE-079/ClipboardXss.ql +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @name Client-side clipboard-based cross-site scripting - * @description Pasting clipboard input directly to the DOM without proper sanitization allows for - * a cross-site scripting vulnerability. - * @kind path-problem - * @problem.severity error - * @security-severity 3.1 - * @precision high - * @id js/clipboard-xss - * @tags security - * external/cwe/cwe-079 - */ - -import javascript -import DataFlow -import semmle.javascript.security.dataflow.DomBasedXssQuery as DomBasedXss -import DataFlow::PathGraph - -/* - * Gets references to clipboardData DataTransfer objects - * https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent/clipboardData - */ - -SourceNode clipboardDataTransferSource(TypeTracker t) { - t.start() and - exists(DataFlow::PropRead pr | pr.getPropertyName() = "clipboardData" and result = pr) - or - exists(TypeTracker t2 | result = clipboardDataTransferSource(t2).track(t2, t)) -} - -SourceNode clipboardDataTransferSource() { - result = clipboardDataTransferSource(TypeTracker::end()) -} - -/* - * Gets references to the result of a call to getData on a DataTransfer object - * https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/getData - */ - -SourceNode clipboardDataSource(TypeTracker t) { - t.start() and - result = clipboardDataTransferSource().getAMethodCall("getData") - or - exists(TypeTracker t2 | result = clipboardDataSource(t2).track(t2, t)) -} - -SourceNode clipboardDataSource() { result = clipboardDataSource(TypeTracker::end()) } - -class ClipboardSource extends DataFlow::Node { - ClipboardSource() { this = clipboardDataSource() } -} - -class ClipboardHtmlInjectionConfiguration extends DomBasedXss::HtmlInjectionConfiguration { - override predicate isSource(DataFlow::Node source) { source instanceof ClipboardSource } -} - -class ClipboardJQueryHtmlOrSelectorInjectionConfiguration extends DomBasedXss::JQueryHtmlOrSelectorInjectionConfiguration { - override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) { - // Reuse any source not derived from location - source instanceof ClipboardSource and - ( - label.isTaint() - or - label.isData() // Require transformation before reaching sink - ) - } -} - -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where - ( - cfg instanceof ClipboardHtmlInjectionConfiguration or - cfg instanceof ClipboardJQueryHtmlOrSelectorInjectionConfiguration - ) and - cfg.hasFlowPath(source, sink) -select sink.getNode(), source, sink, - sink.getNode().(DomBasedXss::Sink).getVulnerabilityKind() + " vulnerability due to $@.", - source.getNode(), "user-provided clipboard value" diff --git a/javascript/ql/src/experimental/Security/CWE-079/examples/clipboard-xss-sample.js b/javascript/ql/src/experimental/Security/CWE-079/examples/clipboard-xss-sample.js deleted file mode 100644 index 98ca88bcb25..00000000000 --- a/javascript/ql/src/experimental/Security/CWE-079/examples/clipboard-xss-sample.js +++ /dev/null @@ -1,18 +0,0 @@ -function paste(e) { - const { clipboardData } = e.originalEvent; - if (!clipboardData) return; - - const text = clipboardData.getData('text/plain'); - const html = clipboardData.getData('text/html'); - if (!text && !html) return; - - e.preventDefault(); - - const div = document.createElement('div'); - if (html) { - div.innerHTML = html; - } else { - div.textContent = text; - } - document.body.append(div); -} \ No newline at end of file diff --git a/javascript/ql/src/experimental/Security/CWE-094/ExpressionInjection.ql b/javascript/ql/src/experimental/Security/CWE-094/ExpressionInjection.ql index a015c5f5147..29a34897880 100644 --- a/javascript/ql/src/experimental/Security/CWE-094/ExpressionInjection.ql +++ b/javascript/ql/src/experimental/Security/CWE-094/ExpressionInjection.ql @@ -65,6 +65,12 @@ private predicate isExternalUserControlledCommit(string context) { context.regexpMatch("\\bgithub\\s*\\.\\s*head_ref\\b") } +bindingset[context] +private predicate isExternalUserControlledDiscussion(string context) { + context.regexpMatch("\\bgithub\\s*\\.\\s*event\\s*\\.\\s*discussion\\s*\\.\\s*title\\b") or + context.regexpMatch("\\bgithub\\s*\\.\\s*event\\s*\\.\\s*discussion\\s*\\.\\s*body\\b") +} + from Actions::Run run, string context, Actions::On on where run.getAReferencedExpression() = context and @@ -87,6 +93,9 @@ where or exists(on.getNode("pull_request_target")) and isExternalUserControlledCommit(context) + or + (exists(on.getNode("discussion")) or exists(on.getNode("discussion_comment"))) and + isExternalUserControlledDiscussion(context) ) select run, "Potential injection from the " + context + diff --git a/javascript/ql/src/experimental/poi/PoI.qll b/javascript/ql/src/experimental/poi/PoI.qll index 20eeeee9f79..c51909c5c9e 100644 --- a/javascript/ql/src/experimental/poi/PoI.qll +++ b/javascript/ql/src/experimental/poi/PoI.qll @@ -55,7 +55,7 @@ import javascript private import DataFlow -private import filters.ClassifyFiles +private import semmle.javascript.filters.ClassifyFiles private import semmle.javascript.RestrictedLocations /** diff --git a/javascript/ql/src/external/DefectFilter.qll b/javascript/ql/src/external/DefectFilter.qll index d35e41d9afd..40c9527e96d 100644 --- a/javascript/ql/src/external/DefectFilter.qll +++ b/javascript/ql/src/external/DefectFilter.qll @@ -8,7 +8,7 @@ import semmle.javascript.Files * column `startcolumn` of line `startline` to column `endcolumn` of line `endline` * in file `filepath`. * - * For more information, see [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * For more information, see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ external predicate defectResults( int id, string queryPath, string file, int startline, int startcol, int endline, int endcol, diff --git a/javascript/ql/src/external/MetricFilter.qll b/javascript/ql/src/external/MetricFilter.qll index 5edecac75d8..e27b733e4b9 100644 --- a/javascript/ql/src/external/MetricFilter.qll +++ b/javascript/ql/src/external/MetricFilter.qll @@ -8,7 +8,7 @@ import javascript * column `startcolumn` of line `startline` to column `endcolumn` of line `endline` * in file `filepath`. * - * For more information, see [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * For more information, see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ external predicate metricResults( int id, string queryPath, string file, int startline, int startcol, int endline, int endcol, diff --git a/javascript/ql/src/filters/ClassifyFiles.ql b/javascript/ql/src/filters/ClassifyFiles.ql index fa7aad41ab4..9100485a6d6 100644 --- a/javascript/ql/src/filters/ClassifyFiles.ql +++ b/javascript/ql/src/filters/ClassifyFiles.ql @@ -8,7 +8,7 @@ */ import javascript -import ClassifyFiles +import semmle.javascript.filters.ClassifyFiles from File f, string category where classify(f, category) diff --git a/javascript/ql/test/library-tests/CFG/CFG.expected b/javascript/ql/test/library-tests/CFG/CFG.expected index a41f1c4999a..235b4f73183 100644 --- a/javascript/ql/test/library-tests/CFG/CFG.expected +++ b/javascript/ql/test/library-tests/CFG/CFG.expected @@ -770,7 +770,37 @@ | staticFieldsTS | 6 | D | 6 | new D() | | staticFieldsTS | 6 | instance | 6 | D | | staticFieldsTS | 6 | new D() | 6 | static ... ew D(); | -| staticFieldsTS | 6 | static ... ew D(); | 8 | exit node of | +| staticFieldsTS | 6 | static ... ew D(); | 9 | export ... ;\\n }\\n} | +| staticFieldsTS | 9 | E | 9 | constructor | +| staticFieldsTS | 9 | class E ... ;\\n }\\n} | 10 | f | +| staticFieldsTS | 9 | constructor | 9 | function in constructor() {} | +| staticFieldsTS | 9 | constructor() {} | 9 | class E ... ;\\n }\\n} | +| staticFieldsTS | 9 | entry node of () {} | 9 | {} | +| staticFieldsTS | 9 | export ... ;\\n }\\n} | 9 | E | +| staticFieldsTS | 9 | function in constructor() {} | 9 | constructor() {} | +| staticFieldsTS | 9 | {} | 9 | exit node of () {} | +| staticFieldsTS | 10 | f | 10 | false | +| staticFieldsTS | 10 | false | 10 | static ... false; | +| staticFieldsTS | 10 | static ... false; | 11 | static ... ();\\n } | +| staticFieldsTS | 11 | static ... ();\\n } | 12 | E.f = new C(); | +| staticFieldsTS | 12 | C | 12 | new C() | +| staticFieldsTS | 12 | E | 12 | f | +| staticFieldsTS | 12 | E.f | 12 | C | +| staticFieldsTS | 12 | E.f = new C() | 14 | g | +| staticFieldsTS | 12 | E.f = new C(); | 12 | E | +| staticFieldsTS | 12 | f | 12 | E.f | +| staticFieldsTS | 12 | new C() | 12 | E.f = new C() | +| staticFieldsTS | 14 | 1337 | 14 | static ... = 1337; | +| staticFieldsTS | 14 | g | 14 | 1337 | +| staticFieldsTS | 14 | static ... = 1337; | 15 | static ... ();\\n } | +| staticFieldsTS | 15 | static ... ();\\n } | 16 | E.g = new D(); | +| staticFieldsTS | 16 | D | 16 | new D() | +| staticFieldsTS | 16 | E | 16 | g | +| staticFieldsTS | 16 | E.g | 16 | D | +| staticFieldsTS | 16 | E.g = new D() | 18 | exit node of | +| staticFieldsTS | 16 | E.g = new D(); | 16 | E | +| staticFieldsTS | 16 | g | 16 | E.g | +| staticFieldsTS | 16 | new D() | 16 | E.g = new D() | | switch | 1 | entry node of | 14 | f | | switch | 1 | switch ... 19;\\n} | 2 | x | | switch | 2 | x | 6 | case\\n ... 19; | diff --git a/javascript/ql/test/library-tests/CFG/StaticInit.expected b/javascript/ql/test/library-tests/CFG/StaticInit.expected index 95e41584cdc..1da2f66503c 100644 --- a/javascript/ql/test/library-tests/CFG/StaticInit.expected +++ b/javascript/ql/test/library-tests/CFG/StaticInit.expected @@ -14,3 +14,5 @@ | staticFields.js:2:3:2:28 | static ... ew C(); | Field initializer occurs after its class is created | | staticFieldsTS.ts:2:3:2:31 | static ... ew C(); | Field initializer occurs after its class is created | | staticFieldsTS.ts:6:3:6:31 | static ... ew D(); | Field initializer occurs after its class is created | +| staticFieldsTS.ts:10:3:10:32 | static ... false; | Field initializer occurs after its class is created | +| staticFieldsTS.ts:14:3:14:30 | static ... = 1337; | Field initializer occurs after its class is created | diff --git a/javascript/ql/test/library-tests/CFG/staticFieldsTS.ts b/javascript/ql/test/library-tests/CFG/staticFieldsTS.ts index ca394de8265..77a17831958 100644 --- a/javascript/ql/test/library-tests/CFG/staticFieldsTS.ts +++ b/javascript/ql/test/library-tests/CFG/staticFieldsTS.ts @@ -5,3 +5,14 @@ class C { export class D { static instance: D = new D(); } + +export class E { + static f: C | boolean = false; + static { + E.f = new C(); + } + static g: D | number = 1337; + static { + E.g = new D(); + } +} \ No newline at end of file diff --git a/javascript/ql/test/library-tests/Classes/staticInitializer.js b/javascript/ql/test/library-tests/Classes/staticInitializer.js new file mode 100644 index 00000000000..453840ca57c --- /dev/null +++ b/javascript/ql/test/library-tests/Classes/staticInitializer.js @@ -0,0 +1,18 @@ +class MyClass { + static x = 1; + constructor() { + this.y = 2; + } + static { + MyClass.z = 3; + } + foo() { + this.t = 4; + } + static bar() { + this.u = 5; + } + static { + this.v = 6; + } +} \ No newline at end of file diff --git a/javascript/ql/test/library-tests/Classes/tests.expected b/javascript/ql/test/library-tests/Classes/tests.expected index e200256b70c..9097aafc8db 100644 --- a/javascript/ql/test/library-tests/Classes/tests.expected +++ b/javascript/ql/test/library-tests/Classes/tests.expected @@ -4,6 +4,7 @@ test_FieldInits | privateFields.js:2:2:2:15 | #privDecl = 3; | privateFields.js:2:14:2:14 | 3 | | privateFields.js:3:2:3:12 | #if = "if"; | privateFields.js:3:8:3:11 | "if" | | privateFields.js:21:2:21:22 | ["#publ ... "] = 6; | privateFields.js:21:21:21:21 | 6 | +| staticInitializer.js:2:3:2:15 | static x = 1; | staticInitializer.js:2:14:2:14 | 1 | test_ComputedMethods | tst.js:3:3:3:56 | ["const ... r. */ } | | tst.js:13:3:13:10 | [m]() {} | @@ -11,6 +12,7 @@ test_StaticMethods | points.js:15:3:17:3 | static ... t";\\n } | | points.js:30:3:32:3 | static ... t";\\n } | | staticConstructor.js:2:3:2:59 | static ... tor"; } | +| staticInitializer.js:12:3:14:3 | static ... 5;\\n } | test_ClassDefinition_getSuperClass | points.js:20:1:33:1 | class C ... ;\\n }\\n} | points.js:20:29:20:33 | Point | | tst.js:6:1:8:1 | class B ... t); }\\n} | tst.js:6:17:6:17 | A | @@ -18,6 +20,7 @@ test_ClassNodeStaticMethod | points.js:1:1:18:1 | class P ... ;\\n }\\n} | className | points.js:15:19:17:3 | () {\\n ... t";\\n } | | points.js:20:1:33:1 | class C ... ;\\n }\\n} | className | points.js:30:19:32:3 | () {\\n ... t";\\n } | | staticConstructor.js:1:1:3:1 | class M ... r"; }\\n} | constructor | staticConstructor.js:2:21:2:59 | () { re ... tor"; } | +| staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | bar | staticInitializer.js:12:13:14:3 | () {\\n ... 5;\\n } | test_ClassDefinitions | dataflow.js:4:2:13:2 | class F ... \\n\\t\\t}\\n\\t} | | fields.js:1:1:4:1 | class C ... = 42\\n} | @@ -25,6 +28,7 @@ test_ClassDefinitions | points.js:20:1:33:1 | class C ... ;\\n }\\n} | | privateFields.js:1:1:27:1 | class F ... );\\n\\t}\\n} | | staticConstructor.js:1:1:3:1 | class M ... r"; }\\n} | +| staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | | tst.js:1:9:4:1 | class { ... */ }\\n} | | tst.js:6:1:8:1 | class B ... t); }\\n} | | tst.js:11:1:14:1 | class C ... () {}\\n} | @@ -38,6 +42,7 @@ test_Fields | privateFields.js:3:2:3:12 | #if = "if"; | privateFields.js:3:2:3:4 | #if | | privateFields.js:19:2:19:13 | #privSecond; | privateFields.js:19:2:19:12 | #privSecond | | privateFields.js:21:2:21:22 | ["#publ ... "] = 6; | privateFields.js:21:3:21:16 | "#publicField" | +| staticInitializer.js:2:3:2:15 | static x = 1; | staticInitializer.js:2:10:2:10 | x | test_ClassDefinition_getName | dataflow.js:4:2:13:2 | class F ... \\n\\t\\t}\\n\\t} | Foo | | fields.js:1:1:4:1 | class C ... = 42\\n} | C | @@ -45,6 +50,7 @@ test_ClassDefinition_getName | points.js:20:1:33:1 | class C ... ;\\n }\\n} | ColouredPoint | | privateFields.js:1:1:27:1 | class F ... );\\n\\t}\\n} | Foo | | staticConstructor.js:1:1:3:1 | class M ... r"; }\\n} | MyClass | +| staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | MyClass | | tst.js:1:9:4:1 | class { ... */ }\\n} | A | | tst.js:6:1:8:1 | class B ... t); }\\n} | B | | tst.js:11:1:14:1 | class C ... () {}\\n} | C | @@ -67,6 +73,9 @@ test_MethodDefinitions | privateFields.js:23:2:26:2 | calls() ... l();\\n\\t} | privateFields.js:23:2:23:6 | calls | privateFields.js:23:7:26:2 | () {\\n\\t\\t ... l();\\n\\t} | privateFields.js:1:1:27:1 | class F ... );\\n\\t}\\n} | | staticConstructor.js:1:15:1:14 | constructor() {} | staticConstructor.js:1:15:1:14 | constructor | staticConstructor.js:1:15:1:14 | () {} | staticConstructor.js:1:1:3:1 | class M ... r"; }\\n} | | staticConstructor.js:2:3:2:59 | static ... tor"; } | staticConstructor.js:2:10:2:20 | constructor | staticConstructor.js:2:21:2:59 | () { re ... tor"; } | staticConstructor.js:1:1:3:1 | class M ... r"; }\\n} | +| staticInitializer.js:3:3:5:3 | constru ... 2;\\n } | staticInitializer.js:3:3:3:13 | constructor | staticInitializer.js:3:14:5:3 | () {\\n ... 2;\\n } | staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | +| staticInitializer.js:9:3:11:3 | foo() { ... 4;\\n } | staticInitializer.js:9:3:9:5 | foo | staticInitializer.js:9:6:11:3 | () {\\n ... 4;\\n } | staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | +| staticInitializer.js:12:3:14:3 | static ... 5;\\n } | staticInitializer.js:12:10:12:12 | bar | staticInitializer.js:12:13:14:3 | () {\\n ... 5;\\n } | staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | | tst.js:2:3:2:50 | "constr ... r. */ } | tst.js:2:3:2:15 | "constructor" | tst.js:2:16:2:50 | () { /* ... r. */ } | tst.js:1:9:4:1 | class { ... */ }\\n} | | tst.js:3:3:3:56 | ["const ... r. */ } | tst.js:3:4:3:16 | "constructor" | tst.js:3:18:3:56 | () { /* ... r. */ } | tst.js:1:9:4:1 | class { ... */ }\\n} | | tst.js:7:3:7:38 | constru ... get); } | tst.js:7:3:7:13 | constructor | tst.js:7:14:7:38 | () { su ... get); } | tst.js:6:1:8:1 | class B ... t); }\\n} | @@ -99,6 +108,12 @@ test_getAMember | privateFields.js:1:1:27:1 | class F ... );\\n\\t}\\n} | privateFields.js:23:2:26:2 | calls() ... l();\\n\\t} | | staticConstructor.js:1:1:3:1 | class M ... r"; }\\n} | staticConstructor.js:1:15:1:14 | constructor() {} | | staticConstructor.js:1:1:3:1 | class M ... r"; }\\n} | staticConstructor.js:2:3:2:59 | static ... tor"; } | +| staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | staticInitializer.js:2:3:2:15 | static x = 1; | +| staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | staticInitializer.js:3:3:5:3 | constru ... 2;\\n } | +| staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | staticInitializer.js:6:10:8:3 | {\\n M ... 3;\\n } | +| staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | staticInitializer.js:9:3:11:3 | foo() { ... 4;\\n } | +| staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | staticInitializer.js:12:3:14:3 | static ... 5;\\n } | +| staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | staticInitializer.js:15:10:17:3 | {\\n t ... 6;\\n } | | tst.js:1:9:4:1 | class { ... */ }\\n} | tst.js:2:3:2:50 | "constr ... r. */ } | | tst.js:1:9:4:1 | class { ... */ }\\n} | tst.js:3:3:3:56 | ["const ... r. */ } | | tst.js:6:1:8:1 | class B ... t); }\\n} | tst.js:7:3:7:38 | constru ... get); } | @@ -124,6 +139,9 @@ test_MethodNames | privateFields.js:23:2:26:2 | calls() ... l();\\n\\t} | calls | | staticConstructor.js:1:15:1:14 | constructor() {} | constructor | | staticConstructor.js:2:3:2:59 | static ... tor"; } | constructor | +| staticInitializer.js:3:3:5:3 | constru ... 2;\\n } | constructor | +| staticInitializer.js:9:3:11:3 | foo() { ... 4;\\n } | foo | +| staticInitializer.js:12:3:14:3 | static ... 5;\\n } | bar | | tst.js:2:3:2:50 | "constr ... r. */ } | constructor | | tst.js:3:3:3:56 | ["const ... r. */ } | constructor | | tst.js:7:3:7:38 | constru ... get); } | constructor | @@ -148,6 +166,7 @@ test_ConstructorDefinitions | points.js:21:3:24:3 | constru ... c;\\n } | | privateFields.js:1:11:1:10 | constructor() {} | | staticConstructor.js:1:15:1:14 | constructor() {} | +| staticInitializer.js:3:3:5:3 | constru ... 2;\\n } | | tst.js:2:3:2:50 | "constr ... r. */ } | | tst.js:7:3:7:38 | constru ... get); } | | tst.js:11:9:11:8 | constructor() {} | @@ -158,6 +177,7 @@ test_ClassNodeConstructor | points.js:20:1:33:1 | class C ... ;\\n }\\n} | points.js:21:14:24:3 | (x, y, ... c;\\n } | | privateFields.js:1:1:27:1 | class F ... );\\n\\t}\\n} | privateFields.js:1:11:1:10 | () {} | | staticConstructor.js:1:1:3:1 | class M ... r"; }\\n} | staticConstructor.js:1:15:1:14 | () {} | +| staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | staticInitializer.js:3:14:5:3 | () {\\n ... 2;\\n } | | tst.js:1:9:4:1 | class { ... */ }\\n} | tst.js:2:16:2:50 | () { /* ... r. */ } | | tst.js:6:1:8:1 | class B ... t); }\\n} | tst.js:7:14:7:38 | () { su ... get); } | | tst.js:11:1:14:1 | class C ... () {}\\n} | tst.js:11:9:11:8 | () {} | @@ -170,6 +190,7 @@ test_ClassNodeInstanceMethod | privateFields.js:1:1:27:1 | class F ... );\\n\\t}\\n} | equals | privateFields.js:10:8:12:2 | (o) {\\n\\t ... ecl;\\n\\t} | | privateFields.js:1:1:27:1 | class F ... );\\n\\t}\\n} | reads | privateFields.js:4:7:8:2 | () {\\n\\t\\t ... #if;\\n\\t} | | privateFields.js:1:1:27:1 | class F ... );\\n\\t}\\n} | writes | privateFields.js:14:8:17:2 | () {\\n\\t\\t ... = 5;\\n\\t} | +| staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | foo | staticInitializer.js:9:6:11:3 | () {\\n ... 4;\\n } | | tst.js:1:9:4:1 | class { ... */ }\\n} | constructor | tst.js:3:18:3:56 | () { /* ... r. */ } | | tst.js:11:1:14:1 | class C ... () {}\\n} | m | tst.js:12:4:12:8 | () {} | getAccessModifier @@ -223,6 +244,15 @@ getAccessModifier | staticConstructor.js:2:3:2:59 | static ... tor"; } | staticConstructor.js:2:10:2:20 | constructor | Public | | staticConstructor.js:4:1:4:11 | console.log | staticConstructor.js:4:9:4:11 | log | Public | | staticConstructor.js:4:13:4:31 | MyClass.constructor | staticConstructor.js:4:21:4:31 | constructor | Public | +| staticInitializer.js:2:3:2:15 | static x = 1; | staticInitializer.js:2:10:2:10 | x | Public | +| staticInitializer.js:3:3:5:3 | constru ... 2;\\n } | staticInitializer.js:3:3:3:13 | constructor | Public | +| staticInitializer.js:4:5:4:10 | this.y | staticInitializer.js:4:10:4:10 | y | Public | +| staticInitializer.js:7:5:7:13 | MyClass.z | staticInitializer.js:7:13:7:13 | z | Public | +| staticInitializer.js:9:3:11:3 | foo() { ... 4;\\n } | staticInitializer.js:9:3:9:5 | foo | Public | +| staticInitializer.js:10:5:10:10 | this.t | staticInitializer.js:10:10:10:10 | t | Public | +| staticInitializer.js:12:3:14:3 | static ... 5;\\n } | staticInitializer.js:12:10:12:12 | bar | Public | +| staticInitializer.js:13:5:13:10 | this.u | staticInitializer.js:13:10:13:10 | u | Public | +| staticInitializer.js:16:5:16:10 | this.v | staticInitializer.js:16:10:16:10 | v | Public | | tst.js:2:3:2:50 | "constr ... r. */ } | tst.js:2:3:2:15 | "constructor" | Public | | tst.js:3:3:3:56 | ["const ... r. */ } | tst.js:3:4:3:16 | "constructor" | Public | | tst.js:7:3:7:38 | constru ... get); } | tst.js:7:3:7:13 | constructor | Public | @@ -233,3 +263,6 @@ getAccessModifier dataflow | dataflow.js:2:15:2:22 | "source" | dataflow.js:14:7:14:25 | new Foo().getPriv() | | dataflow.js:2:15:2:22 | "source" | dataflow.js:16:7:16:33 | new Foo ... ivate() | +staticInitializer +| staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | staticInitializer.js:6:10:8:3 | {\\n M ... 3;\\n } | +| staticInitializer.js:1:1:18:1 | class M ... ;\\n }\\n} | staticInitializer.js:15:10:17:3 | {\\n t ... 6;\\n } | diff --git a/javascript/ql/test/library-tests/Classes/tests.ql b/javascript/ql/test/library-tests/Classes/tests.ql index 5cb3c90db85..5231f51c552 100644 --- a/javascript/ql/test/library-tests/Classes/tests.ql +++ b/javascript/ql/test/library-tests/Classes/tests.ql @@ -1,20 +1,76 @@ -import FieldInits -import ComputedMethods -import StaticMethods -import ClassDefinition_getSuperClass -import ClassNodeStaticMethod -import ClassDefinitions -import AccessorMethods -import Fields -import ClassDefinition_getName -import MethodDefinitions -import getAMember -import MethodNames -import NewTargetExpr -import SuperExpr -import SyntheticConstructors -import ConstructorDefinitions -import ClassNodeConstructor -import ClassNodeInstanceMethod -import PrivateField -import ClassFlow +import javascript + +query predicate test_FieldInits(FieldDefinition field, Expr res) { res = field.getInit() } + +query predicate test_ComputedMethods(MethodDefinition md) { md.isComputed() } + +query predicate test_StaticMethods(MethodDefinition md) { md.isStatic() } + +query predicate test_ClassDefinition_getSuperClass(ClassDefinition cd, Expr res) { + res = cd.getSuperClass() +} + +query predicate test_ClassNodeStaticMethod( + DataFlow::ClassNode class_, string name, DataFlow::FunctionNode res +) { + res = class_.getStaticMethod(name) +} + +query predicate test_ClassDefinitions(ClassDefinition cd) { any() } + +query predicate test_AccessorMethods(AccessorMethodDefinition amd) { any() } + +query predicate test_Fields(FieldDefinition field, Expr res) { res = field.getNameExpr() } + +query predicate test_ClassDefinition_getName(ClassDefinition cd, string res) { res = cd.getName() } + +query predicate test_MethodDefinitions( + MethodDefinition md, Expr res0, FunctionExpr res1, ClassDefinition res2 +) { + res0 = md.getNameExpr() and res1 = md.getBody() and res2 = md.getDeclaringClass() +} + +query predicate test_getAMember(ClassDefinition c, MemberDeclaration res) { res = c.getAMember() } + +query predicate test_MethodNames(MethodDefinition md, string res) { res = md.getName() } + +query predicate test_NewTargetExpr(NewTargetExpr e) { any() } + +query predicate test_SuperExpr(SuperExpr s) { any() } + +query predicate test_SyntheticConstructors(ConstructorDefinition cd) { cd.isSynthetic() } + +query predicate test_ConstructorDefinitions(ConstructorDefinition cd) { any() } + +query predicate test_ClassNodeConstructor(DataFlow::ClassNode class_, DataFlow::FunctionNode res) { + res = class_.getConstructor() +} + +query predicate test_ClassNodeInstanceMethod( + DataFlow::ClassNode class_, string name, DataFlow::FunctionNode res +) { + res = class_.getInstanceMethod(name) +} + +query string getAccessModifier(DataFlow::PropRef ref, Expr prop) { + prop = ref.getPropertyNameExpr() and + if ref.isPrivateField() then result = "Private" else result = "Public" +} + +class Configuration extends DataFlow::Configuration { + Configuration() { this = "ClassDataFlowTestingConfig" } + + override predicate isSource(DataFlow::Node source) { + source.getEnclosingExpr().(StringLiteral).getValue().toLowerCase() = "source" + } + + override predicate isSink(DataFlow::Node sink) { + any(DataFlow::CallNode call | call.getCalleeName() = "sink").getAnArgument() = sink + } +} + +query predicate dataflow(DataFlow::Node pred, DataFlow::Node succ) { + any(Configuration c).hasFlow(pred, succ) +} + +query BlockStmt staticInitializer(ClassDefinition cd) { result = cd.getAStaticInitializerBlock() } diff --git a/javascript/ql/test/library-tests/PackageExports/notPublic.ts b/javascript/ql/test/library-tests/PackageExports/notPublic.ts new file mode 100644 index 00000000000..b5ca23574b1 --- /dev/null +++ b/javascript/ql/test/library-tests/PackageExports/notPublic.ts @@ -0,0 +1,11 @@ +export class PublicClass { + protected constructor(p) {} + private privateMethod(p) {} + protected protectedMethod(p) {} + _kindaPrivateMethod(p) {} + $kindaPrivateMethod(p) {} + #esPrivateMethod(p) {} + + _kindaPrivateFieldMethod = (p) => {}; + private privateFieldMethod = (p) => {}; +} diff --git a/javascript/ql/test/library-tests/PackageExports/tests.expected b/javascript/ql/test/library-tests/PackageExports/tests.expected index 1d46e149521..e4ed532c708 100644 --- a/javascript/ql/test/library-tests/PackageExports/tests.expected +++ b/javascript/ql/test/library-tests/PackageExports/tests.expected @@ -15,3 +15,4 @@ getAnExportedValue | lib1/reexport/a.js:1:1:3:1 | | reexported | lib1/reexport/a.js:2:17:2:40 | functio ... ed() {} | | lib1/reexport/b.js:1:1:6:1 | | base | lib1/reexport/b.js:4:11:4:28 | function base() {} | | lib1/reexport/b.js:1:1:6:1 | | reexported | lib1/reexport/a.js:2:17:2:40 | functio ... ed() {} | +| notPublic.ts:1:1:12:0 | | PublicClass | notPublic.ts:1:8:11:1 | class P ... > {};\\n} | diff --git a/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected b/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected index d05b3228025..37df1d045b8 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected +++ b/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected @@ -87,6 +87,14 @@ nodes | dummy.ts:4:22:4:22 | [RegExpNormalConstant] c | semmle.label | [RegExpNormalConstant] c | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | @@ -591,17 +599,208 @@ nodes | tst.ts:127:14:127:17 | [ThisExpr] this | semmle.label | [ThisExpr] this | | tst.ts:127:14:127:28 | [DotExpr] this.#someValue | semmle.label | [DotExpr] this.#someValue | | tst.ts:127:19:127:28 | [Label] #someValue | semmle.label | [Label] #someValue | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | semmle.label | [NamespaceDeclaration] module ... } } | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | semmle.order | 56 | +| tst.ts:132:8:132:11 | [VarDecl] TS44 | semmle.label | [VarDecl] TS44 | +| tst.ts:133:3:138:3 | [FunctionDeclStmt] functio ... } } | semmle.label | [FunctionDeclStmt] functio ... } } | +| tst.ts:133:12:133:14 | [VarDecl] foo | semmle.label | [VarDecl] foo | +| tst.ts:133:16:133:18 | [SimpleParameter] arg | semmle.label | [SimpleParameter] arg | +| tst.ts:133:21:133:27 | [KeywordTypeExpr] unknown | semmle.label | [KeywordTypeExpr] unknown | +| tst.ts:133:30:138:3 | [BlockStmt] { c ... } } | semmle.label | [BlockStmt] { c ... } } | +| tst.ts:134:5:134:48 | [DeclStmt] const argIsString = ... | semmle.label | [DeclStmt] const argIsString = ... | +| tst.ts:134:11:134:21 | [VarDecl] argIsString | semmle.label | [VarDecl] argIsString | +| tst.ts:134:11:134:47 | [VariableDeclarator] argIsSt ... string" | semmle.label | [VariableDeclarator] argIsSt ... string" | +| tst.ts:134:25:134:34 | [UnaryExpr] typeof arg | semmle.label | [UnaryExpr] typeof arg | +| tst.ts:134:25:134:47 | [BinaryExpr] typeof ... string" | semmle.label | [BinaryExpr] typeof ... string" | +| tst.ts:134:32:134:34 | [VarRef] arg | semmle.label | [VarRef] arg | +| tst.ts:134:40:134:47 | [Literal] "string" | semmle.label | [Literal] "string" | +| tst.ts:135:5:137:5 | [IfStmt] if (arg ... ; } | semmle.label | [IfStmt] if (arg ... ; } | +| tst.ts:135:9:135:19 | [VarRef] argIsString | semmle.label | [VarRef] argIsString | +| tst.ts:135:22:137:5 | [BlockStmt] { ... ; } | semmle.label | [BlockStmt] { ... ; } | +| tst.ts:136:9:136:40 | [DeclStmt] const upper = ... | semmle.label | [DeclStmt] const upper = ... | +| tst.ts:136:15:136:19 | [VarDecl] upper | semmle.label | [VarDecl] upper | +| tst.ts:136:15:136:39 | [VariableDeclarator] upper = ... rCase() | semmle.label | [VariableDeclarator] upper = ... rCase() | +| tst.ts:136:23:136:25 | [VarRef] arg | semmle.label | [VarRef] arg | +| tst.ts:136:23:136:37 | [DotExpr] arg.toUpperCase | semmle.label | [DotExpr] arg.toUpperCase | +| tst.ts:136:23:136:39 | [MethodCallExpr] arg.toUpperCase() | semmle.label | [MethodCallExpr] arg.toUpperCase() | +| tst.ts:136:27:136:37 | [Label] toUpperCase | semmle.label | [Label] toUpperCase | +| tst.ts:140:3:142:47 | [TypeAliasDeclaration,TypeDefinition] type Sh ... mber }; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Sh ... mber }; | +| tst.ts:140:8:140:12 | [Identifier] Shape | semmle.label | [Identifier] Shape | +| tst.ts:141:7:142:46 | [UnionTypeExpr] \| { kin ... umber } | semmle.label | [UnionTypeExpr] \| { kin ... umber } | +| tst.ts:141:9:141:42 | [InterfaceTypeExpr] { kind: ... umber } | semmle.label | [InterfaceTypeExpr] { kind: ... umber } | +| tst.ts:141:11:141:14 | [Label] kind | semmle.label | [Label] kind | +| tst.ts:141:11:141:25 | [FieldDeclaration] kind: "circle", | semmle.label | [FieldDeclaration] kind: "circle", | +| tst.ts:141:17:141:24 | [LiteralTypeExpr] "circle" | semmle.label | [LiteralTypeExpr] "circle" | +| tst.ts:141:27:141:32 | [Label] radius | semmle.label | [Label] radius | +| tst.ts:141:27:141:40 | [FieldDeclaration] radius: number | semmle.label | [FieldDeclaration] radius: number | +| tst.ts:141:35:141:40 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:142:9:142:46 | [InterfaceTypeExpr] { kind: ... umber } | semmle.label | [InterfaceTypeExpr] { kind: ... umber } | +| tst.ts:142:11:142:14 | [Label] kind | semmle.label | [Label] kind | +| tst.ts:142:11:142:25 | [FieldDeclaration] kind: "square", | semmle.label | [FieldDeclaration] kind: "square", | +| tst.ts:142:17:142:24 | [LiteralTypeExpr] "square" | semmle.label | [LiteralTypeExpr] "square" | +| tst.ts:142:27:142:36 | [Label] sideLength | semmle.label | [Label] sideLength | +| tst.ts:142:27:142:44 | [FieldDeclaration] sideLength: number | semmle.label | [FieldDeclaration] sideLength: number | +| tst.ts:142:39:142:44 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:144:3:149:3 | [FunctionDeclStmt] functio ... ; } } | semmle.label | [FunctionDeclStmt] functio ... ; } } | +| tst.ts:144:12:144:15 | [VarDecl] side | semmle.label | [VarDecl] side | +| tst.ts:144:17:144:21 | [SimpleParameter] shape | semmle.label | [SimpleParameter] shape | +| tst.ts:144:24:144:28 | [LocalTypeAccess] Shape | semmle.label | [LocalTypeAccess] Shape | +| tst.ts:144:32:144:37 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:144:39:149:3 | [BlockStmt] { ... ; } } | semmle.label | [BlockStmt] { ... ; } } | +| tst.ts:145:7:145:29 | [DeclStmt] const { ... shape; | semmle.label | [DeclStmt] const { ... shape; | +| tst.ts:145:13:145:20 | [ObjectPattern] { kind } | semmle.label | [ObjectPattern] { kind } | +| tst.ts:145:13:145:28 | [VariableDeclarator] { kind } = shape | semmle.label | [VariableDeclarator] { kind } = shape | +| tst.ts:145:15:145:18 | [Label] kind | semmle.label | [Label] kind | +| tst.ts:145:15:145:18 | [PropertyPattern] kind | semmle.label | [PropertyPattern] kind | +| tst.ts:145:15:145:18 | [VarDecl] kind | semmle.label | [VarDecl] kind | +| tst.ts:145:24:145:28 | [VarRef] shape | semmle.label | [VarRef] shape | +| tst.ts:147:7:148:39 | [IfStmt] if (kin ... ngth; } | semmle.label | [IfStmt] if (kin ... ngth; } | +| tst.ts:147:11:147:14 | [VarRef] kind | semmle.label | [VarRef] kind | +| tst.ts:147:11:147:27 | [BinaryExpr] kind === "circle" | semmle.label | [BinaryExpr] kind === "circle" | +| tst.ts:147:20:147:27 | [Literal] "circle" | semmle.label | [Literal] "circle" | +| tst.ts:147:30:147:52 | [BlockStmt] { retur ... adius;} | semmle.label | [BlockStmt] { retur ... adius;} | +| tst.ts:147:32:147:51 | [ReturnStmt] return shape.radius; | semmle.label | [ReturnStmt] return shape.radius; | +| tst.ts:147:39:147:43 | [VarRef] shape | semmle.label | [VarRef] shape | +| tst.ts:147:39:147:50 | [DotExpr] shape.radius | semmle.label | [DotExpr] shape.radius | +| tst.ts:147:45:147:50 | [Label] radius | semmle.label | [Label] radius | +| tst.ts:148:12:148:39 | [BlockStmt] { retur ... ngth; } | semmle.label | [BlockStmt] { retur ... ngth; } | +| tst.ts:148:14:148:37 | [ReturnStmt] return ... Length; | semmle.label | [ReturnStmt] return ... Length; | +| tst.ts:148:21:148:25 | [VarRef] shape | semmle.label | [VarRef] shape | +| tst.ts:148:21:148:36 | [DotExpr] shape.sideLength | semmle.label | [DotExpr] shape.sideLength | +| tst.ts:148:27:148:36 | [Label] sideLength | semmle.label | [Label] sideLength | +| tst.ts:151:3:162:3 | [FunctionDeclStmt] functio ... 2]; } | semmle.label | [FunctionDeclStmt] functio ... 2]; } | +| tst.ts:151:12:151:22 | [VarDecl] symbolIndex | semmle.label | [VarDecl] symbolIndex | +| tst.ts:151:26:162:3 | [BlockStmt] { i ... 2]; } | semmle.label | [BlockStmt] { i ... 2]; } | +| tst.ts:152:5:156:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | semmle.label | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | +| tst.ts:152:15:152:20 | [Identifier] Colors | semmle.label | [Identifier] Colors | +| tst.ts:153:7:153:28 | [FunctionExpr] [sym: s ... number; | semmle.label | [FunctionExpr] [sym: s ... number; | +| tst.ts:153:7:153:28 | [IndexSignature] [sym: s ... number; | semmle.label | [IndexSignature] [sym: s ... number; | +| tst.ts:153:8:153:10 | [SimpleParameter] sym | semmle.label | [SimpleParameter] sym | +| tst.ts:153:13:153:18 | [KeywordTypeExpr] symbol | semmle.label | [KeywordTypeExpr] symbol | +| tst.ts:153:22:153:27 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:154:7:154:28 | [FunctionExpr] [key: s ... string; | semmle.label | [FunctionExpr] [key: s ... string; | +| tst.ts:154:7:154:28 | [IndexSignature] [key: s ... string; | semmle.label | [IndexSignature] [key: s ... string; | +| tst.ts:154:8:154:10 | [SimpleParameter] key | semmle.label | [SimpleParameter] key | +| tst.ts:154:13:154:18 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | +| tst.ts:154:22:154:27 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | +| tst.ts:155:7:155:29 | [FunctionExpr] [num: n ... oolean; | semmle.label | [FunctionExpr] [num: n ... oolean; | +| tst.ts:155:7:155:29 | [IndexSignature] [num: n ... oolean; | semmle.label | [IndexSignature] [num: n ... oolean; | +| tst.ts:155:8:155:10 | [SimpleParameter] num | semmle.label | [SimpleParameter] num | +| tst.ts:155:13:155:18 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:155:22:155:28 | [KeywordTypeExpr] boolean | semmle.label | [KeywordTypeExpr] boolean | +| tst.ts:158:5:158:28 | [DeclStmt] let colors = ... | semmle.label | [DeclStmt] let colors = ... | +| tst.ts:158:9:158:14 | [VarDecl] colors | semmle.label | [VarDecl] colors | +| tst.ts:158:9:158:27 | [VariableDeclarator] colors: Colors = {} | semmle.label | [VariableDeclarator] colors: Colors = {} | +| tst.ts:158:17:158:22 | [LocalTypeAccess] Colors | semmle.label | [LocalTypeAccess] Colors | +| tst.ts:158:26:158:27 | [ObjectExpr] {} | semmle.label | [ObjectExpr] {} | +| tst.ts:159:5:159:38 | [DeclStmt] const red = ... | semmle.label | [DeclStmt] const red = ... | +| tst.ts:159:11:159:13 | [VarDecl] red | semmle.label | [VarDecl] red | +| tst.ts:159:11:159:37 | [VariableDeclarator] red = c ... "red")] | semmle.label | [VariableDeclarator] red = c ... "red")] | +| tst.ts:159:17:159:22 | [VarRef] colors | semmle.label | [VarRef] colors | +| tst.ts:159:17:159:37 | [IndexExpr] colors[ ... "red")] | semmle.label | [IndexExpr] colors[ ... "red")] | +| tst.ts:159:24:159:29 | [VarRef] Symbol | semmle.label | [VarRef] Symbol | +| tst.ts:159:24:159:36 | [CallExpr] Symbol("red") | semmle.label | [CallExpr] Symbol("red") | +| tst.ts:159:31:159:35 | [Literal] "red" | semmle.label | [Literal] "red" | +| tst.ts:160:5:160:34 | [DeclStmt] const green = ... | semmle.label | [DeclStmt] const green = ... | +| tst.ts:160:11:160:15 | [VarDecl] green | semmle.label | [VarDecl] green | +| tst.ts:160:11:160:33 | [VariableDeclarator] green = ... green"] | semmle.label | [VariableDeclarator] green = ... green"] | +| tst.ts:160:19:160:24 | [VarRef] colors | semmle.label | [VarRef] colors | +| tst.ts:160:19:160:33 | [IndexExpr] colors["green"] | semmle.label | [IndexExpr] colors["green"] | +| tst.ts:160:26:160:32 | [Literal] "green" | semmle.label | [Literal] "green" | +| tst.ts:161:5:161:27 | [DeclStmt] const blue = ... | semmle.label | [DeclStmt] const blue = ... | +| tst.ts:161:11:161:14 | [VarDecl] blue | semmle.label | [VarDecl] blue | +| tst.ts:161:11:161:26 | [VariableDeclarator] blue = colors[2] | semmle.label | [VariableDeclarator] blue = colors[2] | +| tst.ts:161:18:161:23 | [VarRef] colors | semmle.label | [VarRef] colors | +| tst.ts:161:18:161:26 | [IndexExpr] colors[2] | semmle.label | [IndexExpr] colors[2] | +| tst.ts:161:25:161:25 | [Literal] 2 | semmle.label | [Literal] 2 | +| tst.ts:164:3:177:3 | [FunctionDeclStmt] functio ... "]; } | semmle.label | [FunctionDeclStmt] functio ... "]; } | +| tst.ts:164:12:164:29 | [VarDecl] stringPatternIndex | semmle.label | [VarDecl] stringPatternIndex | +| tst.ts:164:33:177:3 | [BlockStmt] { i ... "]; } | semmle.label | [BlockStmt] { i ... "]; } | +| tst.ts:165:5:167:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | semmle.label | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | +| tst.ts:165:15:165:17 | [Identifier] Foo | semmle.label | [Identifier] Foo | +| tst.ts:166:7:166:37 | [FunctionExpr] [key: ` ... number; | semmle.label | [FunctionExpr] [key: ` ... number; | +| tst.ts:166:7:166:37 | [IndexSignature] [key: ` ... number; | semmle.label | [IndexSignature] [key: ` ... number; | +| tst.ts:166:8:166:10 | [SimpleParameter] key | semmle.label | [SimpleParameter] key | +| tst.ts:166:13:166:27 | [TemplateLiteralTypeExpr] `foo-${number}` | semmle.label | [TemplateLiteralTypeExpr] `foo-${number}` | +| tst.ts:166:14:166:17 | [LiteralTypeExpr] foo- | semmle.label | [LiteralTypeExpr] foo- | +| tst.ts:166:20:166:25 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:166:31:166:36 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | +| tst.ts:168:5:168:23 | [DeclStmt] var bla = ... | semmle.label | [DeclStmt] var bla = ... | +| tst.ts:168:9:168:11 | [VarDecl] bla | semmle.label | [VarDecl] bla | +| tst.ts:168:9:168:22 | [VariableDeclarator] bla : Foo = {} | semmle.label | [VariableDeclarator] bla : Foo = {} | +| tst.ts:168:15:168:17 | [LocalTypeAccess] Foo | semmle.label | [LocalTypeAccess] Foo | +| tst.ts:168:21:168:22 | [ObjectExpr] {} | semmle.label | [ObjectExpr] {} | +| tst.ts:169:5:169:29 | [DeclStmt] const bar = ... | semmle.label | [DeclStmt] const bar = ... | +| tst.ts:169:11:169:13 | [VarDecl] bar | semmle.label | [VarDecl] bar | +| tst.ts:169:11:169:28 | [VariableDeclarator] bar = bla[`foo-1`] | semmle.label | [VariableDeclarator] bar = bla[`foo-1`] | +| tst.ts:169:17:169:19 | [VarRef] bla | semmle.label | [VarRef] bla | +| tst.ts:169:17:169:28 | [IndexExpr] bla[`foo-1`] | semmle.label | [IndexExpr] bla[`foo-1`] | +| tst.ts:169:21:169:27 | [TemplateElement] `foo-1` | semmle.label | [TemplateElement] `foo-1` | +| tst.ts:169:21:169:27 | [TemplateLiteral] `foo-1` | semmle.label | [TemplateLiteral] `foo-1` | +| tst.ts:171:5:173:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | semmle.label | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | +| tst.ts:171:15:171:18 | [Identifier] Data | semmle.label | [Identifier] Data | +| tst.ts:172:7:172:42 | [FunctionExpr] [optNam ... oolean; | semmle.label | [FunctionExpr] [optNam ... oolean; | +| tst.ts:172:7:172:42 | [IndexSignature] [optNam ... oolean; | semmle.label | [IndexSignature] [optNam ... oolean; | +| tst.ts:172:8:172:14 | [SimpleParameter] optName | semmle.label | [SimpleParameter] optName | +| tst.ts:172:17:172:22 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | +| tst.ts:172:17:172:31 | [UnionTypeExpr] string \| symbol | semmle.label | [UnionTypeExpr] string \| symbol | +| tst.ts:172:26:172:31 | [KeywordTypeExpr] symbol | semmle.label | [KeywordTypeExpr] symbol | +| tst.ts:172:35:172:41 | [KeywordTypeExpr] boolean | semmle.label | [KeywordTypeExpr] boolean | +| tst.ts:175:5:175:26 | [DeclStmt] const data = ... | semmle.label | [DeclStmt] const data = ... | +| tst.ts:175:11:175:14 | [VarDecl] data | semmle.label | [VarDecl] data | +| tst.ts:175:11:175:25 | [VariableDeclarator] data: Data = {} | semmle.label | [VariableDeclarator] data: Data = {} | +| tst.ts:175:17:175:20 | [LocalTypeAccess] Data | semmle.label | [LocalTypeAccess] Data | +| tst.ts:175:24:175:25 | [ObjectExpr] {} | semmle.label | [ObjectExpr] {} | +| tst.ts:176:5:176:28 | [DeclStmt] const baz = ... | semmle.label | [DeclStmt] const baz = ... | +| tst.ts:176:11:176:13 | [VarDecl] baz | semmle.label | [VarDecl] baz | +| tst.ts:176:11:176:27 | [VariableDeclarator] baz = data["foo"] | semmle.label | [VariableDeclarator] baz = data["foo"] | +| tst.ts:176:17:176:20 | [VarRef] data | semmle.label | [VarRef] data | +| tst.ts:176:17:176:27 | [IndexExpr] data["foo"] | semmle.label | [IndexExpr] data["foo"] | +| tst.ts:176:22:176:26 | [Literal] "foo" | semmle.label | [Literal] "foo" | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | semmle.label | [ClassDefinition,TypeDefinition] class F ... } | +| tst.ts:179:9:179:11 | [VarDecl] Foo | semmle.label | [VarDecl] Foo | +| tst.ts:179:13:179:12 | [BlockStmt] {} | semmle.label | [BlockStmt] {} | +| tst.ts:179:13:179:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} | +| tst.ts:179:13:179:12 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} | +| tst.ts:179:13:179:12 | [Label] constructor | semmle.label | [Label] constructor | +| tst.ts:180:5:180:22 | [ClassInitializedMember,FieldDeclaration] static #count = 0; | semmle.label | [ClassInitializedMember,FieldDeclaration] static #count = 0; | +| tst.ts:180:12:180:17 | [Label] #count | semmle.label | [Label] #count | +| tst.ts:180:21:180:21 | [Literal] 0 | semmle.label | [Literal] 0 | +| tst.ts:182:5:184:5 | [ClassInitializedMember,GetterMethodDefinition] get cou ... ; } | semmle.label | [ClassInitializedMember,GetterMethodDefinition] get cou ... ; } | +| tst.ts:182:5:184:5 | [FunctionExpr] get cou ... ; } | semmle.label | [FunctionExpr] get cou ... ; } | +| tst.ts:182:9:182:13 | [Label] count | semmle.label | [Label] count | +| tst.ts:182:17:184:5 | [BlockStmt] { ... ; } | semmle.label | [BlockStmt] { ... ; } | +| tst.ts:183:9:183:26 | [ReturnStmt] return Foo.#count; | semmle.label | [ReturnStmt] return Foo.#count; | +| tst.ts:183:16:183:18 | [VarRef] Foo | semmle.label | [VarRef] Foo | +| tst.ts:183:16:183:25 | [DotExpr] Foo.#count | semmle.label | [DotExpr] Foo.#count | +| tst.ts:183:20:183:25 | [Label] #count | semmle.label | [Label] #count | +| tst.ts:185:5:187:5 | [BlockStmt] static ... ; } | semmle.label | [BlockStmt] static ... ; } | +| tst.ts:185:5:187:5 | [ClassInitializedMember] static ... ; } | semmle.label | [ClassInitializedMember] static ... ; } | +| tst.ts:186:7:186:9 | [VarRef] Foo | semmle.label | [VarRef] Foo | +| tst.ts:186:7:186:16 | [DotExpr] Foo.#count | semmle.label | [DotExpr] Foo.#count | +| tst.ts:186:7:186:21 | [CompoundAssignExpr] Foo.#count += 3 | semmle.label | [CompoundAssignExpr] Foo.#count += 3 | +| tst.ts:186:7:186:22 | [ExprStmt] Foo.#count += 3; | semmle.label | [ExprStmt] Foo.#count += 3; | +| tst.ts:186:11:186:16 | [Label] #count | semmle.label | [Label] #count | +| tst.ts:186:21:186:21 | [Literal] 3 | semmle.label | [Literal] 3 | +| tst.ts:188:5:190:5 | [BlockStmt] static ... ; } | semmle.label | [BlockStmt] static ... ; } | +| tst.ts:188:5:190:5 | [ClassInitializedMember] static ... ; } | semmle.label | [ClassInitializedMember] static ... ; } | +| tst.ts:189:7:189:29 | [DeclStmt] var count = ... | semmle.label | [DeclStmt] var count = ... | +| tst.ts:189:11:189:15 | [VarDecl] count | semmle.label | [VarDecl] count | +| tst.ts:189:11:189:28 | [VariableDeclarator] count = Foo.#count | semmle.label | [VariableDeclarator] count = Foo.#count | +| tst.ts:189:19:189:21 | [VarRef] Foo | semmle.label | [VarRef] Foo | +| tst.ts:189:19:189:28 | [DotExpr] Foo.#count | semmle.label | [DotExpr] Foo.#count | +| tst.ts:189:23:189:28 | [Label] #count | semmle.label | [Label] #count | | type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | -| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 56 | +| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 57 | | type_alias.ts:1:6:1:6 | [Identifier] B | semmle.label | [Identifier] B | | type_alias.ts:1:10:1:16 | [KeywordTypeExpr] boolean | semmle.label | [KeywordTypeExpr] boolean | | type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.label | [DeclStmt] var b = ... | -| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.order | 57 | +| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.order | 58 | | type_alias.ts:3:5:3:5 | [VarDecl] b | semmle.label | [VarDecl] b | | type_alias.ts:3:5:3:8 | [VariableDeclarator] b: B | semmle.label | [VariableDeclarator] b: B | | type_alias.ts:3:8:3:8 | [LocalTypeAccess] B | semmle.label | [LocalTypeAccess] B | | type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | -| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | semmle.order | 58 | +| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | semmle.order | 59 | | type_alias.ts:5:6:5:17 | [Identifier] ValueOrArray | semmle.label | [Identifier] ValueOrArray | | type_alias.ts:5:19:5:19 | [Identifier] T | semmle.label | [Identifier] T | | type_alias.ts:5:19:5:19 | [TypeParameter] T | semmle.label | [TypeParameter] T | @@ -613,14 +812,14 @@ nodes | type_alias.ts:5:34:5:48 | [GenericTypeExpr] ValueOrArray | semmle.label | [GenericTypeExpr] ValueOrArray | | type_alias.ts:5:47:5:47 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T | | type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.label | [DeclStmt] var c = ... | -| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.order | 59 | +| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.order | 60 | | type_alias.ts:7:5:7:5 | [VarDecl] c | semmle.label | [VarDecl] c | | type_alias.ts:7:5:7:27 | [VariableDeclarator] c: Valu ... number> | semmle.label | [VariableDeclarator] c: Valu ... number> | | type_alias.ts:7:8:7:19 | [LocalTypeAccess] ValueOrArray | semmle.label | [LocalTypeAccess] ValueOrArray | | type_alias.ts:7:8:7:27 | [GenericTypeExpr] ValueOrArray | semmle.label | [GenericTypeExpr] ValueOrArray | | type_alias.ts:7:21:7:26 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | | type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | -| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.order | 60 | +| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.order | 61 | | type_alias.ts:9:6:9:9 | [Identifier] Json | semmle.label | [Identifier] Json | | type_alias.ts:10:5:15:12 | [UnionTypeExpr] \| strin ... Json[] | semmle.label | [UnionTypeExpr] \| strin ... Json[] | | type_alias.ts:10:7:10:12 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | @@ -636,12 +835,12 @@ nodes | type_alias.ts:15:7:15:10 | [LocalTypeAccess] Json | semmle.label | [LocalTypeAccess] Json | | type_alias.ts:15:7:15:12 | [ArrayTypeExpr] Json[] | semmle.label | [ArrayTypeExpr] Json[] | | type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.label | [DeclStmt] var json = ... | -| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.order | 61 | +| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.order | 62 | | type_alias.ts:17:5:17:8 | [VarDecl] json | semmle.label | [VarDecl] json | | type_alias.ts:17:5:17:14 | [VariableDeclarator] json: Json | semmle.label | [VariableDeclarator] json: Json | | type_alias.ts:17:11:17:14 | [LocalTypeAccess] Json | semmle.label | [LocalTypeAccess] Json | | type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | -| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.order | 62 | +| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.order | 63 | | type_alias.ts:19:6:19:16 | [Identifier] VirtualNode | semmle.label | [Identifier] VirtualNode | | type_alias.ts:20:5:21:56 | [UnionTypeExpr] \| strin ... Node[]] | semmle.label | [UnionTypeExpr] \| strin ... Node[]] | | type_alias.ts:20:7:20:12 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | @@ -657,7 +856,7 @@ nodes | type_alias.ts:21:43:21:53 | [LocalTypeAccess] VirtualNode | semmle.label | [LocalTypeAccess] VirtualNode | | type_alias.ts:21:43:21:55 | [ArrayTypeExpr] VirtualNode[] | semmle.label | [ArrayTypeExpr] VirtualNode[] | | type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.label | [DeclStmt] const myNode = ... | -| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.order | 63 | +| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.order | 64 | | type_alias.ts:23:7:23:12 | [VarDecl] myNode | semmle.label | [VarDecl] myNode | | type_alias.ts:23:7:27:5 | [VariableDeclarator] myNode: ... ] ] | semmle.label | [VariableDeclarator] myNode: ... ] ] | | type_alias.ts:23:15:23:25 | [LocalTypeAccess] VirtualNode | semmle.label | [LocalTypeAccess] VirtualNode | @@ -682,12 +881,12 @@ nodes | type_alias.ts:26:23:26:36 | [Literal] "second-child" | semmle.label | [Literal] "second-child" | | type_alias.ts:26:41:26:62 | [Literal] "I'm the second child" | semmle.label | [Literal] "I'm the second child" | | type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.label | [ImportDeclaration] import ... dummy"; | -| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 64 | +| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 65 | | type_definition_objects.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | [ImportSpecifier] * as dummy | | type_definition_objects.ts:1:13:1:17 | [VarDecl] dummy | semmle.label | [VarDecl] dummy | | type_definition_objects.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | [Literal] "./dummy" | | type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.label | [ExportDeclaration] export class C {} | -| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.order | 65 | +| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.order | 66 | | type_definition_objects.ts:3:8:3:17 | [ClassDefinition,TypeDefinition] class C {} | semmle.label | [ClassDefinition,TypeDefinition] class C {} | | type_definition_objects.ts:3:14:3:14 | [VarDecl] C | semmle.label | [VarDecl] C | | type_definition_objects.ts:3:16:3:15 | [BlockStmt] {} | semmle.label | [BlockStmt] {} | @@ -695,36 +894,36 @@ nodes | type_definition_objects.ts:3:16:3:15 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} | | type_definition_objects.ts:3:16:3:15 | [Label] constructor | semmle.label | [Label] constructor | | type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.label | [DeclStmt] let classObj = ... | -| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.order | 66 | +| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.order | 67 | | type_definition_objects.ts:4:5:4:12 | [VarDecl] classObj | semmle.label | [VarDecl] classObj | | type_definition_objects.ts:4:5:4:16 | [VariableDeclarator] classObj = C | semmle.label | [VariableDeclarator] classObj = C | | type_definition_objects.ts:4:16:4:16 | [VarRef] C | semmle.label | [VarRef] C | | type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.label | [ExportDeclaration] export enum E {} | -| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.order | 67 | +| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.order | 68 | | type_definition_objects.ts:6:8:6:16 | [EnumDeclaration,TypeDefinition] enum E {} | semmle.label | [EnumDeclaration,TypeDefinition] enum E {} | | type_definition_objects.ts:6:13:6:13 | [VarDecl] E | semmle.label | [VarDecl] E | | type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.label | [DeclStmt] let enumObj = ... | -| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.order | 68 | +| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.order | 69 | | type_definition_objects.ts:7:5:7:11 | [VarDecl] enumObj | semmle.label | [VarDecl] enumObj | | type_definition_objects.ts:7:5:7:15 | [VariableDeclarator] enumObj = E | semmle.label | [VariableDeclarator] enumObj = E | | type_definition_objects.ts:7:15:7:15 | [VarRef] E | semmle.label | [VarRef] E | | type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.label | [ExportDeclaration] export ... e N {;} | -| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.order | 69 | +| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.order | 70 | | type_definition_objects.ts:9:8:9:22 | [NamespaceDeclaration] namespace N {;} | semmle.label | [NamespaceDeclaration] namespace N {;} | | type_definition_objects.ts:9:18:9:18 | [VarDecl] N | semmle.label | [VarDecl] N | | type_definition_objects.ts:9:21:9:21 | [EmptyStmt] ; | semmle.label | [EmptyStmt] ; | | type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.label | [DeclStmt] let namespaceObj = ... | -| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.order | 70 | +| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.order | 71 | | type_definition_objects.ts:10:5:10:16 | [VarDecl] namespaceObj | semmle.label | [VarDecl] namespaceObj | | type_definition_objects.ts:10:5:10:20 | [VariableDeclarator] namespaceObj = N | semmle.label | [VariableDeclarator] namespaceObj = N | | type_definition_objects.ts:10:20:10:20 | [VarRef] N | semmle.label | [VarRef] N | | type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.label | [ImportDeclaration] import ... dummy"; | -| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 71 | +| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 72 | | type_definitions.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | [ImportSpecifier] * as dummy | | type_definitions.ts:1:13:1:17 | [VarDecl] dummy | semmle.label | [VarDecl] dummy | | type_definitions.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | [Literal] "./dummy" | | type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.label | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | -| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.order | 72 | +| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.order | 73 | | type_definitions.ts:3:11:3:11 | [Identifier] I | semmle.label | [Identifier] I | | type_definitions.ts:3:13:3:13 | [Identifier] S | semmle.label | [Identifier] S | | type_definitions.ts:3:13:3:13 | [TypeParameter] S | semmle.label | [TypeParameter] S | @@ -732,14 +931,14 @@ nodes | type_definitions.ts:4:3:4:7 | [FieldDeclaration] x: S; | semmle.label | [FieldDeclaration] x: S; | | type_definitions.ts:4:6:4:6 | [LocalTypeAccess] S | semmle.label | [LocalTypeAccess] S | | type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.label | [DeclStmt] let i = ... | -| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.order | 73 | +| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.order | 74 | | type_definitions.ts:6:5:6:5 | [VarDecl] i | semmle.label | [VarDecl] i | | type_definitions.ts:6:5:6:16 | [VariableDeclarator] i: I | semmle.label | [VariableDeclarator] i: I | | type_definitions.ts:6:8:6:8 | [LocalTypeAccess] I | semmle.label | [LocalTypeAccess] I | | type_definitions.ts:6:8:6:16 | [GenericTypeExpr] I | semmle.label | [GenericTypeExpr] I | | type_definitions.ts:6:10:6:15 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | | type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.label | [ClassDefinition,TypeDefinition] class C ... x: T } | -| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.order | 74 | +| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.order | 75 | | type_definitions.ts:8:7:8:7 | [VarDecl] C | semmle.label | [VarDecl] C | | type_definitions.ts:8:8:8:7 | [BlockStmt] {} | semmle.label | [BlockStmt] {} | | type_definitions.ts:8:8:8:7 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} | @@ -751,14 +950,14 @@ nodes | type_definitions.ts:9:3:9:6 | [FieldDeclaration] x: T | semmle.label | [FieldDeclaration] x: T | | type_definitions.ts:9:6:9:6 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T | | type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.label | [DeclStmt] let c = ... | -| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.order | 75 | +| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.order | 76 | | type_definitions.ts:11:5:11:5 | [VarDecl] c | semmle.label | [VarDecl] c | | type_definitions.ts:11:5:11:16 | [VariableDeclarator] c: C | semmle.label | [VariableDeclarator] c: C | | type_definitions.ts:11:8:11:8 | [LocalTypeAccess] C | semmle.label | [LocalTypeAccess] C | | type_definitions.ts:11:8:11:16 | [GenericTypeExpr] C | semmle.label | [GenericTypeExpr] C | | type_definitions.ts:11:10:11:15 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | | type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.label | [EnumDeclaration,TypeDefinition] enum Co ... blue } | -| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.order | 76 | +| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.order | 77 | | type_definitions.ts:13:6:13:10 | [VarDecl] Color | semmle.label | [VarDecl] Color | | type_definitions.ts:14:3:14:5 | [EnumMember,TypeDefinition] red | semmle.label | [EnumMember,TypeDefinition] red | | type_definitions.ts:14:3:14:5 | [VarDecl] red | semmle.label | [VarDecl] red | @@ -767,29 +966,29 @@ nodes | type_definitions.ts:14:15:14:18 | [EnumMember,TypeDefinition] blue | semmle.label | [EnumMember,TypeDefinition] blue | | type_definitions.ts:14:15:14:18 | [VarDecl] blue | semmle.label | [VarDecl] blue | | type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.label | [DeclStmt] let color = ... | -| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.order | 77 | +| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.order | 78 | | type_definitions.ts:16:5:16:9 | [VarDecl] color | semmle.label | [VarDecl] color | | type_definitions.ts:16:5:16:16 | [VariableDeclarator] color: Color | semmle.label | [VariableDeclarator] color: Color | | type_definitions.ts:16:12:16:16 | [LocalTypeAccess] Color | semmle.label | [LocalTypeAccess] Color | | type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.label | [EnumDeclaration,TypeDefinition] enum En ... ember } | -| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.order | 78 | +| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.order | 79 | | type_definitions.ts:18:6:18:22 | [VarDecl] EnumWithOneMember | semmle.label | [VarDecl] EnumWithOneMember | | type_definitions.ts:18:26:18:31 | [EnumMember,TypeDefinition] member | semmle.label | [EnumMember,TypeDefinition] member | | type_definitions.ts:18:26:18:31 | [VarDecl] member | semmle.label | [VarDecl] member | | type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.label | [DeclStmt] let e = ... | -| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.order | 79 | +| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.order | 80 | | type_definitions.ts:19:5:19:5 | [VarDecl] e | semmle.label | [VarDecl] e | | type_definitions.ts:19:5:19:24 | [VariableDeclarator] e: EnumWithOneMember | semmle.label | [VariableDeclarator] e: EnumWithOneMember | | type_definitions.ts:19:8:19:24 | [LocalTypeAccess] EnumWithOneMember | semmle.label | [LocalTypeAccess] EnumWithOneMember | | type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | -| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | semmle.order | 80 | +| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | semmle.order | 81 | | type_definitions.ts:21:6:21:10 | [Identifier] Alias | semmle.label | [Identifier] Alias | | type_definitions.ts:21:12:21:12 | [Identifier] T | semmle.label | [Identifier] T | | type_definitions.ts:21:12:21:12 | [TypeParameter] T | semmle.label | [TypeParameter] T | | type_definitions.ts:21:17:21:17 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T | | type_definitions.ts:21:17:21:19 | [ArrayTypeExpr] T[] | semmle.label | [ArrayTypeExpr] T[] | | type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.label | [DeclStmt] let aliasForNumberArray = ... | -| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.order | 81 | +| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.order | 82 | | type_definitions.ts:22:5:22:23 | [VarDecl] aliasForNumberArray | semmle.label | [VarDecl] aliasForNumberArray | | type_definitions.ts:22:5:22:38 | [VariableDeclarator] aliasFo ... number> | semmle.label | [VariableDeclarator] aliasFo ... number> | | type_definitions.ts:22:26:22:30 | [LocalTypeAccess] Alias | semmle.label | [LocalTypeAccess] Alias | @@ -920,6 +1119,8 @@ edges | file://:0:0:0:0 | (Arguments) | tst.ts:86:27:86:31 | [VarRef] value | semmle.order | 0 | | file://:0:0:0:0 | (Arguments) | tst.ts:97:27:97:26 | [SpreadElement] ...args | semmle.label | 0 | | file://:0:0:0:0 | (Arguments) | tst.ts:97:27:97:26 | [SpreadElement] ...args | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | tst.ts:159:31:159:35 | [Literal] "red" | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | tst.ts:159:31:159:35 | [Literal] "red" | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | tst.ts:14:17:14:17 | [SimpleParameter] x | semmle.label | 0 | | file://:0:0:0:0 | (Parameters) | tst.ts:14:17:14:17 | [SimpleParameter] x | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | tst.ts:14:28:14:28 | [SimpleParameter] y | semmle.label | 1 | @@ -944,6 +1145,20 @@ edges | file://:0:0:0:0 | (Parameters) | tst.ts:97:27:97:26 | [SimpleParameter] args | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | tst.ts:104:16:104:16 | [SimpleParameter] s | semmle.label | 0 | | file://:0:0:0:0 | (Parameters) | tst.ts:104:16:104:16 | [SimpleParameter] s | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:133:16:133:18 | [SimpleParameter] arg | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:133:16:133:18 | [SimpleParameter] arg | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:144:17:144:21 | [SimpleParameter] shape | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:144:17:144:21 | [SimpleParameter] shape | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:153:8:153:10 | [SimpleParameter] sym | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:153:8:153:10 | [SimpleParameter] sym | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:154:8:154:10 | [SimpleParameter] key | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:154:8:154:10 | [SimpleParameter] key | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:155:8:155:10 | [SimpleParameter] num | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:155:8:155:10 | [SimpleParameter] num | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:166:8:166:10 | [SimpleParameter] key | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:166:8:166:10 | [SimpleParameter] key | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:172:8:172:14 | [SimpleParameter] optName | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:172:8:172:14 | [SimpleParameter] optName | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | type_alias.ts:14:10:14:17 | [SimpleParameter] property | semmle.label | 0 | | file://:0:0:0:0 | (Parameters) | type_alias.ts:14:10:14:17 | [SimpleParameter] property | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | type_alias.ts:21:19:21:21 | [SimpleParameter] key | semmle.label | 0 | @@ -1760,6 +1975,384 @@ edges | tst.ts:127:14:127:28 | [DotExpr] this.#someValue | tst.ts:127:14:127:17 | [ThisExpr] this | semmle.order | 1 | | tst.ts:127:14:127:28 | [DotExpr] this.#someValue | tst.ts:127:19:127:28 | [Label] #someValue | semmle.label | 2 | | tst.ts:127:14:127:28 | [DotExpr] this.#someValue | tst.ts:127:19:127:28 | [Label] #someValue | semmle.order | 2 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:132:8:132:11 | [VarDecl] TS44 | semmle.label | 1 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:132:8:132:11 | [VarDecl] TS44 | semmle.order | 1 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:133:3:138:3 | [FunctionDeclStmt] functio ... } } | semmle.label | 2 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:133:3:138:3 | [FunctionDeclStmt] functio ... } } | semmle.order | 2 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:140:3:142:47 | [TypeAliasDeclaration,TypeDefinition] type Sh ... mber }; | semmle.label | 3 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:140:3:142:47 | [TypeAliasDeclaration,TypeDefinition] type Sh ... mber }; | semmle.order | 3 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:144:3:149:3 | [FunctionDeclStmt] functio ... ; } } | semmle.label | 4 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:144:3:149:3 | [FunctionDeclStmt] functio ... ; } } | semmle.order | 4 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:151:3:162:3 | [FunctionDeclStmt] functio ... 2]; } | semmle.label | 5 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:151:3:162:3 | [FunctionDeclStmt] functio ... 2]; } | semmle.order | 5 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:164:3:177:3 | [FunctionDeclStmt] functio ... "]; } | semmle.label | 6 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:164:3:177:3 | [FunctionDeclStmt] functio ... "]; } | semmle.order | 6 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | semmle.label | 7 | +| tst.ts:132:1:193:1 | [NamespaceDeclaration] module ... } } | tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | semmle.order | 7 | +| tst.ts:133:3:138:3 | [FunctionDeclStmt] functio ... } } | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| tst.ts:133:3:138:3 | [FunctionDeclStmt] functio ... } } | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| tst.ts:133:3:138:3 | [FunctionDeclStmt] functio ... } } | tst.ts:133:12:133:14 | [VarDecl] foo | semmle.label | 0 | +| tst.ts:133:3:138:3 | [FunctionDeclStmt] functio ... } } | tst.ts:133:12:133:14 | [VarDecl] foo | semmle.order | 0 | +| tst.ts:133:3:138:3 | [FunctionDeclStmt] functio ... } } | tst.ts:133:30:138:3 | [BlockStmt] { c ... } } | semmle.label | 5 | +| tst.ts:133:3:138:3 | [FunctionDeclStmt] functio ... } } | tst.ts:133:30:138:3 | [BlockStmt] { c ... } } | semmle.order | 5 | +| tst.ts:133:16:133:18 | [SimpleParameter] arg | tst.ts:133:21:133:27 | [KeywordTypeExpr] unknown | semmle.label | 0 | +| tst.ts:133:16:133:18 | [SimpleParameter] arg | tst.ts:133:21:133:27 | [KeywordTypeExpr] unknown | semmle.order | 0 | +| tst.ts:133:30:138:3 | [BlockStmt] { c ... } } | tst.ts:134:5:134:48 | [DeclStmt] const argIsString = ... | semmle.label | 1 | +| tst.ts:133:30:138:3 | [BlockStmt] { c ... } } | tst.ts:134:5:134:48 | [DeclStmt] const argIsString = ... | semmle.order | 1 | +| tst.ts:133:30:138:3 | [BlockStmt] { c ... } } | tst.ts:135:5:137:5 | [IfStmt] if (arg ... ; } | semmle.label | 2 | +| tst.ts:133:30:138:3 | [BlockStmt] { c ... } } | tst.ts:135:5:137:5 | [IfStmt] if (arg ... ; } | semmle.order | 2 | +| tst.ts:134:5:134:48 | [DeclStmt] const argIsString = ... | tst.ts:134:11:134:47 | [VariableDeclarator] argIsSt ... string" | semmle.label | 1 | +| tst.ts:134:5:134:48 | [DeclStmt] const argIsString = ... | tst.ts:134:11:134:47 | [VariableDeclarator] argIsSt ... string" | semmle.order | 1 | +| tst.ts:134:11:134:47 | [VariableDeclarator] argIsSt ... string" | tst.ts:134:11:134:21 | [VarDecl] argIsString | semmle.label | 1 | +| tst.ts:134:11:134:47 | [VariableDeclarator] argIsSt ... string" | tst.ts:134:11:134:21 | [VarDecl] argIsString | semmle.order | 1 | +| tst.ts:134:11:134:47 | [VariableDeclarator] argIsSt ... string" | tst.ts:134:25:134:47 | [BinaryExpr] typeof ... string" | semmle.label | 2 | +| tst.ts:134:11:134:47 | [VariableDeclarator] argIsSt ... string" | tst.ts:134:25:134:47 | [BinaryExpr] typeof ... string" | semmle.order | 2 | +| tst.ts:134:25:134:34 | [UnaryExpr] typeof arg | tst.ts:134:32:134:34 | [VarRef] arg | semmle.label | 1 | +| tst.ts:134:25:134:34 | [UnaryExpr] typeof arg | tst.ts:134:32:134:34 | [VarRef] arg | semmle.order | 1 | +| tst.ts:134:25:134:47 | [BinaryExpr] typeof ... string" | tst.ts:134:25:134:34 | [UnaryExpr] typeof arg | semmle.label | 1 | +| tst.ts:134:25:134:47 | [BinaryExpr] typeof ... string" | tst.ts:134:25:134:34 | [UnaryExpr] typeof arg | semmle.order | 1 | +| tst.ts:134:25:134:47 | [BinaryExpr] typeof ... string" | tst.ts:134:40:134:47 | [Literal] "string" | semmle.label | 2 | +| tst.ts:134:25:134:47 | [BinaryExpr] typeof ... string" | tst.ts:134:40:134:47 | [Literal] "string" | semmle.order | 2 | +| tst.ts:135:5:137:5 | [IfStmt] if (arg ... ; } | tst.ts:135:9:135:19 | [VarRef] argIsString | semmle.label | 1 | +| tst.ts:135:5:137:5 | [IfStmt] if (arg ... ; } | tst.ts:135:9:135:19 | [VarRef] argIsString | semmle.order | 1 | +| tst.ts:135:5:137:5 | [IfStmt] if (arg ... ; } | tst.ts:135:22:137:5 | [BlockStmt] { ... ; } | semmle.label | 2 | +| tst.ts:135:5:137:5 | [IfStmt] if (arg ... ; } | tst.ts:135:22:137:5 | [BlockStmt] { ... ; } | semmle.order | 2 | +| tst.ts:135:22:137:5 | [BlockStmt] { ... ; } | tst.ts:136:9:136:40 | [DeclStmt] const upper = ... | semmle.label | 1 | +| tst.ts:135:22:137:5 | [BlockStmt] { ... ; } | tst.ts:136:9:136:40 | [DeclStmt] const upper = ... | semmle.order | 1 | +| tst.ts:136:9:136:40 | [DeclStmt] const upper = ... | tst.ts:136:15:136:39 | [VariableDeclarator] upper = ... rCase() | semmle.label | 1 | +| tst.ts:136:9:136:40 | [DeclStmt] const upper = ... | tst.ts:136:15:136:39 | [VariableDeclarator] upper = ... rCase() | semmle.order | 1 | +| tst.ts:136:15:136:39 | [VariableDeclarator] upper = ... rCase() | tst.ts:136:15:136:19 | [VarDecl] upper | semmle.label | 1 | +| tst.ts:136:15:136:39 | [VariableDeclarator] upper = ... rCase() | tst.ts:136:15:136:19 | [VarDecl] upper | semmle.order | 1 | +| tst.ts:136:15:136:39 | [VariableDeclarator] upper = ... rCase() | tst.ts:136:23:136:39 | [MethodCallExpr] arg.toUpperCase() | semmle.label | 2 | +| tst.ts:136:15:136:39 | [VariableDeclarator] upper = ... rCase() | tst.ts:136:23:136:39 | [MethodCallExpr] arg.toUpperCase() | semmle.order | 2 | +| tst.ts:136:23:136:37 | [DotExpr] arg.toUpperCase | tst.ts:136:23:136:25 | [VarRef] arg | semmle.label | 1 | +| tst.ts:136:23:136:37 | [DotExpr] arg.toUpperCase | tst.ts:136:23:136:25 | [VarRef] arg | semmle.order | 1 | +| tst.ts:136:23:136:37 | [DotExpr] arg.toUpperCase | tst.ts:136:27:136:37 | [Label] toUpperCase | semmle.label | 2 | +| tst.ts:136:23:136:37 | [DotExpr] arg.toUpperCase | tst.ts:136:27:136:37 | [Label] toUpperCase | semmle.order | 2 | +| tst.ts:136:23:136:39 | [MethodCallExpr] arg.toUpperCase() | tst.ts:136:23:136:37 | [DotExpr] arg.toUpperCase | semmle.label | 0 | +| tst.ts:136:23:136:39 | [MethodCallExpr] arg.toUpperCase() | tst.ts:136:23:136:37 | [DotExpr] arg.toUpperCase | semmle.order | 0 | +| tst.ts:140:3:142:47 | [TypeAliasDeclaration,TypeDefinition] type Sh ... mber }; | tst.ts:140:8:140:12 | [Identifier] Shape | semmle.label | 1 | +| tst.ts:140:3:142:47 | [TypeAliasDeclaration,TypeDefinition] type Sh ... mber }; | tst.ts:140:8:140:12 | [Identifier] Shape | semmle.order | 1 | +| tst.ts:140:3:142:47 | [TypeAliasDeclaration,TypeDefinition] type Sh ... mber }; | tst.ts:141:7:142:46 | [UnionTypeExpr] \| { kin ... umber } | semmle.label | 2 | +| tst.ts:140:3:142:47 | [TypeAliasDeclaration,TypeDefinition] type Sh ... mber }; | tst.ts:141:7:142:46 | [UnionTypeExpr] \| { kin ... umber } | semmle.order | 2 | +| tst.ts:141:7:142:46 | [UnionTypeExpr] \| { kin ... umber } | tst.ts:141:9:141:42 | [InterfaceTypeExpr] { kind: ... umber } | semmle.label | 1 | +| tst.ts:141:7:142:46 | [UnionTypeExpr] \| { kin ... umber } | tst.ts:141:9:141:42 | [InterfaceTypeExpr] { kind: ... umber } | semmle.order | 1 | +| tst.ts:141:7:142:46 | [UnionTypeExpr] \| { kin ... umber } | tst.ts:142:9:142:46 | [InterfaceTypeExpr] { kind: ... umber } | semmle.label | 2 | +| tst.ts:141:7:142:46 | [UnionTypeExpr] \| { kin ... umber } | tst.ts:142:9:142:46 | [InterfaceTypeExpr] { kind: ... umber } | semmle.order | 2 | +| tst.ts:141:9:141:42 | [InterfaceTypeExpr] { kind: ... umber } | tst.ts:141:11:141:25 | [FieldDeclaration] kind: "circle", | semmle.label | 1 | +| tst.ts:141:9:141:42 | [InterfaceTypeExpr] { kind: ... umber } | tst.ts:141:11:141:25 | [FieldDeclaration] kind: "circle", | semmle.order | 1 | +| tst.ts:141:9:141:42 | [InterfaceTypeExpr] { kind: ... umber } | tst.ts:141:27:141:40 | [FieldDeclaration] radius: number | semmle.label | 2 | +| tst.ts:141:9:141:42 | [InterfaceTypeExpr] { kind: ... umber } | tst.ts:141:27:141:40 | [FieldDeclaration] radius: number | semmle.order | 2 | +| tst.ts:141:11:141:25 | [FieldDeclaration] kind: "circle", | tst.ts:141:11:141:14 | [Label] kind | semmle.label | 1 | +| tst.ts:141:11:141:25 | [FieldDeclaration] kind: "circle", | tst.ts:141:11:141:14 | [Label] kind | semmle.order | 1 | +| tst.ts:141:11:141:25 | [FieldDeclaration] kind: "circle", | tst.ts:141:17:141:24 | [LiteralTypeExpr] "circle" | semmle.label | 2 | +| tst.ts:141:11:141:25 | [FieldDeclaration] kind: "circle", | tst.ts:141:17:141:24 | [LiteralTypeExpr] "circle" | semmle.order | 2 | +| tst.ts:141:27:141:40 | [FieldDeclaration] radius: number | tst.ts:141:27:141:32 | [Label] radius | semmle.label | 1 | +| tst.ts:141:27:141:40 | [FieldDeclaration] radius: number | tst.ts:141:27:141:32 | [Label] radius | semmle.order | 1 | +| tst.ts:141:27:141:40 | [FieldDeclaration] radius: number | tst.ts:141:35:141:40 | [KeywordTypeExpr] number | semmle.label | 2 | +| tst.ts:141:27:141:40 | [FieldDeclaration] radius: number | tst.ts:141:35:141:40 | [KeywordTypeExpr] number | semmle.order | 2 | +| tst.ts:142:9:142:46 | [InterfaceTypeExpr] { kind: ... umber } | tst.ts:142:11:142:25 | [FieldDeclaration] kind: "square", | semmle.label | 1 | +| tst.ts:142:9:142:46 | [InterfaceTypeExpr] { kind: ... umber } | tst.ts:142:11:142:25 | [FieldDeclaration] kind: "square", | semmle.order | 1 | +| tst.ts:142:9:142:46 | [InterfaceTypeExpr] { kind: ... umber } | tst.ts:142:27:142:44 | [FieldDeclaration] sideLength: number | semmle.label | 2 | +| tst.ts:142:9:142:46 | [InterfaceTypeExpr] { kind: ... umber } | tst.ts:142:27:142:44 | [FieldDeclaration] sideLength: number | semmle.order | 2 | +| tst.ts:142:11:142:25 | [FieldDeclaration] kind: "square", | tst.ts:142:11:142:14 | [Label] kind | semmle.label | 1 | +| tst.ts:142:11:142:25 | [FieldDeclaration] kind: "square", | tst.ts:142:11:142:14 | [Label] kind | semmle.order | 1 | +| tst.ts:142:11:142:25 | [FieldDeclaration] kind: "square", | tst.ts:142:17:142:24 | [LiteralTypeExpr] "square" | semmle.label | 2 | +| tst.ts:142:11:142:25 | [FieldDeclaration] kind: "square", | tst.ts:142:17:142:24 | [LiteralTypeExpr] "square" | semmle.order | 2 | +| tst.ts:142:27:142:44 | [FieldDeclaration] sideLength: number | tst.ts:142:27:142:36 | [Label] sideLength | semmle.label | 1 | +| tst.ts:142:27:142:44 | [FieldDeclaration] sideLength: number | tst.ts:142:27:142:36 | [Label] sideLength | semmle.order | 1 | +| tst.ts:142:27:142:44 | [FieldDeclaration] sideLength: number | tst.ts:142:39:142:44 | [KeywordTypeExpr] number | semmle.label | 2 | +| tst.ts:142:27:142:44 | [FieldDeclaration] sideLength: number | tst.ts:142:39:142:44 | [KeywordTypeExpr] number | semmle.order | 2 | +| tst.ts:144:3:149:3 | [FunctionDeclStmt] functio ... ; } } | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| tst.ts:144:3:149:3 | [FunctionDeclStmt] functio ... ; } } | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| tst.ts:144:3:149:3 | [FunctionDeclStmt] functio ... ; } } | tst.ts:144:12:144:15 | [VarDecl] side | semmle.label | 0 | +| tst.ts:144:3:149:3 | [FunctionDeclStmt] functio ... ; } } | tst.ts:144:12:144:15 | [VarDecl] side | semmle.order | 0 | +| tst.ts:144:3:149:3 | [FunctionDeclStmt] functio ... ; } } | tst.ts:144:32:144:37 | [KeywordTypeExpr] number | semmle.label | 4 | +| tst.ts:144:3:149:3 | [FunctionDeclStmt] functio ... ; } } | tst.ts:144:32:144:37 | [KeywordTypeExpr] number | semmle.order | 4 | +| tst.ts:144:3:149:3 | [FunctionDeclStmt] functio ... ; } } | tst.ts:144:39:149:3 | [BlockStmt] { ... ; } } | semmle.label | 5 | +| tst.ts:144:3:149:3 | [FunctionDeclStmt] functio ... ; } } | tst.ts:144:39:149:3 | [BlockStmt] { ... ; } } | semmle.order | 5 | +| tst.ts:144:17:144:21 | [SimpleParameter] shape | tst.ts:144:24:144:28 | [LocalTypeAccess] Shape | semmle.label | 0 | +| tst.ts:144:17:144:21 | [SimpleParameter] shape | tst.ts:144:24:144:28 | [LocalTypeAccess] Shape | semmle.order | 0 | +| tst.ts:144:39:149:3 | [BlockStmt] { ... ; } } | tst.ts:145:7:145:29 | [DeclStmt] const { ... shape; | semmle.label | 1 | +| tst.ts:144:39:149:3 | [BlockStmt] { ... ; } } | tst.ts:145:7:145:29 | [DeclStmt] const { ... shape; | semmle.order | 1 | +| tst.ts:144:39:149:3 | [BlockStmt] { ... ; } } | tst.ts:147:7:148:39 | [IfStmt] if (kin ... ngth; } | semmle.label | 2 | +| tst.ts:144:39:149:3 | [BlockStmt] { ... ; } } | tst.ts:147:7:148:39 | [IfStmt] if (kin ... ngth; } | semmle.order | 2 | +| tst.ts:145:7:145:29 | [DeclStmt] const { ... shape; | tst.ts:145:13:145:28 | [VariableDeclarator] { kind } = shape | semmle.label | 1 | +| tst.ts:145:7:145:29 | [DeclStmt] const { ... shape; | tst.ts:145:13:145:28 | [VariableDeclarator] { kind } = shape | semmle.order | 1 | +| tst.ts:145:13:145:20 | [ObjectPattern] { kind } | tst.ts:145:15:145:18 | [PropertyPattern] kind | semmle.label | 1 | +| tst.ts:145:13:145:20 | [ObjectPattern] { kind } | tst.ts:145:15:145:18 | [PropertyPattern] kind | semmle.order | 1 | +| tst.ts:145:13:145:28 | [VariableDeclarator] { kind } = shape | tst.ts:145:13:145:20 | [ObjectPattern] { kind } | semmle.label | 1 | +| tst.ts:145:13:145:28 | [VariableDeclarator] { kind } = shape | tst.ts:145:13:145:20 | [ObjectPattern] { kind } | semmle.order | 1 | +| tst.ts:145:13:145:28 | [VariableDeclarator] { kind } = shape | tst.ts:145:24:145:28 | [VarRef] shape | semmle.label | 2 | +| tst.ts:145:13:145:28 | [VariableDeclarator] { kind } = shape | tst.ts:145:24:145:28 | [VarRef] shape | semmle.order | 2 | +| tst.ts:145:15:145:18 | [PropertyPattern] kind | tst.ts:145:15:145:18 | [Label] kind | semmle.label | 1 | +| tst.ts:145:15:145:18 | [PropertyPattern] kind | tst.ts:145:15:145:18 | [Label] kind | semmle.order | 1 | +| tst.ts:145:15:145:18 | [PropertyPattern] kind | tst.ts:145:15:145:18 | [VarDecl] kind | semmle.label | 2 | +| tst.ts:145:15:145:18 | [PropertyPattern] kind | tst.ts:145:15:145:18 | [VarDecl] kind | semmle.order | 2 | +| tst.ts:147:7:148:39 | [IfStmt] if (kin ... ngth; } | tst.ts:147:11:147:27 | [BinaryExpr] kind === "circle" | semmle.label | 1 | +| tst.ts:147:7:148:39 | [IfStmt] if (kin ... ngth; } | tst.ts:147:11:147:27 | [BinaryExpr] kind === "circle" | semmle.order | 1 | +| tst.ts:147:7:148:39 | [IfStmt] if (kin ... ngth; } | tst.ts:147:30:147:52 | [BlockStmt] { retur ... adius;} | semmle.label | 2 | +| tst.ts:147:7:148:39 | [IfStmt] if (kin ... ngth; } | tst.ts:147:30:147:52 | [BlockStmt] { retur ... adius;} | semmle.order | 2 | +| tst.ts:147:7:148:39 | [IfStmt] if (kin ... ngth; } | tst.ts:148:12:148:39 | [BlockStmt] { retur ... ngth; } | semmle.label | 3 | +| tst.ts:147:7:148:39 | [IfStmt] if (kin ... ngth; } | tst.ts:148:12:148:39 | [BlockStmt] { retur ... ngth; } | semmle.order | 3 | +| tst.ts:147:11:147:27 | [BinaryExpr] kind === "circle" | tst.ts:147:11:147:14 | [VarRef] kind | semmle.label | 1 | +| tst.ts:147:11:147:27 | [BinaryExpr] kind === "circle" | tst.ts:147:11:147:14 | [VarRef] kind | semmle.order | 1 | +| tst.ts:147:11:147:27 | [BinaryExpr] kind === "circle" | tst.ts:147:20:147:27 | [Literal] "circle" | semmle.label | 2 | +| tst.ts:147:11:147:27 | [BinaryExpr] kind === "circle" | tst.ts:147:20:147:27 | [Literal] "circle" | semmle.order | 2 | +| tst.ts:147:30:147:52 | [BlockStmt] { retur ... adius;} | tst.ts:147:32:147:51 | [ReturnStmt] return shape.radius; | semmle.label | 1 | +| tst.ts:147:30:147:52 | [BlockStmt] { retur ... adius;} | tst.ts:147:32:147:51 | [ReturnStmt] return shape.radius; | semmle.order | 1 | +| tst.ts:147:32:147:51 | [ReturnStmt] return shape.radius; | tst.ts:147:39:147:50 | [DotExpr] shape.radius | semmle.label | 1 | +| tst.ts:147:32:147:51 | [ReturnStmt] return shape.radius; | tst.ts:147:39:147:50 | [DotExpr] shape.radius | semmle.order | 1 | +| tst.ts:147:39:147:50 | [DotExpr] shape.radius | tst.ts:147:39:147:43 | [VarRef] shape | semmle.label | 1 | +| tst.ts:147:39:147:50 | [DotExpr] shape.radius | tst.ts:147:39:147:43 | [VarRef] shape | semmle.order | 1 | +| tst.ts:147:39:147:50 | [DotExpr] shape.radius | tst.ts:147:45:147:50 | [Label] radius | semmle.label | 2 | +| tst.ts:147:39:147:50 | [DotExpr] shape.radius | tst.ts:147:45:147:50 | [Label] radius | semmle.order | 2 | +| tst.ts:148:12:148:39 | [BlockStmt] { retur ... ngth; } | tst.ts:148:14:148:37 | [ReturnStmt] return ... Length; | semmle.label | 1 | +| tst.ts:148:12:148:39 | [BlockStmt] { retur ... ngth; } | tst.ts:148:14:148:37 | [ReturnStmt] return ... Length; | semmle.order | 1 | +| tst.ts:148:14:148:37 | [ReturnStmt] return ... Length; | tst.ts:148:21:148:36 | [DotExpr] shape.sideLength | semmle.label | 1 | +| tst.ts:148:14:148:37 | [ReturnStmt] return ... Length; | tst.ts:148:21:148:36 | [DotExpr] shape.sideLength | semmle.order | 1 | +| tst.ts:148:21:148:36 | [DotExpr] shape.sideLength | tst.ts:148:21:148:25 | [VarRef] shape | semmle.label | 1 | +| tst.ts:148:21:148:36 | [DotExpr] shape.sideLength | tst.ts:148:21:148:25 | [VarRef] shape | semmle.order | 1 | +| tst.ts:148:21:148:36 | [DotExpr] shape.sideLength | tst.ts:148:27:148:36 | [Label] sideLength | semmle.label | 2 | +| tst.ts:148:21:148:36 | [DotExpr] shape.sideLength | tst.ts:148:27:148:36 | [Label] sideLength | semmle.order | 2 | +| tst.ts:151:3:162:3 | [FunctionDeclStmt] functio ... 2]; } | tst.ts:151:12:151:22 | [VarDecl] symbolIndex | semmle.label | 0 | +| tst.ts:151:3:162:3 | [FunctionDeclStmt] functio ... 2]; } | tst.ts:151:12:151:22 | [VarDecl] symbolIndex | semmle.order | 0 | +| tst.ts:151:3:162:3 | [FunctionDeclStmt] functio ... 2]; } | tst.ts:151:26:162:3 | [BlockStmt] { i ... 2]; } | semmle.label | 5 | +| tst.ts:151:3:162:3 | [FunctionDeclStmt] functio ... 2]; } | tst.ts:151:26:162:3 | [BlockStmt] { i ... 2]; } | semmle.order | 5 | +| tst.ts:151:26:162:3 | [BlockStmt] { i ... 2]; } | tst.ts:152:5:156:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | semmle.label | 1 | +| tst.ts:151:26:162:3 | [BlockStmt] { i ... 2]; } | tst.ts:152:5:156:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | semmle.order | 1 | +| tst.ts:151:26:162:3 | [BlockStmt] { i ... 2]; } | tst.ts:158:5:158:28 | [DeclStmt] let colors = ... | semmle.label | 2 | +| tst.ts:151:26:162:3 | [BlockStmt] { i ... 2]; } | tst.ts:158:5:158:28 | [DeclStmt] let colors = ... | semmle.order | 2 | +| tst.ts:151:26:162:3 | [BlockStmt] { i ... 2]; } | tst.ts:159:5:159:38 | [DeclStmt] const red = ... | semmle.label | 3 | +| tst.ts:151:26:162:3 | [BlockStmt] { i ... 2]; } | tst.ts:159:5:159:38 | [DeclStmt] const red = ... | semmle.order | 3 | +| tst.ts:151:26:162:3 | [BlockStmt] { i ... 2]; } | tst.ts:160:5:160:34 | [DeclStmt] const green = ... | semmle.label | 4 | +| tst.ts:151:26:162:3 | [BlockStmt] { i ... 2]; } | tst.ts:160:5:160:34 | [DeclStmt] const green = ... | semmle.order | 4 | +| tst.ts:151:26:162:3 | [BlockStmt] { i ... 2]; } | tst.ts:161:5:161:27 | [DeclStmt] const blue = ... | semmle.label | 5 | +| tst.ts:151:26:162:3 | [BlockStmt] { i ... 2]; } | tst.ts:161:5:161:27 | [DeclStmt] const blue = ... | semmle.order | 5 | +| tst.ts:152:5:156:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | tst.ts:152:15:152:20 | [Identifier] Colors | semmle.label | 1 | +| tst.ts:152:5:156:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | tst.ts:152:15:152:20 | [Identifier] Colors | semmle.order | 1 | +| tst.ts:152:5:156:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | tst.ts:153:7:153:28 | [IndexSignature] [sym: s ... number; | semmle.label | 2 | +| tst.ts:152:5:156:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | tst.ts:153:7:153:28 | [IndexSignature] [sym: s ... number; | semmle.order | 2 | +| tst.ts:152:5:156:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | tst.ts:154:7:154:28 | [IndexSignature] [key: s ... string; | semmle.label | 3 | +| tst.ts:152:5:156:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | tst.ts:154:7:154:28 | [IndexSignature] [key: s ... string; | semmle.order | 3 | +| tst.ts:152:5:156:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | tst.ts:155:7:155:29 | [IndexSignature] [num: n ... oolean; | semmle.label | 4 | +| tst.ts:152:5:156:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | tst.ts:155:7:155:29 | [IndexSignature] [num: n ... oolean; | semmle.order | 4 | +| tst.ts:153:7:153:28 | [FunctionExpr] [sym: s ... number; | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| tst.ts:153:7:153:28 | [FunctionExpr] [sym: s ... number; | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| tst.ts:153:7:153:28 | [FunctionExpr] [sym: s ... number; | tst.ts:153:22:153:27 | [KeywordTypeExpr] number | semmle.label | 4 | +| tst.ts:153:7:153:28 | [FunctionExpr] [sym: s ... number; | tst.ts:153:22:153:27 | [KeywordTypeExpr] number | semmle.order | 4 | +| tst.ts:153:7:153:28 | [IndexSignature] [sym: s ... number; | tst.ts:153:7:153:28 | [FunctionExpr] [sym: s ... number; | semmle.label | 1 | +| tst.ts:153:7:153:28 | [IndexSignature] [sym: s ... number; | tst.ts:153:7:153:28 | [FunctionExpr] [sym: s ... number; | semmle.order | 1 | +| tst.ts:153:8:153:10 | [SimpleParameter] sym | tst.ts:153:13:153:18 | [KeywordTypeExpr] symbol | semmle.label | 0 | +| tst.ts:153:8:153:10 | [SimpleParameter] sym | tst.ts:153:13:153:18 | [KeywordTypeExpr] symbol | semmle.order | 0 | +| tst.ts:154:7:154:28 | [FunctionExpr] [key: s ... string; | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| tst.ts:154:7:154:28 | [FunctionExpr] [key: s ... string; | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| tst.ts:154:7:154:28 | [FunctionExpr] [key: s ... string; | tst.ts:154:22:154:27 | [KeywordTypeExpr] string | semmle.label | 4 | +| tst.ts:154:7:154:28 | [FunctionExpr] [key: s ... string; | tst.ts:154:22:154:27 | [KeywordTypeExpr] string | semmle.order | 4 | +| tst.ts:154:7:154:28 | [IndexSignature] [key: s ... string; | tst.ts:154:7:154:28 | [FunctionExpr] [key: s ... string; | semmle.label | 1 | +| tst.ts:154:7:154:28 | [IndexSignature] [key: s ... string; | tst.ts:154:7:154:28 | [FunctionExpr] [key: s ... string; | semmle.order | 1 | +| tst.ts:154:8:154:10 | [SimpleParameter] key | tst.ts:154:13:154:18 | [KeywordTypeExpr] string | semmle.label | 0 | +| tst.ts:154:8:154:10 | [SimpleParameter] key | tst.ts:154:13:154:18 | [KeywordTypeExpr] string | semmle.order | 0 | +| tst.ts:155:7:155:29 | [FunctionExpr] [num: n ... oolean; | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| tst.ts:155:7:155:29 | [FunctionExpr] [num: n ... oolean; | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| tst.ts:155:7:155:29 | [FunctionExpr] [num: n ... oolean; | tst.ts:155:22:155:28 | [KeywordTypeExpr] boolean | semmle.label | 4 | +| tst.ts:155:7:155:29 | [FunctionExpr] [num: n ... oolean; | tst.ts:155:22:155:28 | [KeywordTypeExpr] boolean | semmle.order | 4 | +| tst.ts:155:7:155:29 | [IndexSignature] [num: n ... oolean; | tst.ts:155:7:155:29 | [FunctionExpr] [num: n ... oolean; | semmle.label | 1 | +| tst.ts:155:7:155:29 | [IndexSignature] [num: n ... oolean; | tst.ts:155:7:155:29 | [FunctionExpr] [num: n ... oolean; | semmle.order | 1 | +| tst.ts:155:8:155:10 | [SimpleParameter] num | tst.ts:155:13:155:18 | [KeywordTypeExpr] number | semmle.label | 0 | +| tst.ts:155:8:155:10 | [SimpleParameter] num | tst.ts:155:13:155:18 | [KeywordTypeExpr] number | semmle.order | 0 | +| tst.ts:158:5:158:28 | [DeclStmt] let colors = ... | tst.ts:158:9:158:27 | [VariableDeclarator] colors: Colors = {} | semmle.label | 1 | +| tst.ts:158:5:158:28 | [DeclStmt] let colors = ... | tst.ts:158:9:158:27 | [VariableDeclarator] colors: Colors = {} | semmle.order | 1 | +| tst.ts:158:9:158:27 | [VariableDeclarator] colors: Colors = {} | tst.ts:158:9:158:14 | [VarDecl] colors | semmle.label | 1 | +| tst.ts:158:9:158:27 | [VariableDeclarator] colors: Colors = {} | tst.ts:158:9:158:14 | [VarDecl] colors | semmle.order | 1 | +| tst.ts:158:9:158:27 | [VariableDeclarator] colors: Colors = {} | tst.ts:158:17:158:22 | [LocalTypeAccess] Colors | semmle.label | 2 | +| tst.ts:158:9:158:27 | [VariableDeclarator] colors: Colors = {} | tst.ts:158:17:158:22 | [LocalTypeAccess] Colors | semmle.order | 2 | +| tst.ts:158:9:158:27 | [VariableDeclarator] colors: Colors = {} | tst.ts:158:26:158:27 | [ObjectExpr] {} | semmle.label | 3 | +| tst.ts:158:9:158:27 | [VariableDeclarator] colors: Colors = {} | tst.ts:158:26:158:27 | [ObjectExpr] {} | semmle.order | 3 | +| tst.ts:159:5:159:38 | [DeclStmt] const red = ... | tst.ts:159:11:159:37 | [VariableDeclarator] red = c ... "red")] | semmle.label | 1 | +| tst.ts:159:5:159:38 | [DeclStmt] const red = ... | tst.ts:159:11:159:37 | [VariableDeclarator] red = c ... "red")] | semmle.order | 1 | +| tst.ts:159:11:159:37 | [VariableDeclarator] red = c ... "red")] | tst.ts:159:11:159:13 | [VarDecl] red | semmle.label | 1 | +| tst.ts:159:11:159:37 | [VariableDeclarator] red = c ... "red")] | tst.ts:159:11:159:13 | [VarDecl] red | semmle.order | 1 | +| tst.ts:159:11:159:37 | [VariableDeclarator] red = c ... "red")] | tst.ts:159:17:159:37 | [IndexExpr] colors[ ... "red")] | semmle.label | 2 | +| tst.ts:159:11:159:37 | [VariableDeclarator] red = c ... "red")] | tst.ts:159:17:159:37 | [IndexExpr] colors[ ... "red")] | semmle.order | 2 | +| tst.ts:159:17:159:37 | [IndexExpr] colors[ ... "red")] | tst.ts:159:17:159:22 | [VarRef] colors | semmle.label | 1 | +| tst.ts:159:17:159:37 | [IndexExpr] colors[ ... "red")] | tst.ts:159:17:159:22 | [VarRef] colors | semmle.order | 1 | +| tst.ts:159:17:159:37 | [IndexExpr] colors[ ... "red")] | tst.ts:159:24:159:36 | [CallExpr] Symbol("red") | semmle.label | 2 | +| tst.ts:159:17:159:37 | [IndexExpr] colors[ ... "red")] | tst.ts:159:24:159:36 | [CallExpr] Symbol("red") | semmle.order | 2 | +| tst.ts:159:24:159:36 | [CallExpr] Symbol("red") | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| tst.ts:159:24:159:36 | [CallExpr] Symbol("red") | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| tst.ts:159:24:159:36 | [CallExpr] Symbol("red") | tst.ts:159:24:159:29 | [VarRef] Symbol | semmle.label | 0 | +| tst.ts:159:24:159:36 | [CallExpr] Symbol("red") | tst.ts:159:24:159:29 | [VarRef] Symbol | semmle.order | 0 | +| tst.ts:160:5:160:34 | [DeclStmt] const green = ... | tst.ts:160:11:160:33 | [VariableDeclarator] green = ... green"] | semmle.label | 1 | +| tst.ts:160:5:160:34 | [DeclStmt] const green = ... | tst.ts:160:11:160:33 | [VariableDeclarator] green = ... green"] | semmle.order | 1 | +| tst.ts:160:11:160:33 | [VariableDeclarator] green = ... green"] | tst.ts:160:11:160:15 | [VarDecl] green | semmle.label | 1 | +| tst.ts:160:11:160:33 | [VariableDeclarator] green = ... green"] | tst.ts:160:11:160:15 | [VarDecl] green | semmle.order | 1 | +| tst.ts:160:11:160:33 | [VariableDeclarator] green = ... green"] | tst.ts:160:19:160:33 | [IndexExpr] colors["green"] | semmle.label | 2 | +| tst.ts:160:11:160:33 | [VariableDeclarator] green = ... green"] | tst.ts:160:19:160:33 | [IndexExpr] colors["green"] | semmle.order | 2 | +| tst.ts:160:19:160:33 | [IndexExpr] colors["green"] | tst.ts:160:19:160:24 | [VarRef] colors | semmle.label | 1 | +| tst.ts:160:19:160:33 | [IndexExpr] colors["green"] | tst.ts:160:19:160:24 | [VarRef] colors | semmle.order | 1 | +| tst.ts:160:19:160:33 | [IndexExpr] colors["green"] | tst.ts:160:26:160:32 | [Literal] "green" | semmle.label | 2 | +| tst.ts:160:19:160:33 | [IndexExpr] colors["green"] | tst.ts:160:26:160:32 | [Literal] "green" | semmle.order | 2 | +| tst.ts:161:5:161:27 | [DeclStmt] const blue = ... | tst.ts:161:11:161:26 | [VariableDeclarator] blue = colors[2] | semmle.label | 1 | +| tst.ts:161:5:161:27 | [DeclStmt] const blue = ... | tst.ts:161:11:161:26 | [VariableDeclarator] blue = colors[2] | semmle.order | 1 | +| tst.ts:161:11:161:26 | [VariableDeclarator] blue = colors[2] | tst.ts:161:11:161:14 | [VarDecl] blue | semmle.label | 1 | +| tst.ts:161:11:161:26 | [VariableDeclarator] blue = colors[2] | tst.ts:161:11:161:14 | [VarDecl] blue | semmle.order | 1 | +| tst.ts:161:11:161:26 | [VariableDeclarator] blue = colors[2] | tst.ts:161:18:161:26 | [IndexExpr] colors[2] | semmle.label | 2 | +| tst.ts:161:11:161:26 | [VariableDeclarator] blue = colors[2] | tst.ts:161:18:161:26 | [IndexExpr] colors[2] | semmle.order | 2 | +| tst.ts:161:18:161:26 | [IndexExpr] colors[2] | tst.ts:161:18:161:23 | [VarRef] colors | semmle.label | 1 | +| tst.ts:161:18:161:26 | [IndexExpr] colors[2] | tst.ts:161:18:161:23 | [VarRef] colors | semmle.order | 1 | +| tst.ts:161:18:161:26 | [IndexExpr] colors[2] | tst.ts:161:25:161:25 | [Literal] 2 | semmle.label | 2 | +| tst.ts:161:18:161:26 | [IndexExpr] colors[2] | tst.ts:161:25:161:25 | [Literal] 2 | semmle.order | 2 | +| tst.ts:164:3:177:3 | [FunctionDeclStmt] functio ... "]; } | tst.ts:164:12:164:29 | [VarDecl] stringPatternIndex | semmle.label | 0 | +| tst.ts:164:3:177:3 | [FunctionDeclStmt] functio ... "]; } | tst.ts:164:12:164:29 | [VarDecl] stringPatternIndex | semmle.order | 0 | +| tst.ts:164:3:177:3 | [FunctionDeclStmt] functio ... "]; } | tst.ts:164:33:177:3 | [BlockStmt] { i ... "]; } | semmle.label | 5 | +| tst.ts:164:3:177:3 | [FunctionDeclStmt] functio ... "]; } | tst.ts:164:33:177:3 | [BlockStmt] { i ... "]; } | semmle.order | 5 | +| tst.ts:164:33:177:3 | [BlockStmt] { i ... "]; } | tst.ts:165:5:167:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | semmle.label | 1 | +| tst.ts:164:33:177:3 | [BlockStmt] { i ... "]; } | tst.ts:165:5:167:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | semmle.order | 1 | +| tst.ts:164:33:177:3 | [BlockStmt] { i ... "]; } | tst.ts:168:5:168:23 | [DeclStmt] var bla = ... | semmle.label | 2 | +| tst.ts:164:33:177:3 | [BlockStmt] { i ... "]; } | tst.ts:168:5:168:23 | [DeclStmt] var bla = ... | semmle.order | 2 | +| tst.ts:164:33:177:3 | [BlockStmt] { i ... "]; } | tst.ts:169:5:169:29 | [DeclStmt] const bar = ... | semmle.label | 3 | +| tst.ts:164:33:177:3 | [BlockStmt] { i ... "]; } | tst.ts:169:5:169:29 | [DeclStmt] const bar = ... | semmle.order | 3 | +| tst.ts:164:33:177:3 | [BlockStmt] { i ... "]; } | tst.ts:171:5:173:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | semmle.label | 4 | +| tst.ts:164:33:177:3 | [BlockStmt] { i ... "]; } | tst.ts:171:5:173:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | semmle.order | 4 | +| tst.ts:164:33:177:3 | [BlockStmt] { i ... "]; } | tst.ts:175:5:175:26 | [DeclStmt] const data = ... | semmle.label | 5 | +| tst.ts:164:33:177:3 | [BlockStmt] { i ... "]; } | tst.ts:175:5:175:26 | [DeclStmt] const data = ... | semmle.order | 5 | +| tst.ts:164:33:177:3 | [BlockStmt] { i ... "]; } | tst.ts:176:5:176:28 | [DeclStmt] const baz = ... | semmle.label | 6 | +| tst.ts:164:33:177:3 | [BlockStmt] { i ... "]; } | tst.ts:176:5:176:28 | [DeclStmt] const baz = ... | semmle.order | 6 | +| tst.ts:165:5:167:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | tst.ts:165:15:165:17 | [Identifier] Foo | semmle.label | 1 | +| tst.ts:165:5:167:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | tst.ts:165:15:165:17 | [Identifier] Foo | semmle.order | 1 | +| tst.ts:165:5:167:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | tst.ts:166:7:166:37 | [IndexSignature] [key: ` ... number; | semmle.label | 2 | +| tst.ts:165:5:167:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | tst.ts:166:7:166:37 | [IndexSignature] [key: ` ... number; | semmle.order | 2 | +| tst.ts:166:7:166:37 | [FunctionExpr] [key: ` ... number; | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| tst.ts:166:7:166:37 | [FunctionExpr] [key: ` ... number; | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| tst.ts:166:7:166:37 | [FunctionExpr] [key: ` ... number; | tst.ts:166:31:166:36 | [KeywordTypeExpr] number | semmle.label | 4 | +| tst.ts:166:7:166:37 | [FunctionExpr] [key: ` ... number; | tst.ts:166:31:166:36 | [KeywordTypeExpr] number | semmle.order | 4 | +| tst.ts:166:7:166:37 | [IndexSignature] [key: ` ... number; | tst.ts:166:7:166:37 | [FunctionExpr] [key: ` ... number; | semmle.label | 1 | +| tst.ts:166:7:166:37 | [IndexSignature] [key: ` ... number; | tst.ts:166:7:166:37 | [FunctionExpr] [key: ` ... number; | semmle.order | 1 | +| tst.ts:166:8:166:10 | [SimpleParameter] key | tst.ts:166:13:166:27 | [TemplateLiteralTypeExpr] `foo-${number}` | semmle.label | 0 | +| tst.ts:166:8:166:10 | [SimpleParameter] key | tst.ts:166:13:166:27 | [TemplateLiteralTypeExpr] `foo-${number}` | semmle.order | 0 | +| tst.ts:166:13:166:27 | [TemplateLiteralTypeExpr] `foo-${number}` | tst.ts:166:14:166:17 | [LiteralTypeExpr] foo- | semmle.label | 1 | +| tst.ts:166:13:166:27 | [TemplateLiteralTypeExpr] `foo-${number}` | tst.ts:166:14:166:17 | [LiteralTypeExpr] foo- | semmle.order | 1 | +| tst.ts:166:13:166:27 | [TemplateLiteralTypeExpr] `foo-${number}` | tst.ts:166:20:166:25 | [KeywordTypeExpr] number | semmle.label | 2 | +| tst.ts:166:13:166:27 | [TemplateLiteralTypeExpr] `foo-${number}` | tst.ts:166:20:166:25 | [KeywordTypeExpr] number | semmle.order | 2 | +| tst.ts:168:5:168:23 | [DeclStmt] var bla = ... | tst.ts:168:9:168:22 | [VariableDeclarator] bla : Foo = {} | semmle.label | 1 | +| tst.ts:168:5:168:23 | [DeclStmt] var bla = ... | tst.ts:168:9:168:22 | [VariableDeclarator] bla : Foo = {} | semmle.order | 1 | +| tst.ts:168:9:168:22 | [VariableDeclarator] bla : Foo = {} | tst.ts:168:9:168:11 | [VarDecl] bla | semmle.label | 1 | +| tst.ts:168:9:168:22 | [VariableDeclarator] bla : Foo = {} | tst.ts:168:9:168:11 | [VarDecl] bla | semmle.order | 1 | +| tst.ts:168:9:168:22 | [VariableDeclarator] bla : Foo = {} | tst.ts:168:15:168:17 | [LocalTypeAccess] Foo | semmle.label | 2 | +| tst.ts:168:9:168:22 | [VariableDeclarator] bla : Foo = {} | tst.ts:168:15:168:17 | [LocalTypeAccess] Foo | semmle.order | 2 | +| tst.ts:168:9:168:22 | [VariableDeclarator] bla : Foo = {} | tst.ts:168:21:168:22 | [ObjectExpr] {} | semmle.label | 3 | +| tst.ts:168:9:168:22 | [VariableDeclarator] bla : Foo = {} | tst.ts:168:21:168:22 | [ObjectExpr] {} | semmle.order | 3 | +| tst.ts:169:5:169:29 | [DeclStmt] const bar = ... | tst.ts:169:11:169:28 | [VariableDeclarator] bar = bla[`foo-1`] | semmle.label | 1 | +| tst.ts:169:5:169:29 | [DeclStmt] const bar = ... | tst.ts:169:11:169:28 | [VariableDeclarator] bar = bla[`foo-1`] | semmle.order | 1 | +| tst.ts:169:11:169:28 | [VariableDeclarator] bar = bla[`foo-1`] | tst.ts:169:11:169:13 | [VarDecl] bar | semmle.label | 1 | +| tst.ts:169:11:169:28 | [VariableDeclarator] bar = bla[`foo-1`] | tst.ts:169:11:169:13 | [VarDecl] bar | semmle.order | 1 | +| tst.ts:169:11:169:28 | [VariableDeclarator] bar = bla[`foo-1`] | tst.ts:169:17:169:28 | [IndexExpr] bla[`foo-1`] | semmle.label | 2 | +| tst.ts:169:11:169:28 | [VariableDeclarator] bar = bla[`foo-1`] | tst.ts:169:17:169:28 | [IndexExpr] bla[`foo-1`] | semmle.order | 2 | +| tst.ts:169:17:169:28 | [IndexExpr] bla[`foo-1`] | tst.ts:169:17:169:19 | [VarRef] bla | semmle.label | 1 | +| tst.ts:169:17:169:28 | [IndexExpr] bla[`foo-1`] | tst.ts:169:17:169:19 | [VarRef] bla | semmle.order | 1 | +| tst.ts:169:17:169:28 | [IndexExpr] bla[`foo-1`] | tst.ts:169:21:169:27 | [TemplateLiteral] `foo-1` | semmle.label | 2 | +| tst.ts:169:17:169:28 | [IndexExpr] bla[`foo-1`] | tst.ts:169:21:169:27 | [TemplateLiteral] `foo-1` | semmle.order | 2 | +| tst.ts:169:21:169:27 | [TemplateLiteral] `foo-1` | tst.ts:169:21:169:27 | [TemplateElement] `foo-1` | semmle.label | 1 | +| tst.ts:169:21:169:27 | [TemplateLiteral] `foo-1` | tst.ts:169:21:169:27 | [TemplateElement] `foo-1` | semmle.order | 1 | +| tst.ts:171:5:173:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | tst.ts:171:15:171:18 | [Identifier] Data | semmle.label | 1 | +| tst.ts:171:5:173:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | tst.ts:171:15:171:18 | [Identifier] Data | semmle.order | 1 | +| tst.ts:171:5:173:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | tst.ts:172:7:172:42 | [IndexSignature] [optNam ... oolean; | semmle.label | 2 | +| tst.ts:171:5:173:5 | [InterfaceDeclaration,TypeDefinition] interfa ... ; } | tst.ts:172:7:172:42 | [IndexSignature] [optNam ... oolean; | semmle.order | 2 | +| tst.ts:172:7:172:42 | [FunctionExpr] [optNam ... oolean; | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| tst.ts:172:7:172:42 | [FunctionExpr] [optNam ... oolean; | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| tst.ts:172:7:172:42 | [FunctionExpr] [optNam ... oolean; | tst.ts:172:35:172:41 | [KeywordTypeExpr] boolean | semmle.label | 4 | +| tst.ts:172:7:172:42 | [FunctionExpr] [optNam ... oolean; | tst.ts:172:35:172:41 | [KeywordTypeExpr] boolean | semmle.order | 4 | +| tst.ts:172:7:172:42 | [IndexSignature] [optNam ... oolean; | tst.ts:172:7:172:42 | [FunctionExpr] [optNam ... oolean; | semmle.label | 1 | +| tst.ts:172:7:172:42 | [IndexSignature] [optNam ... oolean; | tst.ts:172:7:172:42 | [FunctionExpr] [optNam ... oolean; | semmle.order | 1 | +| tst.ts:172:8:172:14 | [SimpleParameter] optName | tst.ts:172:17:172:31 | [UnionTypeExpr] string \| symbol | semmle.label | 0 | +| tst.ts:172:8:172:14 | [SimpleParameter] optName | tst.ts:172:17:172:31 | [UnionTypeExpr] string \| symbol | semmle.order | 0 | +| tst.ts:172:17:172:31 | [UnionTypeExpr] string \| symbol | tst.ts:172:17:172:22 | [KeywordTypeExpr] string | semmle.label | 1 | +| tst.ts:172:17:172:31 | [UnionTypeExpr] string \| symbol | tst.ts:172:17:172:22 | [KeywordTypeExpr] string | semmle.order | 1 | +| tst.ts:172:17:172:31 | [UnionTypeExpr] string \| symbol | tst.ts:172:26:172:31 | [KeywordTypeExpr] symbol | semmle.label | 2 | +| tst.ts:172:17:172:31 | [UnionTypeExpr] string \| symbol | tst.ts:172:26:172:31 | [KeywordTypeExpr] symbol | semmle.order | 2 | +| tst.ts:175:5:175:26 | [DeclStmt] const data = ... | tst.ts:175:11:175:25 | [VariableDeclarator] data: Data = {} | semmle.label | 1 | +| tst.ts:175:5:175:26 | [DeclStmt] const data = ... | tst.ts:175:11:175:25 | [VariableDeclarator] data: Data = {} | semmle.order | 1 | +| tst.ts:175:11:175:25 | [VariableDeclarator] data: Data = {} | tst.ts:175:11:175:14 | [VarDecl] data | semmle.label | 1 | +| tst.ts:175:11:175:25 | [VariableDeclarator] data: Data = {} | tst.ts:175:11:175:14 | [VarDecl] data | semmle.order | 1 | +| tst.ts:175:11:175:25 | [VariableDeclarator] data: Data = {} | tst.ts:175:17:175:20 | [LocalTypeAccess] Data | semmle.label | 2 | +| tst.ts:175:11:175:25 | [VariableDeclarator] data: Data = {} | tst.ts:175:17:175:20 | [LocalTypeAccess] Data | semmle.order | 2 | +| tst.ts:175:11:175:25 | [VariableDeclarator] data: Data = {} | tst.ts:175:24:175:25 | [ObjectExpr] {} | semmle.label | 3 | +| tst.ts:175:11:175:25 | [VariableDeclarator] data: Data = {} | tst.ts:175:24:175:25 | [ObjectExpr] {} | semmle.order | 3 | +| tst.ts:176:5:176:28 | [DeclStmt] const baz = ... | tst.ts:176:11:176:27 | [VariableDeclarator] baz = data["foo"] | semmle.label | 1 | +| tst.ts:176:5:176:28 | [DeclStmt] const baz = ... | tst.ts:176:11:176:27 | [VariableDeclarator] baz = data["foo"] | semmle.order | 1 | +| tst.ts:176:11:176:27 | [VariableDeclarator] baz = data["foo"] | tst.ts:176:11:176:13 | [VarDecl] baz | semmle.label | 1 | +| tst.ts:176:11:176:27 | [VariableDeclarator] baz = data["foo"] | tst.ts:176:11:176:13 | [VarDecl] baz | semmle.order | 1 | +| tst.ts:176:11:176:27 | [VariableDeclarator] baz = data["foo"] | tst.ts:176:17:176:27 | [IndexExpr] data["foo"] | semmle.label | 2 | +| tst.ts:176:11:176:27 | [VariableDeclarator] baz = data["foo"] | tst.ts:176:17:176:27 | [IndexExpr] data["foo"] | semmle.order | 2 | +| tst.ts:176:17:176:27 | [IndexExpr] data["foo"] | tst.ts:176:17:176:20 | [VarRef] data | semmle.label | 1 | +| tst.ts:176:17:176:27 | [IndexExpr] data["foo"] | tst.ts:176:17:176:20 | [VarRef] data | semmle.order | 1 | +| tst.ts:176:17:176:27 | [IndexExpr] data["foo"] | tst.ts:176:22:176:26 | [Literal] "foo" | semmle.label | 2 | +| tst.ts:176:17:176:27 | [IndexExpr] data["foo"] | tst.ts:176:22:176:26 | [Literal] "foo" | semmle.order | 2 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:179:9:179:11 | [VarDecl] Foo | semmle.label | 1 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:179:9:179:11 | [VarDecl] Foo | semmle.order | 1 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:179:13:179:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | 2 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:179:13:179:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.order | 2 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:180:5:180:22 | [ClassInitializedMember,FieldDeclaration] static #count = 0; | semmle.label | 3 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:180:5:180:22 | [ClassInitializedMember,FieldDeclaration] static #count = 0; | semmle.order | 3 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:182:5:184:5 | [ClassInitializedMember,GetterMethodDefinition] get cou ... ; } | semmle.label | 4 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:182:5:184:5 | [ClassInitializedMember,GetterMethodDefinition] get cou ... ; } | semmle.order | 4 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:185:5:187:5 | [ClassInitializedMember] static ... ; } | semmle.label | 5 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:185:5:187:5 | [ClassInitializedMember] static ... ; } | semmle.order | 5 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:188:5:190:5 | [ClassInitializedMember] static ... ; } | semmle.label | 6 | +| tst.ts:179:3:192:3 | [ClassDefinition,TypeDefinition] class F ... } | tst.ts:188:5:190:5 | [ClassInitializedMember] static ... ; } | semmle.order | 6 | +| tst.ts:179:13:179:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:179:13:179:12 | [FunctionExpr] () {} | semmle.label | 2 | +| tst.ts:179:13:179:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:179:13:179:12 | [FunctionExpr] () {} | semmle.order | 2 | +| tst.ts:179:13:179:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:179:13:179:12 | [Label] constructor | semmle.label | 1 | +| tst.ts:179:13:179:12 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:179:13:179:12 | [Label] constructor | semmle.order | 1 | +| tst.ts:179:13:179:12 | [FunctionExpr] () {} | tst.ts:179:13:179:12 | [BlockStmt] {} | semmle.label | 5 | +| tst.ts:179:13:179:12 | [FunctionExpr] () {} | tst.ts:179:13:179:12 | [BlockStmt] {} | semmle.order | 5 | +| tst.ts:180:5:180:22 | [ClassInitializedMember,FieldDeclaration] static #count = 0; | tst.ts:180:12:180:17 | [Label] #count | semmle.label | 1 | +| tst.ts:180:5:180:22 | [ClassInitializedMember,FieldDeclaration] static #count = 0; | tst.ts:180:12:180:17 | [Label] #count | semmle.order | 1 | +| tst.ts:180:5:180:22 | [ClassInitializedMember,FieldDeclaration] static #count = 0; | tst.ts:180:21:180:21 | [Literal] 0 | semmle.label | 2 | +| tst.ts:180:5:180:22 | [ClassInitializedMember,FieldDeclaration] static #count = 0; | tst.ts:180:21:180:21 | [Literal] 0 | semmle.order | 2 | +| tst.ts:182:5:184:5 | [ClassInitializedMember,GetterMethodDefinition] get cou ... ; } | tst.ts:182:5:184:5 | [FunctionExpr] get cou ... ; } | semmle.label | 1 | +| tst.ts:182:5:184:5 | [ClassInitializedMember,GetterMethodDefinition] get cou ... ; } | tst.ts:182:5:184:5 | [FunctionExpr] get cou ... ; } | semmle.order | 1 | +| tst.ts:182:5:184:5 | [ClassInitializedMember,GetterMethodDefinition] get cou ... ; } | tst.ts:182:9:182:13 | [Label] count | semmle.label | 2 | +| tst.ts:182:5:184:5 | [ClassInitializedMember,GetterMethodDefinition] get cou ... ; } | tst.ts:182:9:182:13 | [Label] count | semmle.order | 2 | +| tst.ts:182:5:184:5 | [FunctionExpr] get cou ... ; } | tst.ts:182:17:184:5 | [BlockStmt] { ... ; } | semmle.label | 5 | +| tst.ts:182:5:184:5 | [FunctionExpr] get cou ... ; } | tst.ts:182:17:184:5 | [BlockStmt] { ... ; } | semmle.order | 5 | +| tst.ts:182:17:184:5 | [BlockStmt] { ... ; } | tst.ts:183:9:183:26 | [ReturnStmt] return Foo.#count; | semmle.label | 1 | +| tst.ts:182:17:184:5 | [BlockStmt] { ... ; } | tst.ts:183:9:183:26 | [ReturnStmt] return Foo.#count; | semmle.order | 1 | +| tst.ts:183:9:183:26 | [ReturnStmt] return Foo.#count; | tst.ts:183:16:183:25 | [DotExpr] Foo.#count | semmle.label | 1 | +| tst.ts:183:9:183:26 | [ReturnStmt] return Foo.#count; | tst.ts:183:16:183:25 | [DotExpr] Foo.#count | semmle.order | 1 | +| tst.ts:183:16:183:25 | [DotExpr] Foo.#count | tst.ts:183:16:183:18 | [VarRef] Foo | semmle.label | 1 | +| tst.ts:183:16:183:25 | [DotExpr] Foo.#count | tst.ts:183:16:183:18 | [VarRef] Foo | semmle.order | 1 | +| tst.ts:183:16:183:25 | [DotExpr] Foo.#count | tst.ts:183:20:183:25 | [Label] #count | semmle.label | 2 | +| tst.ts:183:16:183:25 | [DotExpr] Foo.#count | tst.ts:183:20:183:25 | [Label] #count | semmle.order | 2 | +| tst.ts:185:5:187:5 | [BlockStmt] static ... ; } | tst.ts:186:7:186:22 | [ExprStmt] Foo.#count += 3; | semmle.label | 1 | +| tst.ts:185:5:187:5 | [BlockStmt] static ... ; } | tst.ts:186:7:186:22 | [ExprStmt] Foo.#count += 3; | semmle.order | 1 | +| tst.ts:185:5:187:5 | [ClassInitializedMember] static ... ; } | tst.ts:185:5:187:5 | [BlockStmt] static ... ; } | semmle.label | 1 | +| tst.ts:185:5:187:5 | [ClassInitializedMember] static ... ; } | tst.ts:185:5:187:5 | [BlockStmt] static ... ; } | semmle.order | 1 | +| tst.ts:186:7:186:16 | [DotExpr] Foo.#count | tst.ts:186:7:186:9 | [VarRef] Foo | semmle.label | 1 | +| tst.ts:186:7:186:16 | [DotExpr] Foo.#count | tst.ts:186:7:186:9 | [VarRef] Foo | semmle.order | 1 | +| tst.ts:186:7:186:16 | [DotExpr] Foo.#count | tst.ts:186:11:186:16 | [Label] #count | semmle.label | 2 | +| tst.ts:186:7:186:16 | [DotExpr] Foo.#count | tst.ts:186:11:186:16 | [Label] #count | semmle.order | 2 | +| tst.ts:186:7:186:21 | [CompoundAssignExpr] Foo.#count += 3 | tst.ts:186:7:186:16 | [DotExpr] Foo.#count | semmle.label | 1 | +| tst.ts:186:7:186:21 | [CompoundAssignExpr] Foo.#count += 3 | tst.ts:186:7:186:16 | [DotExpr] Foo.#count | semmle.order | 1 | +| tst.ts:186:7:186:21 | [CompoundAssignExpr] Foo.#count += 3 | tst.ts:186:21:186:21 | [Literal] 3 | semmle.label | 2 | +| tst.ts:186:7:186:21 | [CompoundAssignExpr] Foo.#count += 3 | tst.ts:186:21:186:21 | [Literal] 3 | semmle.order | 2 | +| tst.ts:186:7:186:22 | [ExprStmt] Foo.#count += 3; | tst.ts:186:7:186:21 | [CompoundAssignExpr] Foo.#count += 3 | semmle.label | 1 | +| tst.ts:186:7:186:22 | [ExprStmt] Foo.#count += 3; | tst.ts:186:7:186:21 | [CompoundAssignExpr] Foo.#count += 3 | semmle.order | 1 | +| tst.ts:188:5:190:5 | [BlockStmt] static ... ; } | tst.ts:189:7:189:29 | [DeclStmt] var count = ... | semmle.label | 1 | +| tst.ts:188:5:190:5 | [BlockStmt] static ... ; } | tst.ts:189:7:189:29 | [DeclStmt] var count = ... | semmle.order | 1 | +| tst.ts:188:5:190:5 | [ClassInitializedMember] static ... ; } | tst.ts:188:5:190:5 | [BlockStmt] static ... ; } | semmle.label | 1 | +| tst.ts:188:5:190:5 | [ClassInitializedMember] static ... ; } | tst.ts:188:5:190:5 | [BlockStmt] static ... ; } | semmle.order | 1 | +| tst.ts:189:7:189:29 | [DeclStmt] var count = ... | tst.ts:189:11:189:28 | [VariableDeclarator] count = Foo.#count | semmle.label | 1 | +| tst.ts:189:7:189:29 | [DeclStmt] var count = ... | tst.ts:189:11:189:28 | [VariableDeclarator] count = Foo.#count | semmle.order | 1 | +| tst.ts:189:11:189:28 | [VariableDeclarator] count = Foo.#count | tst.ts:189:11:189:15 | [VarDecl] count | semmle.label | 1 | +| tst.ts:189:11:189:28 | [VariableDeclarator] count = Foo.#count | tst.ts:189:11:189:15 | [VarDecl] count | semmle.order | 1 | +| tst.ts:189:11:189:28 | [VariableDeclarator] count = Foo.#count | tst.ts:189:19:189:28 | [DotExpr] Foo.#count | semmle.label | 2 | +| tst.ts:189:11:189:28 | [VariableDeclarator] count = Foo.#count | tst.ts:189:19:189:28 | [DotExpr] Foo.#count | semmle.order | 2 | +| tst.ts:189:19:189:28 | [DotExpr] Foo.#count | tst.ts:189:19:189:21 | [VarRef] Foo | semmle.label | 1 | +| tst.ts:189:19:189:28 | [DotExpr] Foo.#count | tst.ts:189:19:189:21 | [VarRef] Foo | semmle.order | 1 | +| tst.ts:189:19:189:28 | [DotExpr] Foo.#count | tst.ts:189:23:189:28 | [Label] #count | semmle.label | 2 | +| tst.ts:189:19:189:28 | [DotExpr] Foo.#count | tst.ts:189:23:189:28 | [Label] #count | semmle.order | 2 | | type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | type_alias.ts:1:6:1:6 | [Identifier] B | semmle.label | 1 | | type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | type_alias.ts:1:6:1:6 | [Identifier] B | semmle.order | 1 | | type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | type_alias.ts:1:10:1:16 | [KeywordTypeExpr] boolean | semmle.label | 2 | diff --git a/javascript/ql/test/library-tests/TypeScript/Types/tests.expected b/javascript/ql/test/library-tests/TypeScript/Types/tests.expected index 187c0c7e6ce..1d398443dec 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/tests.expected +++ b/javascript/ql/test/library-tests/TypeScript/Types/tests.expected @@ -175,6 +175,91 @@ getExprType | tst.ts:126:7:126:22 | this.#someMethod | () => number | | tst.ts:126:7:126:24 | this.#someMethod() | number | | tst.ts:127:14:127:28 | this.#someValue | number | +| tst.ts:132:8:132:11 | TS44 | typeof TS44 in library-tests/TypeScript/Types/tst.ts | +| tst.ts:133:12:133:14 | foo | (arg: unknown) => void | +| tst.ts:133:16:133:18 | arg | unknown | +| tst.ts:134:11:134:21 | argIsString | boolean | +| tst.ts:134:25:134:34 | typeof arg | "string" \| "number" \| "bigint" \| "boolean" \| "s... | +| tst.ts:134:25:134:47 | typeof ... string" | boolean | +| tst.ts:134:32:134:34 | arg | unknown | +| tst.ts:134:40:134:47 | "string" | "string" | +| tst.ts:135:9:135:19 | argIsString | boolean | +| tst.ts:136:15:136:19 | upper | string | +| tst.ts:136:23:136:25 | arg | string | +| tst.ts:136:23:136:37 | arg.toUpperCase | () => string | +| tst.ts:136:23:136:39 | arg.toUpperCase() | string | +| tst.ts:136:27:136:37 | toUpperCase | () => string | +| tst.ts:141:11:141:14 | kind | "circle" | +| tst.ts:141:27:141:32 | radius | number | +| tst.ts:142:11:142:14 | kind | "square" | +| tst.ts:142:27:142:36 | sideLength | number | +| tst.ts:144:12:144:15 | side | (shape: Shape) => number | +| tst.ts:144:17:144:21 | shape | Shape | +| tst.ts:145:15:145:18 | kind | "circle" \| "square" | +| tst.ts:145:15:145:18 | kind | "circle" \| "square" | +| tst.ts:145:24:145:28 | shape | Shape | +| tst.ts:147:11:147:14 | kind | "circle" \| "square" | +| tst.ts:147:11:147:27 | kind === "circle" | boolean | +| tst.ts:147:20:147:27 | "circle" | "circle" | +| tst.ts:147:39:147:43 | shape | { kind: "circle"; radius: number; } | +| tst.ts:147:39:147:50 | shape.radius | number | +| tst.ts:147:45:147:50 | radius | number | +| tst.ts:148:21:148:25 | shape | { kind: "square"; sideLength: number; } | +| tst.ts:148:21:148:36 | shape.sideLength | number | +| tst.ts:148:27:148:36 | sideLength | number | +| tst.ts:151:12:151:22 | symbolIndex | () => void | +| tst.ts:153:7:153:28 | [sym: s ... number; | any | +| tst.ts:153:8:153:10 | sym | symbol | +| tst.ts:154:7:154:28 | [key: s ... string; | any | +| tst.ts:154:8:154:10 | key | string | +| tst.ts:155:7:155:29 | [num: n ... oolean; | any | +| tst.ts:155:8:155:10 | num | number | +| tst.ts:158:9:158:14 | colors | Colors | +| tst.ts:158:26:158:27 | {} | Colors | +| tst.ts:159:11:159:13 | red | number | +| tst.ts:159:17:159:22 | colors | Colors | +| tst.ts:159:17:159:37 | colors[ ... "red")] | number | +| tst.ts:159:24:159:29 | Symbol | SymbolConstructor | +| tst.ts:159:24:159:36 | Symbol("red") | symbol | +| tst.ts:159:31:159:35 | "red" | "red" | +| tst.ts:160:11:160:15 | green | string | +| tst.ts:160:19:160:24 | colors | Colors | +| tst.ts:160:19:160:33 | colors["green"] | string | +| tst.ts:160:26:160:32 | "green" | "green" | +| tst.ts:161:11:161:14 | blue | boolean | +| tst.ts:161:18:161:23 | colors | Colors | +| tst.ts:161:18:161:26 | colors[2] | boolean | +| tst.ts:161:25:161:25 | 2 | 2 | +| tst.ts:164:12:164:29 | stringPatternIndex | () => void | +| tst.ts:166:7:166:37 | [key: ` ... number; | any | +| tst.ts:168:9:168:11 | bla | Foo | +| tst.ts:168:21:168:22 | {} | Foo | +| tst.ts:169:11:169:13 | bar | number | +| tst.ts:169:17:169:19 | bla | Foo | +| tst.ts:169:17:169:28 | bla[`foo-1`] | number | +| tst.ts:169:21:169:27 | `foo-1` | "foo-1" | +| tst.ts:169:21:169:27 | `foo-1` | "foo-1" | +| tst.ts:172:7:172:42 | [optNam ... oolean; | any | +| tst.ts:172:8:172:14 | optName | string \| symbol | +| tst.ts:175:11:175:14 | data | Data | +| tst.ts:175:24:175:25 | {} | Data | +| tst.ts:176:11:176:13 | baz | boolean | +| tst.ts:176:17:176:20 | data | Data | +| tst.ts:176:17:176:27 | data["foo"] | boolean | +| tst.ts:176:22:176:26 | "foo" | "foo" | +| tst.ts:179:9:179:11 | Foo | Foo | +| tst.ts:180:21:180:21 | 0 | 0 | +| tst.ts:182:5:184:5 | get cou ... ;\\n } | number | +| tst.ts:182:9:182:13 | count | number | +| tst.ts:183:16:183:18 | Foo | typeof Foo in tst.ts:132 | +| tst.ts:183:16:183:25 | Foo.#count | number | +| tst.ts:186:7:186:9 | Foo | typeof Foo in tst.ts:132 | +| tst.ts:186:7:186:16 | Foo.#count | number | +| tst.ts:186:7:186:21 | Foo.#count += 3 | number | +| tst.ts:186:21:186:21 | 3 | 3 | +| tst.ts:189:11:189:15 | count | number | +| tst.ts:189:19:189:21 | Foo | typeof Foo in tst.ts:132 | +| tst.ts:189:19:189:28 | Foo.#count | number | | type_alias.ts:3:5:3:5 | b | boolean | | type_alias.ts:7:5:7:5 | c | ValueOrArray | | type_alias.ts:14:9:14:32 | [proper ... ]: Json | any | @@ -233,6 +318,11 @@ getTypeDefinitionType | tst.ts:91:3:95:3 | class S ... }\\n } | Super | | tst.ts:97:3:101:3 | class S ... }\\n } | Sub | | tst.ts:116:3:129:3 | class F ... }\\n } | Foo | +| tst.ts:140:3:142:47 | type Sh ... mber }; | Shape | +| tst.ts:152:5:156:5 | interfa ... ;\\n } | Colors | +| tst.ts:165:5:167:5 | interfa ... ;\\n } | Foo | +| tst.ts:171:5:173:5 | interfa ... ;\\n } | Data | +| tst.ts:179:3:192:3 | class F ... \\n } | Foo | | type_alias.ts:1:1:1:17 | type B = boolean; | boolean | | type_alias.ts:5:1:5:50 | type Va ... ay>; | ValueOrArray | | type_alias.ts:9:1:15:13 | type Js ... Json[]; | Json | @@ -369,6 +459,36 @@ getTypeExprType | tst.ts:111:29:111:32 | -2-3 | any | | tst.ts:117:20:117:25 | number | number | | tst.ts:121:23:121:28 | number | number | +| tst.ts:133:21:133:27 | unknown | unknown | +| tst.ts:140:8:140:12 | Shape | Shape | +| tst.ts:141:7:142:46 | \| { kin ... umber } | { kind: "circle"; radius: number; } \| { kind: "... | +| tst.ts:141:9:141:42 | { kind: ... umber } | { kind: "circle"; radius: number; } | +| tst.ts:141:17:141:24 | "circle" | "circle" | +| tst.ts:141:35:141:40 | number | number | +| tst.ts:142:9:142:46 | { kind: ... umber } | { kind: "square"; sideLength: number; } | +| tst.ts:142:17:142:24 | "square" | "square" | +| tst.ts:142:39:142:44 | number | number | +| tst.ts:144:24:144:28 | Shape | Shape | +| tst.ts:144:32:144:37 | number | number | +| tst.ts:152:15:152:20 | Colors | Colors | +| tst.ts:153:13:153:18 | symbol | symbol | +| tst.ts:153:22:153:27 | number | number | +| tst.ts:154:13:154:18 | string | string | +| tst.ts:154:22:154:27 | string | string | +| tst.ts:155:13:155:18 | number | number | +| tst.ts:155:22:155:28 | boolean | boolean | +| tst.ts:158:17:158:22 | Colors | Colors | +| tst.ts:165:15:165:17 | Foo | Foo | +| tst.ts:166:14:166:17 | foo- | any | +| tst.ts:166:20:166:25 | number | number | +| tst.ts:166:31:166:36 | number | number | +| tst.ts:168:15:168:17 | Foo | Foo | +| tst.ts:171:15:171:18 | Data | Data | +| tst.ts:172:17:172:22 | string | string | +| tst.ts:172:17:172:31 | string \| symbol | string \| symbol | +| tst.ts:172:26:172:31 | symbol | symbol | +| tst.ts:172:35:172:41 | boolean | boolean | +| tst.ts:175:17:175:20 | Data | Data | | type_alias.ts:1:6:1:6 | B | boolean | | type_alias.ts:1:10:1:16 | boolean | boolean | | type_alias.ts:3:8:3:8 | B | boolean | @@ -439,9 +559,13 @@ referenceDefinition | Color.blue | type_definitions.ts:14:15:14:18 | blue | | Color.green | type_definitions.ts:14:8:14:12 | green | | Color.red | type_definitions.ts:14:3:14:5 | red | +| Colors | tst.ts:152:5:156:5 | interfa ... ;\\n } | +| Data | tst.ts:171:5:173:5 | interfa ... ;\\n } | | E | type_definition_objects.ts:6:8:6:16 | enum E {} | | EnumWithOneMember | type_definitions.ts:18:26:18:31 | member | | Foo | tst.ts:116:3:129:3 | class F ... }\\n } | +| Foo | tst.ts:165:5:167:5 | interfa ... ;\\n } | +| Foo | tst.ts:179:3:192:3 | class F ... \\n } | | HasArea | tst.ts:58:1:60:1 | interfa ... mber;\\n} | | I | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} | | I | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} | @@ -449,6 +573,7 @@ referenceDefinition | MyUnion | tst.ts:65:1:65:54 | type My ... true}; | | MyUnion2 | tst.ts:68:1:68:49 | type My ... true}; | | NonAbstractDummy | tst.ts:54:1:56:1 | interfa ... mber;\\n} | +| Shape | tst.ts:140:3:142:47 | type Sh ... mber }; | | Sub | tst.ts:97:3:101:3 | class S ... }\\n } | | Super | tst.ts:91:3:95:3 | class S ... }\\n } | | Super | tst.ts:91:3:95:3 | class S ... }\\n } | @@ -490,6 +615,8 @@ unknownType | tst.ts:40:5:40:15 | unknownType | unknown | | tst.ts:47:8:47:8 | e | unknown | | tst.ts:48:14:48:14 | e | unknown | +| tst.ts:133:16:133:18 | arg | unknown | +| tst.ts:134:32:134:34 | arg | unknown | abstractSignature | (): HasArea | | new (): HasArea | @@ -498,9 +625,11 @@ unionIndex | 2 | 1 | 1 \| 2 | | "bigint" | 2 | "string" \| "number" \| "bigint" \| "boolean" \| "s... | | "boolean" | 3 | "string" \| "number" \| "bigint" \| "boolean" \| "s... | +| "circle" | 0 | "circle" \| "square" | | "function" | 7 | "string" \| "number" \| "bigint" \| "boolean" \| "s... | | "number" | 1 | "string" \| "number" \| "bigint" \| "boolean" \| "s... | | "object" | 6 | "string" \| "number" \| "bigint" \| "boolean" \| "s... | +| "square" | 1 | "circle" \| "square" | | "string" | 0 | "string" \| "number" \| "bigint" \| "boolean" \| "s... | | "symbol" | 4 | "string" \| "number" \| "bigint" \| "boolean" \| "s... | | "undefined" | 5 | "string" \| "number" \| "bigint" \| "boolean" \| "s... | @@ -524,7 +653,9 @@ unionIndex | string | 0 | string \| number \| boolean | | string | 0 | string \| number \| boolean \| { [property: string... | | string | 0 | string \| number \| true | +| string | 0 | string \| symbol | | string | 0 | string \| { [key: string]: any; } | +| symbol | 1 | string \| symbol | | true | 1 | boolean | | true | 2 | string \| number \| true | | true | 3 | string \| number \| boolean | @@ -532,8 +663,13 @@ unionIndex | { [key: string]: any; } | 1 | string \| { [key: string]: any; } | | { [key: string]: any; } | 2 | VirtualNode \| { [key: string]: any; } | | { [property: string]: Json; } | 4 | string \| number \| boolean \| { [property: string... | +| { kind: "circle"; radius: number; } | 0 | { kind: "circle"; radius: number; } \| { kind: "... | +| { kind: "square"; sideLength: number; } | 1 | { kind: "circle"; radius: number; } \| { kind: "... | | { myUnion: true; } | 0 | MyUnion \| { yetAnotherType: true; } | | { myUnion: true; } | 0 | { myUnion: true; } \| { stillMyUnion: true; } | | { stillMyUnion: true; } | 1 | MyUnion \| { yetAnotherType: true; } | | { stillMyUnion: true; } | 1 | { myUnion: true; } \| { stillMyUnion: true; } | | { yetAnotherType: true; } | 2 | MyUnion \| { yetAnotherType: true; } | +getAStaticInitializerBlock +| tst.ts:179:3:192:3 | class F ... \\n } | tst.ts:185:5:187:5 | static ... ;\\n } | +| tst.ts:179:3:192:3 | class F ... \\n } | tst.ts:188:5:190:5 | static ... ;\\n } | diff --git a/javascript/ql/test/library-tests/TypeScript/Types/tests.ql b/javascript/ql/test/library-tests/TypeScript/Types/tests.ql index 0f31295ce50..dad3934113e 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/tests.ql +++ b/javascript/ql/test/library-tests/TypeScript/Types/tests.ql @@ -39,3 +39,7 @@ query predicate unknownType(Expr e, Type type) { query CallSignatureType abstractSignature() { result.isAbstract() } query UnionType unionIndex(Type element, int i) { result.getElementType(i) = element } + +query BlockStmt getAStaticInitializerBlock(ClassDefinition cls) { + result = cls.getAStaticInitializerBlock() +} diff --git a/javascript/ql/test/library-tests/TypeScript/Types/tst.ts b/javascript/ql/test/library-tests/TypeScript/Types/tst.ts index 389770984fd..0db050b2f49 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/tst.ts +++ b/javascript/ql/test/library-tests/TypeScript/Types/tst.ts @@ -127,4 +127,67 @@ module TS43 { return this.#someValue; } } +} + +module TS44 { + function foo(arg: unknown) { + const argIsString = typeof arg === "string"; + if (argIsString) { + const upper = arg.toUpperCase(); + } + } + + type Shape = + | { kind: "circle", radius: number } + | { kind: "square", sideLength: number }; + + function side(shape: Shape): number { + const { kind } = shape; + + if (kind === "circle") { return shape.radius;} + else { return shape.sideLength; } + } + + function symbolIndex() { + interface Colors { + [sym: symbol]: number; + [key: string]: string; + [num: number]: boolean; + } + + let colors: Colors = {}; + const red = colors[Symbol("red")]; + const green = colors["green"]; + const blue = colors[2]; + } + + function stringPatternIndex() { + interface Foo { + [key: `foo-${number}`]: number; + } + var bla : Foo = {}; + const bar = bla[`foo-1`]; + + interface Data { + [optName: string | symbol]: boolean; + } + + const data: Data = {}; + const baz = data["foo"]; + } + + class Foo { + static #count = 0; + + get count() { + return Foo.#count; + } + static { + Foo.#count += 3; + } + static { + var count = Foo.#count; + } + + } } \ No newline at end of file diff --git a/javascript/ql/test/library-tests/TypeTracking/ClassStyle.expected b/javascript/ql/test/library-tests/TypeTracking/ClassStyle.expected index 1a04300fc3d..cf561c366f2 100644 --- a/javascript/ql/test/library-tests/TypeTracking/ClassStyle.expected +++ b/javascript/ql/test/library-tests/TypeTracking/ClassStyle.expected @@ -38,6 +38,9 @@ test_Connection | tst.js:112:10:112:14 | obj.x | | tst.js:114:1:114:28 | getX({ ... on() }) | | tst.js:114:11:114:25 | getConnection() | +| tst.js:118:12:118:26 | getConnection() | +| tst.js:120:21:120:24 | conn | +| tst.js:126:22:126:25 | conn | | tst_conflict.js:6:38:6:77 | api.cha ... ction() | test_DataCallback | client.js:3:28:3:34 | x => {} | diff --git a/javascript/ql/test/library-tests/TypeTracking/PredicateStyle.expected b/javascript/ql/test/library-tests/TypeTracking/PredicateStyle.expected index 61d1675e794..5aef5c84540 100644 --- a/javascript/ql/test/library-tests/TypeTracking/PredicateStyle.expected +++ b/javascript/ql/test/library-tests/TypeTracking/PredicateStyle.expected @@ -40,6 +40,9 @@ connection | type tracker without call steps | tst.js:108:8:108:22 | getConnection() | | type tracker without call steps | tst.js:114:1:114:28 | getX({ ... on() }) | | type tracker without call steps | tst.js:114:11:114:25 | getConnection() | +| type tracker without call steps | tst.js:118:12:118:26 | getConnection() | +| type tracker without call steps | tst.js:120:21:120:24 | conn | +| type tracker without call steps | tst.js:126:22:126:25 | conn | | type tracker without call steps | tst_conflict.js:6:38:6:77 | api.cha ... ction() | | type tracker without call steps with property MyApplication.namespace.connection | file://:0:0:0:0 | global access path | | type tracker without call steps with property conflict | tst.js:63:3:63:25 | MyAppli ... mespace | diff --git a/javascript/ql/test/library-tests/TypeTracking/tst.js b/javascript/ql/test/library-tests/TypeTracking/tst.js index 38817dbb57e..cd11eaae8e7 100644 --- a/javascript/ql/test/library-tests/TypeTracking/tst.js +++ b/javascript/ql/test/library-tests/TypeTracking/tst.js @@ -113,3 +113,15 @@ function getX(obj) { } getX({ x: getConnection() }); getX({ x: somethingElse() }); + +function makeConnectionAsync(callback) { + callback(getConnection()); +} +makeConnectionAsync(conn => {}); +makeConnectionAsync(); // suppress single-call precision gains + +function makeConnectionAsync2(callback) { + makeConnectionAsync(callback); +} +makeConnectionAsync2(conn => {}); +makeConnectionAsync2(); // suppress single-call precision gains diff --git a/javascript/ql/test/library-tests/literals/test.expected b/javascript/ql/test/library-tests/literals/test.expected new file mode 100644 index 00000000000..1f592fc7d77 --- /dev/null +++ b/javascript/ql/test/library-tests/literals/test.expected @@ -0,0 +1 @@ +| test.js:1:9:1:16 | "\\ud800" | \ufffd | "\\ud800" | \ufffd | test.js:1:9:1:16 | "\\ud800" | diff --git a/javascript/ql/test/library-tests/literals/test.js b/javascript/ql/test/library-tests/literals/test.js new file mode 100644 index 00000000000..2ba36a76199 --- /dev/null +++ b/javascript/ql/test/library-tests/literals/test.js @@ -0,0 +1 @@ +let s = "\ud800"; diff --git a/javascript/ql/test/library-tests/literals/test.ql b/javascript/ql/test/library-tests/literals/test.ql new file mode 100644 index 00000000000..9b1a172d530 --- /dev/null +++ b/javascript/ql/test/library-tests/literals/test.ql @@ -0,0 +1,5 @@ +import javascript + +from StringLiteral sl +where sl.getFile().getBaseName() = "test.js" +select sl, sl.getValue(), sl.getRawValue(), sl.getStringValue(), sl.getUnderlyingValue() diff --git a/javascript/ql/test/query-tests/Expressions/SelfAssignment/template.njk b/javascript/ql/test/query-tests/Expressions/SelfAssignment/template.njk new file mode 100644 index 00000000000..8319bb1e414 --- /dev/null +++ b/javascript/ql/test/query-tests/Expressions/SelfAssignment/template.njk @@ -0,0 +1,3 @@ +
    + {{ foo(x=x) }} +
    diff --git a/javascript/ql/test/query-tests/Performance/ReDoS/tst.js b/javascript/ql/test/query-tests/Performance/ReDoS/tst.js index c3521343111..1ab557520cb 100644 --- a/javascript/ql/test/query-tests/Performance/ReDoS/tst.js +++ b/javascript/ql/test/query-tests/Performance/ReDoS/tst.js @@ -304,10 +304,10 @@ var bad66 = /^ab(c+)+$/; // NOT GOOD var bad67 = /(\d(\s+)*){20}/; -// GOOD - but we spuriously conclude that a rejecting suffix exists. +// GOOD - but we spuriously conclude that a rejecting suffix exists. var good36 = /(([^/]|X)+)(\/[^]*)*$/; -// GOOD - but we spuriously conclude that a rejecting suffix exists. +// GOOD - but we spuriously conclude that a rejecting suffix exists. var good37 = /^((x([^Y]+)?)*(Y|$))/; // NOT GOOD @@ -331,7 +331,7 @@ var bad72 = /(c?a?)*b/; // NOT GOOD var bad73 = /(?:a|a?)+b/; -// NOT GOOD - but not detected. +// NOT GOOD - but not detected. var bad74 = /(a?b?)*$/; // NOT GOOD @@ -357,13 +357,13 @@ var good40 = /(a|b)+/; var good41 = /(?:[\s;,"'<>(){}|[\]@=+*]|:(?![/\\]))+/; // NOT GOOD -var bad83 = /^((?:a{|-)|\w\{)+X$/; -var bad84 = /^((?:a{0|-)|\w\{\d)+X$/; -var bad85 = /^((?:a{0,|-)|\w\{\d,)+X$/; -var bad86 = /^((?:a{0,2|-)|\w\{\d,\d)+X$/; +var bad83 = /^((?:a{|-)|\w\{)+X$/; +var bad84 = /^((?:a{0|-)|\w\{\d)+X$/; +var bad85 = /^((?:a{0,|-)|\w\{\d,)+X$/; +var bad86 = /^((?:a{0,2|-)|\w\{\d,\d)+X$/; -// GOOD: -var good42 = /^((?:a{0,2}|-)|\w\{\d,\d\})+X$/; +// GOOD: +var good42 = /^((?:a{0,2}|-)|\w\{\d,\d\})+X$/; // GOOD var good43 = /("[^"]*?"|[^"\s]+)+(?=\s*|\s*$)/g; diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 199c3aacd3a..432aa42ab23 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -91,6 +91,20 @@ nodes | classnames.js:15:47:15:63 | clsx(window.name) | | classnames.js:15:52:15:62 | window.name | | classnames.js:15:52:15:62 | window.name | +| clipboard.ts:8:11:8:51 | html | +| clipboard.ts:8:18:8:51 | clipboa ... /html') | +| clipboard.ts:8:18:8:51 | clipboa ... /html') | +| clipboard.ts:15:25:15:28 | html | +| clipboard.ts:15:25:15:28 | html | +| clipboard.ts:24:23:24:58 | e.clipb ... /html') | +| clipboard.ts:24:23:24:58 | e.clipb ... /html') | +| clipboard.ts:24:23:24:58 | e.clipb ... /html') | +| clipboard.ts:29:19:29:54 | e.clipb ... /html') | +| clipboard.ts:29:19:29:54 | e.clipb ... /html') | +| clipboard.ts:29:19:29:54 | e.clipb ... /html') | +| clipboard.ts:33:19:33:68 | e.origi ... /html') | +| clipboard.ts:33:19:33:68 | e.origi ... /html') | +| clipboard.ts:33:19:33:68 | e.origi ... /html') | | d3.js:4:12:4:22 | window.name | | d3.js:4:12:4:22 | window.name | | d3.js:11:15:11:24 | getTaint() | @@ -857,6 +871,13 @@ edges | classnames.js:15:47:15:63 | clsx(window.name) | classnames.js:15:31:15:78 | `` | | classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) | | classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) | +| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | +| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | +| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html | +| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html | +| clipboard.ts:24:23:24:58 | e.clipb ... /html') | clipboard.ts:24:23:24:58 | e.clipb ... /html') | +| clipboard.ts:29:19:29:54 | e.clipb ... /html') | clipboard.ts:29:19:29:54 | e.clipb ... /html') | +| clipboard.ts:33:19:33:68 | e.origi ... /html') | clipboard.ts:33:19:33:68 | e.origi ... /html') | | d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | | d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | | d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | @@ -1514,6 +1535,10 @@ edges | classnames.js:11:31:11:79 | `` | classnames.js:10:45:10:55 | window.name | classnames.js:11:31:11:79 | `` | Cross-site scripting vulnerability due to $@. | classnames.js:10:45:10:55 | window.name | user-provided value | | classnames.js:13:31:13:83 | `` | classnames.js:13:57:13:67 | window.name | classnames.js:13:31:13:83 | `` | Cross-site scripting vulnerability due to $@. | classnames.js:13:57:13:67 | window.name | user-provided value | | classnames.js:15:31:15:78 | `` | classnames.js:15:52:15:62 | window.name | classnames.js:15:31:15:78 | `` | Cross-site scripting vulnerability due to $@. | classnames.js:15:52:15:62 | window.name | user-provided value | +| clipboard.ts:15:25:15:28 | html | clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:15:25:15:28 | html | Cross-site scripting vulnerability due to $@. | clipboard.ts:8:18:8:51 | clipboa ... /html') | user-provided value | +| clipboard.ts:24:23:24:58 | e.clipb ... /html') | clipboard.ts:24:23:24:58 | e.clipb ... /html') | clipboard.ts:24:23:24:58 | e.clipb ... /html') | Cross-site scripting vulnerability due to $@. | clipboard.ts:24:23:24:58 | e.clipb ... /html') | user-provided value | +| clipboard.ts:29:19:29:54 | e.clipb ... /html') | clipboard.ts:29:19:29:54 | e.clipb ... /html') | clipboard.ts:29:19:29:54 | e.clipb ... /html') | Cross-site scripting vulnerability due to $@. | clipboard.ts:29:19:29:54 | e.clipb ... /html') | user-provided value | +| clipboard.ts:33:19:33:68 | e.origi ... /html') | clipboard.ts:33:19:33:68 | e.origi ... /html') | clipboard.ts:33:19:33:68 | e.origi ... /html') | Cross-site scripting vulnerability due to $@. | clipboard.ts:33:19:33:68 | e.origi ... /html') | user-provided value | | d3.js:11:15:11:24 | getTaint() | d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | Cross-site scripting vulnerability due to $@. | d3.js:4:12:4:22 | window.name | user-provided value | | d3.js:12:20:12:29 | getTaint() | d3.js:4:12:4:22 | window.name | d3.js:12:20:12:29 | getTaint() | Cross-site scripting vulnerability due to $@. | d3.js:4:12:4:22 | window.name | user-provided value | | d3.js:14:20:14:29 | getTaint() | d3.js:4:12:4:22 | window.name | d3.js:14:20:14:29 | getTaint() | Cross-site scripting vulnerability due to $@. | d3.js:4:12:4:22 | window.name | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index b54e7a231ec..278f00ecebd 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -91,6 +91,20 @@ nodes | classnames.js:15:47:15:63 | clsx(window.name) | | classnames.js:15:52:15:62 | window.name | | classnames.js:15:52:15:62 | window.name | +| clipboard.ts:8:11:8:51 | html | +| clipboard.ts:8:18:8:51 | clipboa ... /html') | +| clipboard.ts:8:18:8:51 | clipboa ... /html') | +| clipboard.ts:15:25:15:28 | html | +| clipboard.ts:15:25:15:28 | html | +| clipboard.ts:24:23:24:58 | e.clipb ... /html') | +| clipboard.ts:24:23:24:58 | e.clipb ... /html') | +| clipboard.ts:24:23:24:58 | e.clipb ... /html') | +| clipboard.ts:29:19:29:54 | e.clipb ... /html') | +| clipboard.ts:29:19:29:54 | e.clipb ... /html') | +| clipboard.ts:29:19:29:54 | e.clipb ... /html') | +| clipboard.ts:33:19:33:68 | e.origi ... /html') | +| clipboard.ts:33:19:33:68 | e.origi ... /html') | +| clipboard.ts:33:19:33:68 | e.origi ... /html') | | d3.js:4:12:4:22 | window.name | | d3.js:4:12:4:22 | window.name | | d3.js:11:15:11:24 | getTaint() | @@ -875,6 +889,13 @@ edges | classnames.js:15:47:15:63 | clsx(window.name) | classnames.js:15:31:15:78 | `` | | classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) | | classnames.js:15:52:15:62 | window.name | classnames.js:15:47:15:63 | clsx(window.name) | +| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | +| clipboard.ts:8:11:8:51 | html | clipboard.ts:15:25:15:28 | html | +| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html | +| clipboard.ts:8:18:8:51 | clipboa ... /html') | clipboard.ts:8:11:8:51 | html | +| clipboard.ts:24:23:24:58 | e.clipb ... /html') | clipboard.ts:24:23:24:58 | e.clipb ... /html') | +| clipboard.ts:29:19:29:54 | e.clipb ... /html') | clipboard.ts:29:19:29:54 | e.clipb ... /html') | +| clipboard.ts:33:19:33:68 | e.origi ... /html') | clipboard.ts:33:19:33:68 | e.origi ... /html') | | d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | | d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | | d3.js:4:12:4:22 | window.name | d3.js:11:15:11:24 | getTaint() | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/clipboard.ts b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/clipboard.ts new file mode 100644 index 00000000000..93eab788d06 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/clipboard.ts @@ -0,0 +1,34 @@ +$("#foo").on("paste", paste); + +function paste(e) { + const { clipboardData } = e.originalEvent; + if (!clipboardData) return; + + const text = clipboardData.getData('text/plain'); + const html = clipboardData.getData('text/html'); + if (!text && !html) return; + + e.preventDefault(); + + const div = document.createElement('div'); + if (html) { + div.innerHTML = html; // NOT OK + } else { + div.textContent = text; + } + document.body.append(div); +} + +export function install(el: HTMLElement): void { + el.addEventListener('paste', (e) => { + $("#id").html(e.clipboardData.getData('text/html')); // NOT OK + }) +} + +document.addEventListener('paste', (e) => { + $("#id").html(e.clipboardData.getData('text/html')); // NOT OK +}); + +$("#foo").bind('paste', (e) => { + $("#id").html(e.originalEvent.clipboardData.getData('text/html')); // NOT OK +}); \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/XssThroughDom.expected b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/XssThroughDom.expected index 5d088481711..032446f4935 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/XssThroughDom.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/XssThroughDom.expected @@ -118,6 +118,10 @@ nodes | xss-through-dom.js:96:17:96:47 | $("#foo ... ].value | | xss-through-dom.js:96:17:96:47 | $("#foo ... ].value | | xss-through-dom.js:96:17:96:47 | $("#foo ... ].value | +| xss-through-dom.js:109:31:109:70 | "" | +| xss-through-dom.js:109:31:109:70 | "" | +| xss-through-dom.js:109:45:109:55 | this.el.src | +| xss-through-dom.js:109:45:109:55 | this.el.src | edges | forms.js:8:23:8:28 | values | forms.js:9:31:9:36 | values | | forms.js:8:23:8:28 | values | forms.js:9:31:9:36 | values | @@ -186,6 +190,10 @@ edges | xss-through-dom.js:87:36:87:39 | text | xss-through-dom.js:87:16:87:40 | new ans ... s(text) | | xss-through-dom.js:93:16:93:46 | $("#foo ... ].value | xss-through-dom.js:93:16:93:46 | $("#foo ... ].value | | xss-through-dom.js:96:17:96:47 | $("#foo ... ].value | xss-through-dom.js:96:17:96:47 | $("#foo ... ].value | +| xss-through-dom.js:109:45:109:55 | this.el.src | xss-through-dom.js:109:31:109:70 | "" | +| xss-through-dom.js:109:45:109:55 | this.el.src | xss-through-dom.js:109:31:109:70 | "" | +| xss-through-dom.js:109:45:109:55 | this.el.src | xss-through-dom.js:109:31:109:70 | "" | +| xss-through-dom.js:109:45:109:55 | this.el.src | xss-through-dom.js:109:31:109:70 | "" | #select | forms.js:9:31:9:40 | values.foo | forms.js:8:23:8:28 | values | forms.js:9:31:9:40 | values.foo | $@ is reinterpreted as HTML without escaping meta-characters. | forms.js:8:23:8:28 | values | DOM text | | forms.js:12:31:12:40 | values.bar | forms.js:11:24:11:29 | values | forms.js:12:31:12:40 | values.bar | $@ is reinterpreted as HTML without escaping meta-characters. | forms.js:11:24:11:29 | values | DOM text | @@ -219,3 +227,4 @@ edges | xss-through-dom.js:87:16:87:40 | new ans ... s(text) | xss-through-dom.js:84:15:84:30 | $("text").text() | xss-through-dom.js:87:16:87:40 | new ans ... s(text) | $@ is reinterpreted as HTML without escaping meta-characters. | xss-through-dom.js:84:15:84:30 | $("text").text() | DOM text | | xss-through-dom.js:93:16:93:46 | $("#foo ... ].value | xss-through-dom.js:93:16:93:46 | $("#foo ... ].value | xss-through-dom.js:93:16:93:46 | $("#foo ... ].value | $@ is reinterpreted as HTML without escaping meta-characters. | xss-through-dom.js:93:16:93:46 | $("#foo ... ].value | DOM text | | xss-through-dom.js:96:17:96:47 | $("#foo ... ].value | xss-through-dom.js:96:17:96:47 | $("#foo ... ].value | xss-through-dom.js:96:17:96:47 | $("#foo ... ].value | $@ is reinterpreted as HTML without escaping meta-characters. | xss-through-dom.js:96:17:96:47 | $("#foo ... ].value | DOM text | +| xss-through-dom.js:109:31:109:70 | "" | xss-through-dom.js:109:45:109:55 | this.el.src | xss-through-dom.js:109:31:109:70 | "" | $@ is reinterpreted as HTML without escaping meta-characters. | xss-through-dom.js:109:45:109:55 | this.el.src | DOM text | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/xss-through-dom.js b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/xss-through-dom.js index d7f6d6a8208..b6e23c11c02 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/xss-through-dom.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/xss-through-dom.js @@ -95,4 +95,17 @@ for (var i = 0; i < foo.length; i++) { $("#id").html($("#foo").find(".bla")[i].value); // NOT OK. } -})(); \ No newline at end of file +})(); + +class Super { + constructor() { + this.el = $("#id").get(0); + } +} + +class Sub extends Super { + constructor() { + super(); + $("#id").get(0).innerHTML = "foo"; // NOT OK. Attack: `` + } +} \ No newline at end of file diff --git a/javascript/upgrades/9ca3692b65fd8d751431861d1a25c57f3e61d15b/old.dbscheme b/javascript/upgrades/9ca3692b65fd8d751431861d1a25c57f3e61d15b/old.dbscheme new file mode 100644 index 00000000000..9ca3692b65f --- /dev/null +++ b/javascript/upgrades/9ca3692b65fd8d751431861d1a25c57f3e61d15b/old.dbscheme @@ -0,0 +1,1226 @@ +/*** Standard fragments ***/ + +/** Files and folders **/ + +@location = @location_default; + +locations_default(unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref + ); + +@sourceline = @locatable; + +numlines(int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref + ); + + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files(unique int id: @file, + varchar(900) name: string ref, + varchar(900) simple: string ref, + varchar(900) ext: string ref, + int fromSource: int ref); + +folders(unique int id: @folder, + varchar(900) name: string ref, + varchar(900) simple: string ref); + + +@container = @folder | @file ; + + +containerparent(int parent: @container ref, + unique int child: @container ref); + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + +/** Version control data **/ + +svnentries( + int id : @svnentry, + varchar(500) revision : string ref, + varchar(500) author : string ref, + date revisionDate : date ref, + int changeSize : int ref +); + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + varchar(500) action : string ref +); + +svnentrymsg( + int id : @svnentry ref, + varchar(500) message : string ref +); + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +); + + +/*** JavaScript-specific part ***/ + +filetype( + int file: @file ref, + string filetype: string ref +) + +// top-level code fragments +toplevels (unique int id: @toplevel, + int kind: int ref); + +is_externs (int toplevel: @toplevel ref); + +case @toplevel.kind of + 0 = @script +| 1 = @inline_script +| 2 = @event_handler +| 3 = @javascript_url +| 4 = @template_toplevel; + +is_module (int tl: @toplevel ref); +is_nodejs (int tl: @toplevel ref); +is_es2015_module (int tl: @toplevel ref); +is_closure_module (int tl: @toplevel ref); + +@xml_node_with_code = @xmlelement | @xmlattribute | @template_placeholder_tag; +toplevel_parent_xml_node( + unique int toplevel: @toplevel ref, + int xmlnode: @xml_node_with_code ref); + +xml_element_parent_expression( + unique int xmlnode: @xmlelement ref, + int expression: @expr ref, + int index: int ref); + +// statements +#keyset[parent, idx] +stmts (unique int id: @stmt, + int kind: int ref, + int parent: @stmt_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +stmt_containers (unique int stmt: @stmt ref, + int container: @stmt_container ref); + +jump_targets (unique int jump: @stmt ref, + int target: @stmt ref); + +@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr; +@stmt_container = @toplevel | @function | @namespace_declaration | @external_module_declaration | @global_augmentation_declaration; + +case @stmt.kind of + 0 = @empty_stmt +| 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @labeled_stmt +| 5 = @break_stmt +| 6 = @continue_stmt +| 7 = @with_stmt +| 8 = @switch_stmt +| 9 = @return_stmt +| 10 = @throw_stmt +| 11 = @try_stmt +| 12 = @while_stmt +| 13 = @do_while_stmt +| 14 = @for_stmt +| 15 = @for_in_stmt +| 16 = @debugger_stmt +| 17 = @function_decl_stmt +| 18 = @var_decl_stmt +| 19 = @case +| 20 = @catch_clause +| 21 = @for_of_stmt +| 22 = @const_decl_stmt +| 23 = @let_stmt +| 24 = @legacy_let_stmt +| 25 = @for_each_stmt +| 26 = @class_decl_stmt +| 27 = @import_declaration +| 28 = @export_all_declaration +| 29 = @export_default_declaration +| 30 = @export_named_declaration +| 31 = @namespace_declaration +| 32 = @import_equals_declaration +| 33 = @export_assign_declaration +| 34 = @interface_declaration +| 35 = @type_alias_declaration +| 36 = @enum_declaration +| 37 = @external_module_declaration +| 38 = @export_as_namespace_declaration +| 39 = @global_augmentation_declaration +; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt; + +@export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration; + +@namespace_definition = @namespace_declaration | @enum_declaration; +@type_definition = @class_definition | @interface_declaration | @enum_declaration | @type_alias_declaration | @enum_member; + +is_instantiated(unique int decl: @namespace_declaration ref); + +@declarable_node = @decl_stmt | @namespace_declaration | @class_decl_stmt | @function_decl_stmt | @enum_declaration | @external_module_declaration | @global_augmentation_declaration | @field; +has_declare_keyword(unique int stmt: @declarable_node ref); + +is_for_await_of(unique int forof: @for_of_stmt ref); + +// expressions +#keyset[parent, idx] +exprs (unique int id: @expr, + int kind: int ref, + int parent: @expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @expr_or_type ref); + +enclosing_stmt (unique int expr: @expr_or_type ref, + int stmt: @stmt ref); + +expr_containers (unique int expr: @expr_or_type ref, + int container: @stmt_container ref); + +array_size (unique int ae: @arraylike ref, + int sz: int ref); + +is_delegating (int yield: @yield_expr ref); + +@expr_or_stmt = @expr | @stmt; +@expr_or_type = @expr | @typeexpr; +@expr_parent = @expr_or_stmt | @property | @function_typeexpr; +@arraylike = @array_expr | @array_pattern; +@type_annotation = @typeexpr | @jsdoc_type_expr; +@node_in_stmt_container = @cfg_node | @type_annotation | @toplevel; + +case @expr.kind of + 0 = @label +| 1 = @null_literal +| 2 = @boolean_literal +| 3 = @number_literal +| 4 = @string_literal +| 5 = @regexp_literal +| 6 = @this_expr +| 7 = @array_expr +| 8 = @obj_expr +| 9 = @function_expr +| 10 = @seq_expr +| 11 = @conditional_expr +| 12 = @new_expr +| 13 = @call_expr +| 14 = @dot_expr +| 15 = @index_expr +| 16 = @neg_expr +| 17 = @plus_expr +| 18 = @log_not_expr +| 19 = @bit_not_expr +| 20 = @typeof_expr +| 21 = @void_expr +| 22 = @delete_expr +| 23 = @eq_expr +| 24 = @neq_expr +| 25 = @eqq_expr +| 26 = @neqq_expr +| 27 = @lt_expr +| 28 = @le_expr +| 29 = @gt_expr +| 30 = @ge_expr +| 31 = @lshift_expr +| 32 = @rshift_expr +| 33 = @urshift_expr +| 34 = @add_expr +| 35 = @sub_expr +| 36 = @mul_expr +| 37 = @div_expr +| 38 = @mod_expr +| 39 = @bitor_expr +| 40 = @xor_expr +| 41 = @bitand_expr +| 42 = @in_expr +| 43 = @instanceof_expr +| 44 = @logand_expr +| 45 = @logor_expr +| 47 = @assign_expr +| 48 = @assign_add_expr +| 49 = @assign_sub_expr +| 50 = @assign_mul_expr +| 51 = @assign_div_expr +| 52 = @assign_mod_expr +| 53 = @assign_lshift_expr +| 54 = @assign_rshift_expr +| 55 = @assign_urshift_expr +| 56 = @assign_or_expr +| 57 = @assign_xor_expr +| 58 = @assign_and_expr +| 59 = @preinc_expr +| 60 = @postinc_expr +| 61 = @predec_expr +| 62 = @postdec_expr +| 63 = @par_expr +| 64 = @var_declarator +| 65 = @arrow_function_expr +| 66 = @spread_element +| 67 = @array_pattern +| 68 = @object_pattern +| 69 = @yield_expr +| 70 = @tagged_template_expr +| 71 = @template_literal +| 72 = @template_element +| 73 = @array_comprehension_expr +| 74 = @generator_expr +| 75 = @for_in_comprehension_block +| 76 = @for_of_comprehension_block +| 77 = @legacy_letexpr +| 78 = @var_decl +| 79 = @proper_varaccess +| 80 = @class_expr +| 81 = @super_expr +| 82 = @newtarget_expr +| 83 = @named_import_specifier +| 84 = @import_default_specifier +| 85 = @import_namespace_specifier +| 86 = @named_export_specifier +| 87 = @exp_expr +| 88 = @assign_exp_expr +| 89 = @jsx_element +| 90 = @jsx_qualified_name +| 91 = @jsx_empty_expr +| 92 = @await_expr +| 93 = @function_sent_expr +| 94 = @decorator +| 95 = @export_default_specifier +| 96 = @export_namespace_specifier +| 97 = @bind_expr +| 98 = @external_module_reference +| 99 = @dynamic_import +| 100 = @expression_with_type_arguments +| 101 = @prefix_type_assertion +| 102 = @as_type_assertion +| 103 = @export_varaccess +| 104 = @decorator_list +| 105 = @non_null_assertion +| 106 = @bigint_literal +| 107 = @nullishcoalescing_expr +| 108 = @e4x_xml_anyname +| 109 = @e4x_xml_static_attribute_selector +| 110 = @e4x_xml_dynamic_attribute_selector +| 111 = @e4x_xml_filter_expression +| 112 = @e4x_xml_static_qualident +| 113 = @e4x_xml_dynamic_qualident +| 114 = @e4x_xml_dotdotexpr +| 115 = @import_meta_expr +| 116 = @assignlogandexpr +| 117 = @assignlogorexpr +| 118 = @assignnullishcoalescingexpr +| 119 = @template_pipe_ref +| 120 = @generated_code_expr +; + +@varaccess = @proper_varaccess | @export_varaccess; +@varref = @var_decl | @varaccess; + +@identifier = @label | @varref | @type_identifier; + +@literal = @null_literal | @boolean_literal | @number_literal | @string_literal | @regexp_literal | @bigint_literal; + +@propaccess = @dot_expr | @index_expr; + +@invokeexpr = @new_expr | @call_expr; + +@unaryexpr = @neg_expr | @plus_expr | @log_not_expr | @bit_not_expr | @typeof_expr | @void_expr | @delete_expr | @spread_element; + +@equality_test = @eq_expr | @neq_expr | @eqq_expr | @neqq_expr; + +@comparison = @equality_test | @lt_expr | @le_expr | @gt_expr | @ge_expr; + +@binaryexpr = @comparison | @lshift_expr | @rshift_expr | @urshift_expr | @add_expr | @sub_expr | @mul_expr | @div_expr | @mod_expr | @exp_expr | @bitor_expr | @xor_expr | @bitand_expr | @in_expr | @instanceof_expr | @logand_expr | @logor_expr | @nullishcoalescing_expr; + +@assignment = @assign_expr | @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr | @assign_mod_expr | @assign_exp_expr | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr | @assign_or_expr | @assign_xor_expr | @assign_and_expr | @assignlogandexpr | @assignlogorexpr | @assignnullishcoalescingexpr; + +@updateexpr = @preinc_expr | @postinc_expr | @predec_expr | @postdec_expr; + +@pattern = @varref | @array_pattern | @object_pattern; + +@comprehension_expr = @array_comprehension_expr | @generator_expr; + +@comprehension_block = @for_in_comprehension_block | @for_of_comprehension_block; + +@import_specifier = @named_import_specifier | @import_default_specifier | @import_namespace_specifier; + +@exportspecifier = @named_export_specifier | @export_default_specifier | @export_namespace_specifier; + +@import_or_export_declaration = @import_declaration | @export_declaration; + +@type_assertion = @as_type_assertion | @prefix_type_assertion; + +@class_definition = @class_decl_stmt | @class_expr; +@interface_definition = @interface_declaration | @interface_typeexpr; +@class_or_interface = @class_definition | @interface_definition; + +@lexical_decl = @var_decl | @type_decl; +@lexical_access = @varaccess | @local_type_access | @local_var_type_access | @local_namespace_access; +@lexical_ref = @lexical_decl | @lexical_access; + +@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector; +@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident; + +expr_contains_template_tag_location( + int expr: @expr ref, + int location: @location ref +); + +@template_placeholder_tag_parent = @xmlelement | @xmlattribute | @file; + +template_placeholder_tag_info( + unique int node: @template_placeholder_tag, + int parentNode: @template_placeholder_tag_parent ref, + varchar(900) raw: string ref +); + +// scopes +scopes (unique int id: @scope, + int kind: int ref); + +case @scope.kind of + 0 = @global_scope +| 1 = @function_scope +| 2 = @catch_scope +| 3 = @module_scope +| 4 = @block_scope +| 5 = @for_scope +| 6 = @for_in_scope // for-of scopes work the same as for-in scopes +| 7 = @comprehension_block_scope +| 8 = @class_expr_scope +| 9 = @namespace_scope +| 10 = @class_decl_scope +| 11 = @interface_scope +| 12 = @type_alias_scope +| 13 = @mapped_type_scope +| 14 = @enum_scope +| 15 = @external_module_scope +| 16 = @conditional_type_scope; + +scopenodes (unique int node: @ast_node ref, + int scope: @scope ref); + +scopenesting (unique int inner: @scope ref, + int outer: @scope ref); + +// functions +@function = @function_decl_stmt | @function_expr | @arrow_function_expr; + +@parameterized = @function | @catch_clause; +@type_parameterized = @function | @class_or_interface | @type_alias_declaration | @mapped_typeexpr | @infer_typeexpr; + +is_generator (int fun: @function ref); +has_rest_parameter (int fun: @function ref); +is_async (int fun: @function ref); + +// variables and lexically scoped type names +#keyset[scope, name] +variables (unique int id: @variable, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_type_names (unique int id: @local_type_name, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_namespace_names (unique int id: @local_namespace_name, + varchar(900) name: string ref, + int scope: @scope ref); + +is_arguments_object (int id: @variable ref); + +@lexical_name = @variable | @local_type_name | @local_namespace_name; + +@bind_id = @varaccess | @local_var_type_access; +bind (unique int id: @bind_id ref, + int decl: @variable ref); + +decl (unique int id: @var_decl ref, + int decl: @variable ref); + +@typebind_id = @local_type_access | @export_varaccess; +typebind (unique int id: @typebind_id ref, + int decl: @local_type_name ref); + +@typedecl_id = @type_decl | @var_decl; +typedecl (unique int id: @typedecl_id ref, + int decl: @local_type_name ref); + +namespacedecl (unique int id: @var_decl ref, + int decl: @local_namespace_name ref); + +@namespacebind_id = @local_namespace_access | @export_varaccess; +namespacebind (unique int id: @namespacebind_id ref, + int decl: @local_namespace_name ref); + + +// properties in object literals, property patterns in object patterns, and method declarations in classes +#keyset[parent, index] +properties (unique int id: @property, + int parent: @property_parent ref, + int index: int ref, + int kind: int ref, + varchar(900) tostring: string ref); + +case @property.kind of + 0 = @value_property +| 1 = @property_getter +| 2 = @property_setter +| 3 = @jsx_attribute +| 4 = @function_call_signature +| 5 = @constructor_call_signature +| 6 = @index_signature +| 7 = @enum_member +| 8 = @proper_field +| 9 = @parameter_field +; + +@property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration; +@property_accessor = @property_getter | @property_setter; +@call_signature = @function_call_signature | @constructor_call_signature; +@field = @proper_field | @parameter_field; +@field_or_vardeclarator = @field | @var_declarator; + +is_computed (int id: @property ref); +is_method (int id: @property ref); +is_static (int id: @property ref); +is_abstract_member (int id: @property ref); +is_const_enum (int id: @enum_declaration ref); +is_abstract_class (int id: @class_decl_stmt ref); + +has_public_keyword (int id: @property ref); +has_private_keyword (int id: @property ref); +has_protected_keyword (int id: @property ref); +has_readonly_keyword (int id: @property ref); +has_type_keyword (int id: @import_or_export_declaration ref); +is_optional_member (int id: @property ref); +has_definite_assignment_assertion (int id: @field_or_vardeclarator ref); +is_optional_parameter_declaration (unique int parameter: @pattern ref); + +#keyset[constructor, param_index] +parameter_fields( + unique int field: @parameter_field ref, + int constructor: @function_expr ref, + int param_index: int ref +); + +// types +#keyset[parent, idx] +typeexprs ( + unique int id: @typeexpr, + int kind: int ref, + int parent: @typeexpr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref +); + +case @typeexpr.kind of + 0 = @local_type_access +| 1 = @type_decl +| 2 = @keyword_typeexpr +| 3 = @string_literal_typeexpr +| 4 = @number_literal_typeexpr +| 5 = @boolean_literal_typeexpr +| 6 = @array_typeexpr +| 7 = @union_typeexpr +| 8 = @indexed_access_typeexpr +| 9 = @intersection_typeexpr +| 10 = @parenthesized_typeexpr +| 11 = @tuple_typeexpr +| 12 = @keyof_typeexpr +| 13 = @qualified_type_access +| 14 = @generic_typeexpr +| 15 = @type_label +| 16 = @typeof_typeexpr +| 17 = @local_var_type_access +| 18 = @qualified_var_type_access +| 19 = @this_var_type_access +| 20 = @predicate_typeexpr +| 21 = @interface_typeexpr +| 22 = @type_parameter +| 23 = @plain_function_typeexpr +| 24 = @constructor_typeexpr +| 25 = @local_namespace_access +| 26 = @qualified_namespace_access +| 27 = @mapped_typeexpr +| 28 = @conditional_typeexpr +| 29 = @infer_typeexpr +| 30 = @import_type_access +| 31 = @import_namespace_access +| 32 = @import_var_type_access +| 33 = @optional_typeexpr +| 34 = @rest_typeexpr +| 35 = @bigint_literal_typeexpr +| 36 = @readonly_typeexpr +| 37 = @template_literal_typeexpr +; + +@typeref = @typeaccess | @type_decl; +@type_identifier = @type_decl | @local_type_access | @type_label | @local_var_type_access | @local_namespace_access; +@typeexpr_parent = @expr | @stmt | @property | @typeexpr; +@literal_typeexpr = @string_literal_typeexpr | @number_literal_typeexpr | @boolean_literal_typeexpr | @bigint_literal_typeexpr; +@typeaccess = @local_type_access | @qualified_type_access | @import_type_access; +@vartypeaccess = @local_var_type_access | @qualified_var_type_access | @this_var_type_access | @import_var_type_access; +@namespace_access = @local_namespace_access | @qualified_namespace_access | @import_namespace_access; +@import_typeexpr = @import_type_access | @import_namespace_access | @import_var_type_access; + +@function_typeexpr = @plain_function_typeexpr | @constructor_typeexpr; + +// types +types ( + unique int id: @type, + int kind: int ref, + varchar(900) tostring: string ref +); + +#keyset[parent, idx] +type_child ( + int child: @type ref, + int parent: @type ref, + int idx: int ref +); + +case @type.kind of + 0 = @any_type +| 1 = @string_type +| 2 = @number_type +| 3 = @union_type +| 4 = @true_type +| 5 = @false_type +| 6 = @type_reference +| 7 = @object_type +| 8 = @canonical_type_variable_type +| 9 = @typeof_type +| 10 = @void_type +| 11 = @undefined_type +| 12 = @null_type +| 13 = @never_type +| 14 = @plain_symbol_type +| 15 = @unique_symbol_type +| 16 = @objectkeyword_type +| 17 = @intersection_type +| 18 = @tuple_type +| 19 = @lexical_type_variable_type +| 20 = @this_type +| 21 = @number_literal_type +| 22 = @string_literal_type +| 23 = @unknown_type +| 24 = @bigint_type +| 25 = @bigint_literal_type +; + +@boolean_literal_type = @true_type | @false_type; +@symbol_type = @plain_symbol_type | @unique_symbol_type; +@union_or_intersection_type = @union_type | @intersection_type; +@typevariable_type = @canonical_type_variable_type | @lexical_type_variable_type; + +has_asserts_keyword(int node: @predicate_typeexpr ref); + +@typed_ast_node = @expr | @typeexpr | @function; +ast_node_type( + unique int node: @typed_ast_node ref, + int typ: @type ref); + +declared_function_signature( + unique int node: @function ref, + int sig: @signature_type ref +); + +invoke_expr_signature( + unique int node: @invokeexpr ref, + int sig: @signature_type ref +); + +invoke_expr_overload_index( + unique int node: @invokeexpr ref, + int index: int ref +); + +symbols ( + unique int id: @symbol, + int kind: int ref, + varchar(900) name: string ref +); + +symbol_parent ( + unique int symbol: @symbol ref, + int parent: @symbol ref +); + +symbol_module ( + int symbol: @symbol ref, + varchar(900) moduleName: string ref +); + +symbol_global ( + int symbol: @symbol ref, + varchar(900) globalName: string ref +); + +case @symbol.kind of + 0 = @root_symbol +| 1 = @member_symbol +| 2 = @other_symbol +; + +@type_with_symbol = @type_reference | @typevariable_type | @typeof_type | @unique_symbol_type; +@ast_node_with_symbol = @type_definition | @namespace_definition | @toplevel | @typeaccess | @namespace_access | @var_decl | @function | @invokeexpr | @import_declaration | @external_module_reference; + +ast_node_symbol( + unique int node: @ast_node_with_symbol ref, + int symbol: @symbol ref); + +type_symbol( + unique int typ: @type_with_symbol ref, + int symbol: @symbol ref); + +#keyset[typ, name] +type_property( + int typ: @type ref, + varchar(900) name: string ref, + int propertyType: @type ref); + +type_alias( + unique int aliasType: @type ref, + int underlyingType: @type ref); + +@literal_type = @string_literal_type | @number_literal_type | @boolean_literal_type | @bigint_literal_type; +@type_with_literal_value = @string_literal_type | @number_literal_type | @bigint_literal_type; +type_literal_value( + unique int typ: @type_with_literal_value ref, + varchar(900) value: string ref); + +signature_types ( + unique int id: @signature_type, + int kind: int ref, + varchar(900) tostring: string ref, + int type_parameters: int ref, + int required_params: int ref +); + +is_abstract_signature( + unique int sig: @signature_type ref +); + +signature_rest_parameter( + unique int sig: @signature_type ref, + int rest_param_arra_type: @type ref +); + +case @signature_type.kind of + 0 = @function_signature_type +| 1 = @constructor_signature_type +; + +#keyset[typ, kind, index] +type_contains_signature ( + int typ: @type ref, + int kind: int ref, // constructor/call/index + int index: int ref, // ordering of overloaded signatures + int sig: @signature_type ref +); + +#keyset[parent, index] +signature_contains_type ( + int child: @type ref, + int parent: @signature_type ref, + int index: int ref +); + +#keyset[sig, index] +signature_parameter_name ( + int sig: @signature_type ref, + int index: int ref, + varchar(900) name: string ref +); + +number_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +string_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +base_type_names( + int typeName: @symbol ref, + int baseTypeName: @symbol ref +); + +self_types( + int typeName: @symbol ref, + int selfType: @type_reference ref +); + +tuple_type_min_length( + unique int typ: @type ref, + int minLength: int ref +); + +tuple_type_rest_index( + unique int typ: @type ref, + int index: int ref +); + +// comments +comments (unique int id: @comment, + int kind: int ref, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(900) tostring: string ref); + +case @comment.kind of + 0 = @slashslash_comment +| 1 = @slashstar_comment +| 2 = @doc_comment +| 3 = @html_comment_start +| 4 = @htmlcommentend; + +@html_comment = @html_comment_start | @htmlcommentend; +@line_comment = @slashslash_comment | @html_comment; +@block_comment = @slashstar_comment | @doc_comment; + +// source lines +lines (unique int id: @line, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(2) terminator: string ref); +indentation (int file: @file ref, + int lineno: int ref, + varchar(1) indentChar: string ref, + int indentDepth: int ref); + +// JavaScript parse errors +js_parse_errors (unique int id: @js_parse_error, + int toplevel: @toplevel ref, + varchar(900) message: string ref, + varchar(900) line: string ref); + +// regular expressions +#keyset[parent, idx] +regexpterm (unique int id: @regexpterm, + int kind: int ref, + int parent: @regexpparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +@regexpparent = @regexpterm | @regexp_literal | @string_literal; + +case @regexpterm.kind of + 0 = @regexp_alt +| 1 = @regexp_seq +| 2 = @regexp_caret +| 3 = @regexp_dollar +| 4 = @regexp_wordboundary +| 5 = @regexp_nonwordboundary +| 6 = @regexp_positive_lookahead +| 7 = @regexp_negative_lookahead +| 8 = @regexp_star +| 9 = @regexp_plus +| 10 = @regexp_opt +| 11 = @regexp_range +| 12 = @regexp_dot +| 13 = @regexp_group +| 14 = @regexp_normal_constant +| 15 = @regexp_hex_escape +| 16 = @regexp_unicode_escape +| 17 = @regexp_dec_escape +| 18 = @regexp_oct_escape +| 19 = @regexp_ctrl_escape +| 20 = @regexp_char_class_escape +| 21 = @regexp_id_escape +| 22 = @regexp_backref +| 23 = @regexp_char_class +| 24 = @regexp_char_range +| 25 = @regexp_positive_lookbehind +| 26 = @regexp_negative_lookbehind +| 27 = @regexp_unicode_property_escape; + +regexp_parse_errors (unique int id: @regexp_parse_error, + int regexp: @regexpterm ref, + varchar(900) message: string ref); + +@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range; +@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape; +@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape; +@regexp_constant = @regexp_normal_constant | @regexp_char_escape; +@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead; +@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind; +@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind; +@regexp_anchor = @regexp_dollar | @regexp_caret; + +is_greedy (int id: @regexp_quantifier ref); +range_quantifier_lower_bound (unique int id: @regexp_range ref, int lo: int ref); +range_quantifier_upper_bound (unique int id: @regexp_range ref, int hi: int ref); +is_capture (unique int id: @regexp_group ref, int number: int ref); +is_named_capture (unique int id: @regexp_group ref, string name: string ref); +is_inverted (int id: @regexp_char_class ref); +regexp_const_value (unique int id: @regexp_constant ref, varchar(1) value: string ref); +char_class_escape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref); +backref (unique int id: @regexp_backref ref, int value: int ref); +named_backref (unique int id: @regexp_backref ref, string name: string ref); +unicode_property_escapename (unique int id: @regexp_unicode_property_escape ref, string name: string ref); +unicode_property_escapevalue (unique int id: @regexp_unicode_property_escape ref, string value: string ref); + +// tokens +#keyset[toplevel, idx] +tokeninfo (unique int id: @token, + int kind: int ref, + int toplevel: @toplevel ref, + int idx: int ref, + varchar(900) value: string ref); + +case @token.kind of + 0 = @token_eof +| 1 = @token_null_literal +| 2 = @token_boolean_literal +| 3 = @token_numeric_literal +| 4 = @token_string_literal +| 5 = @token_regular_expression +| 6 = @token_identifier +| 7 = @token_keyword +| 8 = @token_punctuator; + +// associate comments with the token immediately following them (which may be EOF) +next_token (int comment: @comment ref, int token: @token ref); + +// JSON +#keyset[parent, idx] +json (unique int id: @json_value, + int kind: int ref, + int parent: @json_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +json_literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @json_value ref); + +json_properties (int obj: @json_object ref, + varchar(900) property: string ref, + int value: @json_value ref); + +json_errors (unique int id: @json_parse_error, + varchar(900) message: string ref); + +json_locations(unique int locatable: @json_locatable ref, + int location: @location_default ref); + +case @json_value.kind of + 0 = @json_null +| 1 = @json_boolean +| 2 = @json_number +| 3 = @json_string +| 4 = @json_array +| 5 = @json_object; + +@json_parent = @json_object | @json_array | @file; + +@json_locatable = @json_value | @json_parse_error; + +// locations +@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr; + +@locatable = @file + | @ast_node + | @comment + | @line + | @js_parse_error | @regexp_parse_error + | @regexpterm + | @json_locatable + | @token + | @cfg_node + | @jsdoc | @jsdoc_type_expr | @jsdoc_tag + | @yaml_locatable + | @xmllocatable + | @configLocatable + | @template_placeholder_tag; + +hasLocation (unique int locatable: @locatable ref, + int location: @location ref); + +// CFG +entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref); +exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref); +guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref); +case @guard_node.kind of + 0 = @falsy_guard +| 1 = @truthy_guard; +@condition_guard = @falsy_guard | @truthy_guard; + +@synthetic_cfg_node = @entry_node | @exit_node | @guard_node; +@cfg_node = @synthetic_cfg_node | @expr_parent; + +successor (int pred: @cfg_node ref, int succ: @cfg_node ref); + +// JSDoc comments +jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref); +#keyset[parent, idx] +jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref, + int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref); +jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); +jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); + +#keyset[parent, idx] +jsdoc_type_exprs (unique int id: @jsdoc_type_expr, + int kind: int ref, + int parent: @jsdoc_type_expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); +case @jsdoc_type_expr.kind of + 0 = @jsdoc_any_type_expr +| 1 = @jsdoc_null_type_expr +| 2 = @jsdoc_undefined_type_expr +| 3 = @jsdoc_unknown_type_expr +| 4 = @jsdoc_void_type_expr +| 5 = @jsdoc_named_type_expr +| 6 = @jsdoc_applied_type_expr +| 7 = @jsdoc_nullable_type_expr +| 8 = @jsdoc_non_nullable_type_expr +| 9 = @jsdoc_record_type_expr +| 10 = @jsdoc_array_type_expr +| 11 = @jsdoc_union_type_expr +| 12 = @jsdoc_function_type_expr +| 13 = @jsdoc_optional_type_expr +| 14 = @jsdoc_rest_type_expr +; + +#keyset[id, idx] +jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref); +jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref); +jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref); + +@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag; + +jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref); + +// YAML +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + varchar(900) tag: string ref, + varchar(900) tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + varchar(900) anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + varchar(900) target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + varchar(900) value: string ref); + +yaml_errors (unique int id: @yaml_error, + varchar(900) message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/* XML Files */ + +xmlEncoding( + unique int id: @file ref, + varchar(900) encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + varchar(900) root: string ref, + varchar(900) publicId: string ref, + varchar(900) systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + varchar(900) name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + varchar(900) name: string ref, + varchar(3600) value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + varchar(900) prefixName: string ref, + varchar(900) URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property; + +@optionalchainable = @call_expr | @propaccess; + +isOptionalChaining(int id: @optionalchainable ref); + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +/** + * The time taken for the extraction of a file. + * This table contains non-deterministic content. + * + * The sum of the `time` column for each (`file`, `timerKind`) pair + * is the total time taken for extraction of `file`. The `extractionPhase` + * column provides a granular view of the extraction time of the file. + */ +extraction_time( + int file : @file ref, + // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`. + int extractionPhase: int ref, + // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds + int timerKind: int ref, + float time: float ref +) + +/** + * Non-timing related data for the extraction of a single file. + * This table contains non-deterministic content. + */ +extraction_data( + int file : @file ref, + // the absolute path to the cache file + varchar(900) cacheFile: string ref, + boolean fromCache: boolean ref, + int length: int ref +) diff --git a/javascript/upgrades/9ca3692b65fd8d751431861d1a25c57f3e61d15b/semmlecode.javascript.dbscheme b/javascript/upgrades/9ca3692b65fd8d751431861d1a25c57f3e61d15b/semmlecode.javascript.dbscheme new file mode 100644 index 00000000000..e34b3e16dba --- /dev/null +++ b/javascript/upgrades/9ca3692b65fd8d751431861d1a25c57f3e61d15b/semmlecode.javascript.dbscheme @@ -0,0 +1,1216 @@ +/*** Standard fragments ***/ + +/** Files and folders **/ + +@location = @location_default; + +locations_default(unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref + ); + +@sourceline = @locatable; + +numlines(int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref + ); + +files(unique int id: @file, + varchar(900) name: string ref); + +folders(unique int id: @folder, + varchar(900) name: string ref); + + +@container = @folder | @file ; + + +containerparent(int parent: @container ref, + unique int child: @container ref); + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + +/** Version control data **/ + +svnentries( + int id : @svnentry, + varchar(500) revision : string ref, + varchar(500) author : string ref, + date revisionDate : date ref, + int changeSize : int ref +); + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + varchar(500) action : string ref +); + +svnentrymsg( + int id : @svnentry ref, + varchar(500) message : string ref +); + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +); + + +/*** JavaScript-specific part ***/ + +filetype( + int file: @file ref, + string filetype: string ref +) + +// top-level code fragments +toplevels (unique int id: @toplevel, + int kind: int ref); + +is_externs (int toplevel: @toplevel ref); + +case @toplevel.kind of + 0 = @script +| 1 = @inline_script +| 2 = @event_handler +| 3 = @javascript_url +| 4 = @template_toplevel; + +is_module (int tl: @toplevel ref); +is_nodejs (int tl: @toplevel ref); +is_es2015_module (int tl: @toplevel ref); +is_closure_module (int tl: @toplevel ref); + +@xml_node_with_code = @xmlelement | @xmlattribute | @template_placeholder_tag; +toplevel_parent_xml_node( + unique int toplevel: @toplevel ref, + int xmlnode: @xml_node_with_code ref); + +xml_element_parent_expression( + unique int xmlnode: @xmlelement ref, + int expression: @expr ref, + int index: int ref); + +// statements +#keyset[parent, idx] +stmts (unique int id: @stmt, + int kind: int ref, + int parent: @stmt_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +stmt_containers (unique int stmt: @stmt ref, + int container: @stmt_container ref); + +jump_targets (unique int jump: @stmt ref, + int target: @stmt ref); + +@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr; +@stmt_container = @toplevel | @function | @namespace_declaration | @external_module_declaration | @global_augmentation_declaration; + +case @stmt.kind of + 0 = @empty_stmt +| 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @labeled_stmt +| 5 = @break_stmt +| 6 = @continue_stmt +| 7 = @with_stmt +| 8 = @switch_stmt +| 9 = @return_stmt +| 10 = @throw_stmt +| 11 = @try_stmt +| 12 = @while_stmt +| 13 = @do_while_stmt +| 14 = @for_stmt +| 15 = @for_in_stmt +| 16 = @debugger_stmt +| 17 = @function_decl_stmt +| 18 = @var_decl_stmt +| 19 = @case +| 20 = @catch_clause +| 21 = @for_of_stmt +| 22 = @const_decl_stmt +| 23 = @let_stmt +| 24 = @legacy_let_stmt +| 25 = @for_each_stmt +| 26 = @class_decl_stmt +| 27 = @import_declaration +| 28 = @export_all_declaration +| 29 = @export_default_declaration +| 30 = @export_named_declaration +| 31 = @namespace_declaration +| 32 = @import_equals_declaration +| 33 = @export_assign_declaration +| 34 = @interface_declaration +| 35 = @type_alias_declaration +| 36 = @enum_declaration +| 37 = @external_module_declaration +| 38 = @export_as_namespace_declaration +| 39 = @global_augmentation_declaration +; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt; + +@export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration; + +@namespace_definition = @namespace_declaration | @enum_declaration; +@type_definition = @class_definition | @interface_declaration | @enum_declaration | @type_alias_declaration | @enum_member; + +is_instantiated(unique int decl: @namespace_declaration ref); + +@declarable_node = @decl_stmt | @namespace_declaration | @class_decl_stmt | @function_decl_stmt | @enum_declaration | @external_module_declaration | @global_augmentation_declaration | @field; +has_declare_keyword(unique int stmt: @declarable_node ref); + +is_for_await_of(unique int forof: @for_of_stmt ref); + +// expressions +#keyset[parent, idx] +exprs (unique int id: @expr, + int kind: int ref, + int parent: @expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @expr_or_type ref); + +enclosing_stmt (unique int expr: @expr_or_type ref, + int stmt: @stmt ref); + +expr_containers (unique int expr: @expr_or_type ref, + int container: @stmt_container ref); + +array_size (unique int ae: @arraylike ref, + int sz: int ref); + +is_delegating (int yield: @yield_expr ref); + +@expr_or_stmt = @expr | @stmt; +@expr_or_type = @expr | @typeexpr; +@expr_parent = @expr_or_stmt | @property | @function_typeexpr; +@arraylike = @array_expr | @array_pattern; +@type_annotation = @typeexpr | @jsdoc_type_expr; +@node_in_stmt_container = @cfg_node | @type_annotation | @toplevel; + +case @expr.kind of + 0 = @label +| 1 = @null_literal +| 2 = @boolean_literal +| 3 = @number_literal +| 4 = @string_literal +| 5 = @regexp_literal +| 6 = @this_expr +| 7 = @array_expr +| 8 = @obj_expr +| 9 = @function_expr +| 10 = @seq_expr +| 11 = @conditional_expr +| 12 = @new_expr +| 13 = @call_expr +| 14 = @dot_expr +| 15 = @index_expr +| 16 = @neg_expr +| 17 = @plus_expr +| 18 = @log_not_expr +| 19 = @bit_not_expr +| 20 = @typeof_expr +| 21 = @void_expr +| 22 = @delete_expr +| 23 = @eq_expr +| 24 = @neq_expr +| 25 = @eqq_expr +| 26 = @neqq_expr +| 27 = @lt_expr +| 28 = @le_expr +| 29 = @gt_expr +| 30 = @ge_expr +| 31 = @lshift_expr +| 32 = @rshift_expr +| 33 = @urshift_expr +| 34 = @add_expr +| 35 = @sub_expr +| 36 = @mul_expr +| 37 = @div_expr +| 38 = @mod_expr +| 39 = @bitor_expr +| 40 = @xor_expr +| 41 = @bitand_expr +| 42 = @in_expr +| 43 = @instanceof_expr +| 44 = @logand_expr +| 45 = @logor_expr +| 47 = @assign_expr +| 48 = @assign_add_expr +| 49 = @assign_sub_expr +| 50 = @assign_mul_expr +| 51 = @assign_div_expr +| 52 = @assign_mod_expr +| 53 = @assign_lshift_expr +| 54 = @assign_rshift_expr +| 55 = @assign_urshift_expr +| 56 = @assign_or_expr +| 57 = @assign_xor_expr +| 58 = @assign_and_expr +| 59 = @preinc_expr +| 60 = @postinc_expr +| 61 = @predec_expr +| 62 = @postdec_expr +| 63 = @par_expr +| 64 = @var_declarator +| 65 = @arrow_function_expr +| 66 = @spread_element +| 67 = @array_pattern +| 68 = @object_pattern +| 69 = @yield_expr +| 70 = @tagged_template_expr +| 71 = @template_literal +| 72 = @template_element +| 73 = @array_comprehension_expr +| 74 = @generator_expr +| 75 = @for_in_comprehension_block +| 76 = @for_of_comprehension_block +| 77 = @legacy_letexpr +| 78 = @var_decl +| 79 = @proper_varaccess +| 80 = @class_expr +| 81 = @super_expr +| 82 = @newtarget_expr +| 83 = @named_import_specifier +| 84 = @import_default_specifier +| 85 = @import_namespace_specifier +| 86 = @named_export_specifier +| 87 = @exp_expr +| 88 = @assign_exp_expr +| 89 = @jsx_element +| 90 = @jsx_qualified_name +| 91 = @jsx_empty_expr +| 92 = @await_expr +| 93 = @function_sent_expr +| 94 = @decorator +| 95 = @export_default_specifier +| 96 = @export_namespace_specifier +| 97 = @bind_expr +| 98 = @external_module_reference +| 99 = @dynamic_import +| 100 = @expression_with_type_arguments +| 101 = @prefix_type_assertion +| 102 = @as_type_assertion +| 103 = @export_varaccess +| 104 = @decorator_list +| 105 = @non_null_assertion +| 106 = @bigint_literal +| 107 = @nullishcoalescing_expr +| 108 = @e4x_xml_anyname +| 109 = @e4x_xml_static_attribute_selector +| 110 = @e4x_xml_dynamic_attribute_selector +| 111 = @e4x_xml_filter_expression +| 112 = @e4x_xml_static_qualident +| 113 = @e4x_xml_dynamic_qualident +| 114 = @e4x_xml_dotdotexpr +| 115 = @import_meta_expr +| 116 = @assignlogandexpr +| 117 = @assignlogorexpr +| 118 = @assignnullishcoalescingexpr +| 119 = @template_pipe_ref +| 120 = @generated_code_expr +; + +@varaccess = @proper_varaccess | @export_varaccess; +@varref = @var_decl | @varaccess; + +@identifier = @label | @varref | @type_identifier; + +@literal = @null_literal | @boolean_literal | @number_literal | @string_literal | @regexp_literal | @bigint_literal; + +@propaccess = @dot_expr | @index_expr; + +@invokeexpr = @new_expr | @call_expr; + +@unaryexpr = @neg_expr | @plus_expr | @log_not_expr | @bit_not_expr | @typeof_expr | @void_expr | @delete_expr | @spread_element; + +@equality_test = @eq_expr | @neq_expr | @eqq_expr | @neqq_expr; + +@comparison = @equality_test | @lt_expr | @le_expr | @gt_expr | @ge_expr; + +@binaryexpr = @comparison | @lshift_expr | @rshift_expr | @urshift_expr | @add_expr | @sub_expr | @mul_expr | @div_expr | @mod_expr | @exp_expr | @bitor_expr | @xor_expr | @bitand_expr | @in_expr | @instanceof_expr | @logand_expr | @logor_expr | @nullishcoalescing_expr; + +@assignment = @assign_expr | @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr | @assign_mod_expr | @assign_exp_expr | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr | @assign_or_expr | @assign_xor_expr | @assign_and_expr | @assignlogandexpr | @assignlogorexpr | @assignnullishcoalescingexpr; + +@updateexpr = @preinc_expr | @postinc_expr | @predec_expr | @postdec_expr; + +@pattern = @varref | @array_pattern | @object_pattern; + +@comprehension_expr = @array_comprehension_expr | @generator_expr; + +@comprehension_block = @for_in_comprehension_block | @for_of_comprehension_block; + +@import_specifier = @named_import_specifier | @import_default_specifier | @import_namespace_specifier; + +@exportspecifier = @named_export_specifier | @export_default_specifier | @export_namespace_specifier; + +@import_or_export_declaration = @import_declaration | @export_declaration; + +@type_assertion = @as_type_assertion | @prefix_type_assertion; + +@class_definition = @class_decl_stmt | @class_expr; +@interface_definition = @interface_declaration | @interface_typeexpr; +@class_or_interface = @class_definition | @interface_definition; + +@lexical_decl = @var_decl | @type_decl; +@lexical_access = @varaccess | @local_type_access | @local_var_type_access | @local_namespace_access; +@lexical_ref = @lexical_decl | @lexical_access; + +@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector; +@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident; + +expr_contains_template_tag_location( + int expr: @expr ref, + int location: @location ref +); + +@template_placeholder_tag_parent = @xmlelement | @xmlattribute | @file; + +template_placeholder_tag_info( + unique int node: @template_placeholder_tag, + int parentNode: @template_placeholder_tag_parent ref, + varchar(900) raw: string ref +); + +// scopes +scopes (unique int id: @scope, + int kind: int ref); + +case @scope.kind of + 0 = @global_scope +| 1 = @function_scope +| 2 = @catch_scope +| 3 = @module_scope +| 4 = @block_scope +| 5 = @for_scope +| 6 = @for_in_scope // for-of scopes work the same as for-in scopes +| 7 = @comprehension_block_scope +| 8 = @class_expr_scope +| 9 = @namespace_scope +| 10 = @class_decl_scope +| 11 = @interface_scope +| 12 = @type_alias_scope +| 13 = @mapped_type_scope +| 14 = @enum_scope +| 15 = @external_module_scope +| 16 = @conditional_type_scope; + +scopenodes (unique int node: @ast_node ref, + int scope: @scope ref); + +scopenesting (unique int inner: @scope ref, + int outer: @scope ref); + +// functions +@function = @function_decl_stmt | @function_expr | @arrow_function_expr; + +@parameterized = @function | @catch_clause; +@type_parameterized = @function | @class_or_interface | @type_alias_declaration | @mapped_typeexpr | @infer_typeexpr; + +is_generator (int fun: @function ref); +has_rest_parameter (int fun: @function ref); +is_async (int fun: @function ref); + +// variables and lexically scoped type names +#keyset[scope, name] +variables (unique int id: @variable, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_type_names (unique int id: @local_type_name, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_namespace_names (unique int id: @local_namespace_name, + varchar(900) name: string ref, + int scope: @scope ref); + +is_arguments_object (int id: @variable ref); + +@lexical_name = @variable | @local_type_name | @local_namespace_name; + +@bind_id = @varaccess | @local_var_type_access; +bind (unique int id: @bind_id ref, + int decl: @variable ref); + +decl (unique int id: @var_decl ref, + int decl: @variable ref); + +@typebind_id = @local_type_access | @export_varaccess; +typebind (unique int id: @typebind_id ref, + int decl: @local_type_name ref); + +@typedecl_id = @type_decl | @var_decl; +typedecl (unique int id: @typedecl_id ref, + int decl: @local_type_name ref); + +namespacedecl (unique int id: @var_decl ref, + int decl: @local_namespace_name ref); + +@namespacebind_id = @local_namespace_access | @export_varaccess; +namespacebind (unique int id: @namespacebind_id ref, + int decl: @local_namespace_name ref); + + +// properties in object literals, property patterns in object patterns, and method declarations in classes +#keyset[parent, index] +properties (unique int id: @property, + int parent: @property_parent ref, + int index: int ref, + int kind: int ref, + varchar(900) tostring: string ref); + +case @property.kind of + 0 = @value_property +| 1 = @property_getter +| 2 = @property_setter +| 3 = @jsx_attribute +| 4 = @function_call_signature +| 5 = @constructor_call_signature +| 6 = @index_signature +| 7 = @enum_member +| 8 = @proper_field +| 9 = @parameter_field +; + +@property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration; +@property_accessor = @property_getter | @property_setter; +@call_signature = @function_call_signature | @constructor_call_signature; +@field = @proper_field | @parameter_field; +@field_or_vardeclarator = @field | @var_declarator; + +is_computed (int id: @property ref); +is_method (int id: @property ref); +is_static (int id: @property ref); +is_abstract_member (int id: @property ref); +is_const_enum (int id: @enum_declaration ref); +is_abstract_class (int id: @class_decl_stmt ref); + +has_public_keyword (int id: @property ref); +has_private_keyword (int id: @property ref); +has_protected_keyword (int id: @property ref); +has_readonly_keyword (int id: @property ref); +has_type_keyword (int id: @import_or_export_declaration ref); +is_optional_member (int id: @property ref); +has_definite_assignment_assertion (int id: @field_or_vardeclarator ref); +is_optional_parameter_declaration (unique int parameter: @pattern ref); + +#keyset[constructor, param_index] +parameter_fields( + unique int field: @parameter_field ref, + int constructor: @function_expr ref, + int param_index: int ref +); + +// types +#keyset[parent, idx] +typeexprs ( + unique int id: @typeexpr, + int kind: int ref, + int parent: @typeexpr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref +); + +case @typeexpr.kind of + 0 = @local_type_access +| 1 = @type_decl +| 2 = @keyword_typeexpr +| 3 = @string_literal_typeexpr +| 4 = @number_literal_typeexpr +| 5 = @boolean_literal_typeexpr +| 6 = @array_typeexpr +| 7 = @union_typeexpr +| 8 = @indexed_access_typeexpr +| 9 = @intersection_typeexpr +| 10 = @parenthesized_typeexpr +| 11 = @tuple_typeexpr +| 12 = @keyof_typeexpr +| 13 = @qualified_type_access +| 14 = @generic_typeexpr +| 15 = @type_label +| 16 = @typeof_typeexpr +| 17 = @local_var_type_access +| 18 = @qualified_var_type_access +| 19 = @this_var_type_access +| 20 = @predicate_typeexpr +| 21 = @interface_typeexpr +| 22 = @type_parameter +| 23 = @plain_function_typeexpr +| 24 = @constructor_typeexpr +| 25 = @local_namespace_access +| 26 = @qualified_namespace_access +| 27 = @mapped_typeexpr +| 28 = @conditional_typeexpr +| 29 = @infer_typeexpr +| 30 = @import_type_access +| 31 = @import_namespace_access +| 32 = @import_var_type_access +| 33 = @optional_typeexpr +| 34 = @rest_typeexpr +| 35 = @bigint_literal_typeexpr +| 36 = @readonly_typeexpr +| 37 = @template_literal_typeexpr +; + +@typeref = @typeaccess | @type_decl; +@type_identifier = @type_decl | @local_type_access | @type_label | @local_var_type_access | @local_namespace_access; +@typeexpr_parent = @expr | @stmt | @property | @typeexpr; +@literal_typeexpr = @string_literal_typeexpr | @number_literal_typeexpr | @boolean_literal_typeexpr | @bigint_literal_typeexpr; +@typeaccess = @local_type_access | @qualified_type_access | @import_type_access; +@vartypeaccess = @local_var_type_access | @qualified_var_type_access | @this_var_type_access | @import_var_type_access; +@namespace_access = @local_namespace_access | @qualified_namespace_access | @import_namespace_access; +@import_typeexpr = @import_type_access | @import_namespace_access | @import_var_type_access; + +@function_typeexpr = @plain_function_typeexpr | @constructor_typeexpr; + +// types +types ( + unique int id: @type, + int kind: int ref, + varchar(900) tostring: string ref +); + +#keyset[parent, idx] +type_child ( + int child: @type ref, + int parent: @type ref, + int idx: int ref +); + +case @type.kind of + 0 = @any_type +| 1 = @string_type +| 2 = @number_type +| 3 = @union_type +| 4 = @true_type +| 5 = @false_type +| 6 = @type_reference +| 7 = @object_type +| 8 = @canonical_type_variable_type +| 9 = @typeof_type +| 10 = @void_type +| 11 = @undefined_type +| 12 = @null_type +| 13 = @never_type +| 14 = @plain_symbol_type +| 15 = @unique_symbol_type +| 16 = @objectkeyword_type +| 17 = @intersection_type +| 18 = @tuple_type +| 19 = @lexical_type_variable_type +| 20 = @this_type +| 21 = @number_literal_type +| 22 = @string_literal_type +| 23 = @unknown_type +| 24 = @bigint_type +| 25 = @bigint_literal_type +; + +@boolean_literal_type = @true_type | @false_type; +@symbol_type = @plain_symbol_type | @unique_symbol_type; +@union_or_intersection_type = @union_type | @intersection_type; +@typevariable_type = @canonical_type_variable_type | @lexical_type_variable_type; + +has_asserts_keyword(int node: @predicate_typeexpr ref); + +@typed_ast_node = @expr | @typeexpr | @function; +ast_node_type( + unique int node: @typed_ast_node ref, + int typ: @type ref); + +declared_function_signature( + unique int node: @function ref, + int sig: @signature_type ref +); + +invoke_expr_signature( + unique int node: @invokeexpr ref, + int sig: @signature_type ref +); + +invoke_expr_overload_index( + unique int node: @invokeexpr ref, + int index: int ref +); + +symbols ( + unique int id: @symbol, + int kind: int ref, + varchar(900) name: string ref +); + +symbol_parent ( + unique int symbol: @symbol ref, + int parent: @symbol ref +); + +symbol_module ( + int symbol: @symbol ref, + varchar(900) moduleName: string ref +); + +symbol_global ( + int symbol: @symbol ref, + varchar(900) globalName: string ref +); + +case @symbol.kind of + 0 = @root_symbol +| 1 = @member_symbol +| 2 = @other_symbol +; + +@type_with_symbol = @type_reference | @typevariable_type | @typeof_type | @unique_symbol_type; +@ast_node_with_symbol = @type_definition | @namespace_definition | @toplevel | @typeaccess | @namespace_access | @var_decl | @function | @invokeexpr | @import_declaration | @external_module_reference; + +ast_node_symbol( + unique int node: @ast_node_with_symbol ref, + int symbol: @symbol ref); + +type_symbol( + unique int typ: @type_with_symbol ref, + int symbol: @symbol ref); + +#keyset[typ, name] +type_property( + int typ: @type ref, + varchar(900) name: string ref, + int propertyType: @type ref); + +type_alias( + unique int aliasType: @type ref, + int underlyingType: @type ref); + +@literal_type = @string_literal_type | @number_literal_type | @boolean_literal_type | @bigint_literal_type; +@type_with_literal_value = @string_literal_type | @number_literal_type | @bigint_literal_type; +type_literal_value( + unique int typ: @type_with_literal_value ref, + varchar(900) value: string ref); + +signature_types ( + unique int id: @signature_type, + int kind: int ref, + varchar(900) tostring: string ref, + int type_parameters: int ref, + int required_params: int ref +); + +is_abstract_signature( + unique int sig: @signature_type ref +); + +signature_rest_parameter( + unique int sig: @signature_type ref, + int rest_param_arra_type: @type ref +); + +case @signature_type.kind of + 0 = @function_signature_type +| 1 = @constructor_signature_type +; + +#keyset[typ, kind, index] +type_contains_signature ( + int typ: @type ref, + int kind: int ref, // constructor/call/index + int index: int ref, // ordering of overloaded signatures + int sig: @signature_type ref +); + +#keyset[parent, index] +signature_contains_type ( + int child: @type ref, + int parent: @signature_type ref, + int index: int ref +); + +#keyset[sig, index] +signature_parameter_name ( + int sig: @signature_type ref, + int index: int ref, + varchar(900) name: string ref +); + +number_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +string_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +base_type_names( + int typeName: @symbol ref, + int baseTypeName: @symbol ref +); + +self_types( + int typeName: @symbol ref, + int selfType: @type_reference ref +); + +tuple_type_min_length( + unique int typ: @type ref, + int minLength: int ref +); + +tuple_type_rest_index( + unique int typ: @type ref, + int index: int ref +); + +// comments +comments (unique int id: @comment, + int kind: int ref, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(900) tostring: string ref); + +case @comment.kind of + 0 = @slashslash_comment +| 1 = @slashstar_comment +| 2 = @doc_comment +| 3 = @html_comment_start +| 4 = @htmlcommentend; + +@html_comment = @html_comment_start | @htmlcommentend; +@line_comment = @slashslash_comment | @html_comment; +@block_comment = @slashstar_comment | @doc_comment; + +// source lines +lines (unique int id: @line, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(2) terminator: string ref); +indentation (int file: @file ref, + int lineno: int ref, + varchar(1) indentChar: string ref, + int indentDepth: int ref); + +// JavaScript parse errors +js_parse_errors (unique int id: @js_parse_error, + int toplevel: @toplevel ref, + varchar(900) message: string ref, + varchar(900) line: string ref); + +// regular expressions +#keyset[parent, idx] +regexpterm (unique int id: @regexpterm, + int kind: int ref, + int parent: @regexpparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +@regexpparent = @regexpterm | @regexp_literal | @string_literal; + +case @regexpterm.kind of + 0 = @regexp_alt +| 1 = @regexp_seq +| 2 = @regexp_caret +| 3 = @regexp_dollar +| 4 = @regexp_wordboundary +| 5 = @regexp_nonwordboundary +| 6 = @regexp_positive_lookahead +| 7 = @regexp_negative_lookahead +| 8 = @regexp_star +| 9 = @regexp_plus +| 10 = @regexp_opt +| 11 = @regexp_range +| 12 = @regexp_dot +| 13 = @regexp_group +| 14 = @regexp_normal_constant +| 15 = @regexp_hex_escape +| 16 = @regexp_unicode_escape +| 17 = @regexp_dec_escape +| 18 = @regexp_oct_escape +| 19 = @regexp_ctrl_escape +| 20 = @regexp_char_class_escape +| 21 = @regexp_id_escape +| 22 = @regexp_backref +| 23 = @regexp_char_class +| 24 = @regexp_char_range +| 25 = @regexp_positive_lookbehind +| 26 = @regexp_negative_lookbehind +| 27 = @regexp_unicode_property_escape; + +regexp_parse_errors (unique int id: @regexp_parse_error, + int regexp: @regexpterm ref, + varchar(900) message: string ref); + +@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range; +@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape; +@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape; +@regexp_constant = @regexp_normal_constant | @regexp_char_escape; +@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead; +@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind; +@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind; +@regexp_anchor = @regexp_dollar | @regexp_caret; + +is_greedy (int id: @regexp_quantifier ref); +range_quantifier_lower_bound (unique int id: @regexp_range ref, int lo: int ref); +range_quantifier_upper_bound (unique int id: @regexp_range ref, int hi: int ref); +is_capture (unique int id: @regexp_group ref, int number: int ref); +is_named_capture (unique int id: @regexp_group ref, string name: string ref); +is_inverted (int id: @regexp_char_class ref); +regexp_const_value (unique int id: @regexp_constant ref, varchar(1) value: string ref); +char_class_escape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref); +backref (unique int id: @regexp_backref ref, int value: int ref); +named_backref (unique int id: @regexp_backref ref, string name: string ref); +unicode_property_escapename (unique int id: @regexp_unicode_property_escape ref, string name: string ref); +unicode_property_escapevalue (unique int id: @regexp_unicode_property_escape ref, string value: string ref); + +// tokens +#keyset[toplevel, idx] +tokeninfo (unique int id: @token, + int kind: int ref, + int toplevel: @toplevel ref, + int idx: int ref, + varchar(900) value: string ref); + +case @token.kind of + 0 = @token_eof +| 1 = @token_null_literal +| 2 = @token_boolean_literal +| 3 = @token_numeric_literal +| 4 = @token_string_literal +| 5 = @token_regular_expression +| 6 = @token_identifier +| 7 = @token_keyword +| 8 = @token_punctuator; + +// associate comments with the token immediately following them (which may be EOF) +next_token (int comment: @comment ref, int token: @token ref); + +// JSON +#keyset[parent, idx] +json (unique int id: @json_value, + int kind: int ref, + int parent: @json_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +json_literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @json_value ref); + +json_properties (int obj: @json_object ref, + varchar(900) property: string ref, + int value: @json_value ref); + +json_errors (unique int id: @json_parse_error, + varchar(900) message: string ref); + +json_locations(unique int locatable: @json_locatable ref, + int location: @location_default ref); + +case @json_value.kind of + 0 = @json_null +| 1 = @json_boolean +| 2 = @json_number +| 3 = @json_string +| 4 = @json_array +| 5 = @json_object; + +@json_parent = @json_object | @json_array | @file; + +@json_locatable = @json_value | @json_parse_error; + +// locations +@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr; + +@locatable = @file + | @ast_node + | @comment + | @line + | @js_parse_error | @regexp_parse_error + | @regexpterm + | @json_locatable + | @token + | @cfg_node + | @jsdoc | @jsdoc_type_expr | @jsdoc_tag + | @yaml_locatable + | @xmllocatable + | @configLocatable + | @template_placeholder_tag; + +hasLocation (unique int locatable: @locatable ref, + int location: @location ref); + +// CFG +entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref); +exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref); +guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref); +case @guard_node.kind of + 0 = @falsy_guard +| 1 = @truthy_guard; +@condition_guard = @falsy_guard | @truthy_guard; + +@synthetic_cfg_node = @entry_node | @exit_node | @guard_node; +@cfg_node = @synthetic_cfg_node | @expr_parent; + +successor (int pred: @cfg_node ref, int succ: @cfg_node ref); + +// JSDoc comments +jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref); +#keyset[parent, idx] +jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref, + int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref); +jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); +jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); + +#keyset[parent, idx] +jsdoc_type_exprs (unique int id: @jsdoc_type_expr, + int kind: int ref, + int parent: @jsdoc_type_expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); +case @jsdoc_type_expr.kind of + 0 = @jsdoc_any_type_expr +| 1 = @jsdoc_null_type_expr +| 2 = @jsdoc_undefined_type_expr +| 3 = @jsdoc_unknown_type_expr +| 4 = @jsdoc_void_type_expr +| 5 = @jsdoc_named_type_expr +| 6 = @jsdoc_applied_type_expr +| 7 = @jsdoc_nullable_type_expr +| 8 = @jsdoc_non_nullable_type_expr +| 9 = @jsdoc_record_type_expr +| 10 = @jsdoc_array_type_expr +| 11 = @jsdoc_union_type_expr +| 12 = @jsdoc_function_type_expr +| 13 = @jsdoc_optional_type_expr +| 14 = @jsdoc_rest_type_expr +; + +#keyset[id, idx] +jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref); +jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref); +jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref); + +@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag; + +jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref); + +// YAML +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + varchar(900) tag: string ref, + varchar(900) tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + varchar(900) anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + varchar(900) target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + varchar(900) value: string ref); + +yaml_errors (unique int id: @yaml_error, + varchar(900) message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/* XML Files */ + +xmlEncoding( + unique int id: @file ref, + varchar(900) encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + varchar(900) root: string ref, + varchar(900) publicId: string ref, + varchar(900) systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + varchar(900) name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + varchar(900) name: string ref, + varchar(3600) value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + varchar(900) prefixName: string ref, + varchar(900) URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property; + +@optionalchainable = @call_expr | @propaccess; + +isOptionalChaining(int id: @optionalchainable ref); + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +/** + * The time taken for the extraction of a file. + * This table contains non-deterministic content. + * + * The sum of the `time` column for each (`file`, `timerKind`) pair + * is the total time taken for extraction of `file`. The `extractionPhase` + * column provides a granular view of the extraction time of the file. + */ +extraction_time( + int file : @file ref, + // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`. + int extractionPhase: int ref, + // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds + int timerKind: int ref, + float time: float ref +) + +/** + * Non-timing related data for the extraction of a single file. + * This table contains non-deterministic content. + */ +extraction_data( + int file : @file ref, + // the absolute path to the cache file + varchar(900) cacheFile: string ref, + boolean fromCache: boolean ref, + int length: int ref +) diff --git a/javascript/upgrades/9ca3692b65fd8d751431861d1a25c57f3e61d15b/upgrade.properties b/javascript/upgrades/9ca3692b65fd8d751431861d1a25c57f3e61d15b/upgrade.properties new file mode 100644 index 00000000000..a0c4ba602a1 --- /dev/null +++ b/javascript/upgrades/9ca3692b65fd8d751431861d1a25c57f3e61d15b/upgrade.properties @@ -0,0 +1,4 @@ +description: Removed unused column from the `folders` and `files` relations +compatibility: full +files.rel: reorder files.rel (int id, string name, string simple, string ext, int fromSource) id name +folders.rel: reorder folders.rel (int id, string name, string simple) id name \ No newline at end of file diff --git a/javascript/upgrades/e34b3e16dba5d11961119818c9beeff334f20a90/old.dbscheme b/javascript/upgrades/e34b3e16dba5d11961119818c9beeff334f20a90/old.dbscheme new file mode 100644 index 00000000000..e34b3e16dba --- /dev/null +++ b/javascript/upgrades/e34b3e16dba5d11961119818c9beeff334f20a90/old.dbscheme @@ -0,0 +1,1216 @@ +/*** Standard fragments ***/ + +/** Files and folders **/ + +@location = @location_default; + +locations_default(unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref + ); + +@sourceline = @locatable; + +numlines(int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref + ); + +files(unique int id: @file, + varchar(900) name: string ref); + +folders(unique int id: @folder, + varchar(900) name: string ref); + + +@container = @folder | @file ; + + +containerparent(int parent: @container ref, + unique int child: @container ref); + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + +/** Version control data **/ + +svnentries( + int id : @svnentry, + varchar(500) revision : string ref, + varchar(500) author : string ref, + date revisionDate : date ref, + int changeSize : int ref +); + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + varchar(500) action : string ref +); + +svnentrymsg( + int id : @svnentry ref, + varchar(500) message : string ref +); + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +); + + +/*** JavaScript-specific part ***/ + +filetype( + int file: @file ref, + string filetype: string ref +) + +// top-level code fragments +toplevels (unique int id: @toplevel, + int kind: int ref); + +is_externs (int toplevel: @toplevel ref); + +case @toplevel.kind of + 0 = @script +| 1 = @inline_script +| 2 = @event_handler +| 3 = @javascript_url +| 4 = @template_toplevel; + +is_module (int tl: @toplevel ref); +is_nodejs (int tl: @toplevel ref); +is_es2015_module (int tl: @toplevel ref); +is_closure_module (int tl: @toplevel ref); + +@xml_node_with_code = @xmlelement | @xmlattribute | @template_placeholder_tag; +toplevel_parent_xml_node( + unique int toplevel: @toplevel ref, + int xmlnode: @xml_node_with_code ref); + +xml_element_parent_expression( + unique int xmlnode: @xmlelement ref, + int expression: @expr ref, + int index: int ref); + +// statements +#keyset[parent, idx] +stmts (unique int id: @stmt, + int kind: int ref, + int parent: @stmt_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +stmt_containers (unique int stmt: @stmt ref, + int container: @stmt_container ref); + +jump_targets (unique int jump: @stmt ref, + int target: @stmt ref); + +@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr; +@stmt_container = @toplevel | @function | @namespace_declaration | @external_module_declaration | @global_augmentation_declaration; + +case @stmt.kind of + 0 = @empty_stmt +| 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @labeled_stmt +| 5 = @break_stmt +| 6 = @continue_stmt +| 7 = @with_stmt +| 8 = @switch_stmt +| 9 = @return_stmt +| 10 = @throw_stmt +| 11 = @try_stmt +| 12 = @while_stmt +| 13 = @do_while_stmt +| 14 = @for_stmt +| 15 = @for_in_stmt +| 16 = @debugger_stmt +| 17 = @function_decl_stmt +| 18 = @var_decl_stmt +| 19 = @case +| 20 = @catch_clause +| 21 = @for_of_stmt +| 22 = @const_decl_stmt +| 23 = @let_stmt +| 24 = @legacy_let_stmt +| 25 = @for_each_stmt +| 26 = @class_decl_stmt +| 27 = @import_declaration +| 28 = @export_all_declaration +| 29 = @export_default_declaration +| 30 = @export_named_declaration +| 31 = @namespace_declaration +| 32 = @import_equals_declaration +| 33 = @export_assign_declaration +| 34 = @interface_declaration +| 35 = @type_alias_declaration +| 36 = @enum_declaration +| 37 = @external_module_declaration +| 38 = @export_as_namespace_declaration +| 39 = @global_augmentation_declaration +; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt; + +@export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration; + +@namespace_definition = @namespace_declaration | @enum_declaration; +@type_definition = @class_definition | @interface_declaration | @enum_declaration | @type_alias_declaration | @enum_member; + +is_instantiated(unique int decl: @namespace_declaration ref); + +@declarable_node = @decl_stmt | @namespace_declaration | @class_decl_stmt | @function_decl_stmt | @enum_declaration | @external_module_declaration | @global_augmentation_declaration | @field; +has_declare_keyword(unique int stmt: @declarable_node ref); + +is_for_await_of(unique int forof: @for_of_stmt ref); + +// expressions +#keyset[parent, idx] +exprs (unique int id: @expr, + int kind: int ref, + int parent: @expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @expr_or_type ref); + +enclosing_stmt (unique int expr: @expr_or_type ref, + int stmt: @stmt ref); + +expr_containers (unique int expr: @expr_or_type ref, + int container: @stmt_container ref); + +array_size (unique int ae: @arraylike ref, + int sz: int ref); + +is_delegating (int yield: @yield_expr ref); + +@expr_or_stmt = @expr | @stmt; +@expr_or_type = @expr | @typeexpr; +@expr_parent = @expr_or_stmt | @property | @function_typeexpr; +@arraylike = @array_expr | @array_pattern; +@type_annotation = @typeexpr | @jsdoc_type_expr; +@node_in_stmt_container = @cfg_node | @type_annotation | @toplevel; + +case @expr.kind of + 0 = @label +| 1 = @null_literal +| 2 = @boolean_literal +| 3 = @number_literal +| 4 = @string_literal +| 5 = @regexp_literal +| 6 = @this_expr +| 7 = @array_expr +| 8 = @obj_expr +| 9 = @function_expr +| 10 = @seq_expr +| 11 = @conditional_expr +| 12 = @new_expr +| 13 = @call_expr +| 14 = @dot_expr +| 15 = @index_expr +| 16 = @neg_expr +| 17 = @plus_expr +| 18 = @log_not_expr +| 19 = @bit_not_expr +| 20 = @typeof_expr +| 21 = @void_expr +| 22 = @delete_expr +| 23 = @eq_expr +| 24 = @neq_expr +| 25 = @eqq_expr +| 26 = @neqq_expr +| 27 = @lt_expr +| 28 = @le_expr +| 29 = @gt_expr +| 30 = @ge_expr +| 31 = @lshift_expr +| 32 = @rshift_expr +| 33 = @urshift_expr +| 34 = @add_expr +| 35 = @sub_expr +| 36 = @mul_expr +| 37 = @div_expr +| 38 = @mod_expr +| 39 = @bitor_expr +| 40 = @xor_expr +| 41 = @bitand_expr +| 42 = @in_expr +| 43 = @instanceof_expr +| 44 = @logand_expr +| 45 = @logor_expr +| 47 = @assign_expr +| 48 = @assign_add_expr +| 49 = @assign_sub_expr +| 50 = @assign_mul_expr +| 51 = @assign_div_expr +| 52 = @assign_mod_expr +| 53 = @assign_lshift_expr +| 54 = @assign_rshift_expr +| 55 = @assign_urshift_expr +| 56 = @assign_or_expr +| 57 = @assign_xor_expr +| 58 = @assign_and_expr +| 59 = @preinc_expr +| 60 = @postinc_expr +| 61 = @predec_expr +| 62 = @postdec_expr +| 63 = @par_expr +| 64 = @var_declarator +| 65 = @arrow_function_expr +| 66 = @spread_element +| 67 = @array_pattern +| 68 = @object_pattern +| 69 = @yield_expr +| 70 = @tagged_template_expr +| 71 = @template_literal +| 72 = @template_element +| 73 = @array_comprehension_expr +| 74 = @generator_expr +| 75 = @for_in_comprehension_block +| 76 = @for_of_comprehension_block +| 77 = @legacy_letexpr +| 78 = @var_decl +| 79 = @proper_varaccess +| 80 = @class_expr +| 81 = @super_expr +| 82 = @newtarget_expr +| 83 = @named_import_specifier +| 84 = @import_default_specifier +| 85 = @import_namespace_specifier +| 86 = @named_export_specifier +| 87 = @exp_expr +| 88 = @assign_exp_expr +| 89 = @jsx_element +| 90 = @jsx_qualified_name +| 91 = @jsx_empty_expr +| 92 = @await_expr +| 93 = @function_sent_expr +| 94 = @decorator +| 95 = @export_default_specifier +| 96 = @export_namespace_specifier +| 97 = @bind_expr +| 98 = @external_module_reference +| 99 = @dynamic_import +| 100 = @expression_with_type_arguments +| 101 = @prefix_type_assertion +| 102 = @as_type_assertion +| 103 = @export_varaccess +| 104 = @decorator_list +| 105 = @non_null_assertion +| 106 = @bigint_literal +| 107 = @nullishcoalescing_expr +| 108 = @e4x_xml_anyname +| 109 = @e4x_xml_static_attribute_selector +| 110 = @e4x_xml_dynamic_attribute_selector +| 111 = @e4x_xml_filter_expression +| 112 = @e4x_xml_static_qualident +| 113 = @e4x_xml_dynamic_qualident +| 114 = @e4x_xml_dotdotexpr +| 115 = @import_meta_expr +| 116 = @assignlogandexpr +| 117 = @assignlogorexpr +| 118 = @assignnullishcoalescingexpr +| 119 = @template_pipe_ref +| 120 = @generated_code_expr +; + +@varaccess = @proper_varaccess | @export_varaccess; +@varref = @var_decl | @varaccess; + +@identifier = @label | @varref | @type_identifier; + +@literal = @null_literal | @boolean_literal | @number_literal | @string_literal | @regexp_literal | @bigint_literal; + +@propaccess = @dot_expr | @index_expr; + +@invokeexpr = @new_expr | @call_expr; + +@unaryexpr = @neg_expr | @plus_expr | @log_not_expr | @bit_not_expr | @typeof_expr | @void_expr | @delete_expr | @spread_element; + +@equality_test = @eq_expr | @neq_expr | @eqq_expr | @neqq_expr; + +@comparison = @equality_test | @lt_expr | @le_expr | @gt_expr | @ge_expr; + +@binaryexpr = @comparison | @lshift_expr | @rshift_expr | @urshift_expr | @add_expr | @sub_expr | @mul_expr | @div_expr | @mod_expr | @exp_expr | @bitor_expr | @xor_expr | @bitand_expr | @in_expr | @instanceof_expr | @logand_expr | @logor_expr | @nullishcoalescing_expr; + +@assignment = @assign_expr | @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr | @assign_mod_expr | @assign_exp_expr | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr | @assign_or_expr | @assign_xor_expr | @assign_and_expr | @assignlogandexpr | @assignlogorexpr | @assignnullishcoalescingexpr; + +@updateexpr = @preinc_expr | @postinc_expr | @predec_expr | @postdec_expr; + +@pattern = @varref | @array_pattern | @object_pattern; + +@comprehension_expr = @array_comprehension_expr | @generator_expr; + +@comprehension_block = @for_in_comprehension_block | @for_of_comprehension_block; + +@import_specifier = @named_import_specifier | @import_default_specifier | @import_namespace_specifier; + +@exportspecifier = @named_export_specifier | @export_default_specifier | @export_namespace_specifier; + +@import_or_export_declaration = @import_declaration | @export_declaration; + +@type_assertion = @as_type_assertion | @prefix_type_assertion; + +@class_definition = @class_decl_stmt | @class_expr; +@interface_definition = @interface_declaration | @interface_typeexpr; +@class_or_interface = @class_definition | @interface_definition; + +@lexical_decl = @var_decl | @type_decl; +@lexical_access = @varaccess | @local_type_access | @local_var_type_access | @local_namespace_access; +@lexical_ref = @lexical_decl | @lexical_access; + +@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector; +@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident; + +expr_contains_template_tag_location( + int expr: @expr ref, + int location: @location ref +); + +@template_placeholder_tag_parent = @xmlelement | @xmlattribute | @file; + +template_placeholder_tag_info( + unique int node: @template_placeholder_tag, + int parentNode: @template_placeholder_tag_parent ref, + varchar(900) raw: string ref +); + +// scopes +scopes (unique int id: @scope, + int kind: int ref); + +case @scope.kind of + 0 = @global_scope +| 1 = @function_scope +| 2 = @catch_scope +| 3 = @module_scope +| 4 = @block_scope +| 5 = @for_scope +| 6 = @for_in_scope // for-of scopes work the same as for-in scopes +| 7 = @comprehension_block_scope +| 8 = @class_expr_scope +| 9 = @namespace_scope +| 10 = @class_decl_scope +| 11 = @interface_scope +| 12 = @type_alias_scope +| 13 = @mapped_type_scope +| 14 = @enum_scope +| 15 = @external_module_scope +| 16 = @conditional_type_scope; + +scopenodes (unique int node: @ast_node ref, + int scope: @scope ref); + +scopenesting (unique int inner: @scope ref, + int outer: @scope ref); + +// functions +@function = @function_decl_stmt | @function_expr | @arrow_function_expr; + +@parameterized = @function | @catch_clause; +@type_parameterized = @function | @class_or_interface | @type_alias_declaration | @mapped_typeexpr | @infer_typeexpr; + +is_generator (int fun: @function ref); +has_rest_parameter (int fun: @function ref); +is_async (int fun: @function ref); + +// variables and lexically scoped type names +#keyset[scope, name] +variables (unique int id: @variable, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_type_names (unique int id: @local_type_name, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_namespace_names (unique int id: @local_namespace_name, + varchar(900) name: string ref, + int scope: @scope ref); + +is_arguments_object (int id: @variable ref); + +@lexical_name = @variable | @local_type_name | @local_namespace_name; + +@bind_id = @varaccess | @local_var_type_access; +bind (unique int id: @bind_id ref, + int decl: @variable ref); + +decl (unique int id: @var_decl ref, + int decl: @variable ref); + +@typebind_id = @local_type_access | @export_varaccess; +typebind (unique int id: @typebind_id ref, + int decl: @local_type_name ref); + +@typedecl_id = @type_decl | @var_decl; +typedecl (unique int id: @typedecl_id ref, + int decl: @local_type_name ref); + +namespacedecl (unique int id: @var_decl ref, + int decl: @local_namespace_name ref); + +@namespacebind_id = @local_namespace_access | @export_varaccess; +namespacebind (unique int id: @namespacebind_id ref, + int decl: @local_namespace_name ref); + + +// properties in object literals, property patterns in object patterns, and method declarations in classes +#keyset[parent, index] +properties (unique int id: @property, + int parent: @property_parent ref, + int index: int ref, + int kind: int ref, + varchar(900) tostring: string ref); + +case @property.kind of + 0 = @value_property +| 1 = @property_getter +| 2 = @property_setter +| 3 = @jsx_attribute +| 4 = @function_call_signature +| 5 = @constructor_call_signature +| 6 = @index_signature +| 7 = @enum_member +| 8 = @proper_field +| 9 = @parameter_field +; + +@property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration; +@property_accessor = @property_getter | @property_setter; +@call_signature = @function_call_signature | @constructor_call_signature; +@field = @proper_field | @parameter_field; +@field_or_vardeclarator = @field | @var_declarator; + +is_computed (int id: @property ref); +is_method (int id: @property ref); +is_static (int id: @property ref); +is_abstract_member (int id: @property ref); +is_const_enum (int id: @enum_declaration ref); +is_abstract_class (int id: @class_decl_stmt ref); + +has_public_keyword (int id: @property ref); +has_private_keyword (int id: @property ref); +has_protected_keyword (int id: @property ref); +has_readonly_keyword (int id: @property ref); +has_type_keyword (int id: @import_or_export_declaration ref); +is_optional_member (int id: @property ref); +has_definite_assignment_assertion (int id: @field_or_vardeclarator ref); +is_optional_parameter_declaration (unique int parameter: @pattern ref); + +#keyset[constructor, param_index] +parameter_fields( + unique int field: @parameter_field ref, + int constructor: @function_expr ref, + int param_index: int ref +); + +// types +#keyset[parent, idx] +typeexprs ( + unique int id: @typeexpr, + int kind: int ref, + int parent: @typeexpr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref +); + +case @typeexpr.kind of + 0 = @local_type_access +| 1 = @type_decl +| 2 = @keyword_typeexpr +| 3 = @string_literal_typeexpr +| 4 = @number_literal_typeexpr +| 5 = @boolean_literal_typeexpr +| 6 = @array_typeexpr +| 7 = @union_typeexpr +| 8 = @indexed_access_typeexpr +| 9 = @intersection_typeexpr +| 10 = @parenthesized_typeexpr +| 11 = @tuple_typeexpr +| 12 = @keyof_typeexpr +| 13 = @qualified_type_access +| 14 = @generic_typeexpr +| 15 = @type_label +| 16 = @typeof_typeexpr +| 17 = @local_var_type_access +| 18 = @qualified_var_type_access +| 19 = @this_var_type_access +| 20 = @predicate_typeexpr +| 21 = @interface_typeexpr +| 22 = @type_parameter +| 23 = @plain_function_typeexpr +| 24 = @constructor_typeexpr +| 25 = @local_namespace_access +| 26 = @qualified_namespace_access +| 27 = @mapped_typeexpr +| 28 = @conditional_typeexpr +| 29 = @infer_typeexpr +| 30 = @import_type_access +| 31 = @import_namespace_access +| 32 = @import_var_type_access +| 33 = @optional_typeexpr +| 34 = @rest_typeexpr +| 35 = @bigint_literal_typeexpr +| 36 = @readonly_typeexpr +| 37 = @template_literal_typeexpr +; + +@typeref = @typeaccess | @type_decl; +@type_identifier = @type_decl | @local_type_access | @type_label | @local_var_type_access | @local_namespace_access; +@typeexpr_parent = @expr | @stmt | @property | @typeexpr; +@literal_typeexpr = @string_literal_typeexpr | @number_literal_typeexpr | @boolean_literal_typeexpr | @bigint_literal_typeexpr; +@typeaccess = @local_type_access | @qualified_type_access | @import_type_access; +@vartypeaccess = @local_var_type_access | @qualified_var_type_access | @this_var_type_access | @import_var_type_access; +@namespace_access = @local_namespace_access | @qualified_namespace_access | @import_namespace_access; +@import_typeexpr = @import_type_access | @import_namespace_access | @import_var_type_access; + +@function_typeexpr = @plain_function_typeexpr | @constructor_typeexpr; + +// types +types ( + unique int id: @type, + int kind: int ref, + varchar(900) tostring: string ref +); + +#keyset[parent, idx] +type_child ( + int child: @type ref, + int parent: @type ref, + int idx: int ref +); + +case @type.kind of + 0 = @any_type +| 1 = @string_type +| 2 = @number_type +| 3 = @union_type +| 4 = @true_type +| 5 = @false_type +| 6 = @type_reference +| 7 = @object_type +| 8 = @canonical_type_variable_type +| 9 = @typeof_type +| 10 = @void_type +| 11 = @undefined_type +| 12 = @null_type +| 13 = @never_type +| 14 = @plain_symbol_type +| 15 = @unique_symbol_type +| 16 = @objectkeyword_type +| 17 = @intersection_type +| 18 = @tuple_type +| 19 = @lexical_type_variable_type +| 20 = @this_type +| 21 = @number_literal_type +| 22 = @string_literal_type +| 23 = @unknown_type +| 24 = @bigint_type +| 25 = @bigint_literal_type +; + +@boolean_literal_type = @true_type | @false_type; +@symbol_type = @plain_symbol_type | @unique_symbol_type; +@union_or_intersection_type = @union_type | @intersection_type; +@typevariable_type = @canonical_type_variable_type | @lexical_type_variable_type; + +has_asserts_keyword(int node: @predicate_typeexpr ref); + +@typed_ast_node = @expr | @typeexpr | @function; +ast_node_type( + unique int node: @typed_ast_node ref, + int typ: @type ref); + +declared_function_signature( + unique int node: @function ref, + int sig: @signature_type ref +); + +invoke_expr_signature( + unique int node: @invokeexpr ref, + int sig: @signature_type ref +); + +invoke_expr_overload_index( + unique int node: @invokeexpr ref, + int index: int ref +); + +symbols ( + unique int id: @symbol, + int kind: int ref, + varchar(900) name: string ref +); + +symbol_parent ( + unique int symbol: @symbol ref, + int parent: @symbol ref +); + +symbol_module ( + int symbol: @symbol ref, + varchar(900) moduleName: string ref +); + +symbol_global ( + int symbol: @symbol ref, + varchar(900) globalName: string ref +); + +case @symbol.kind of + 0 = @root_symbol +| 1 = @member_symbol +| 2 = @other_symbol +; + +@type_with_symbol = @type_reference | @typevariable_type | @typeof_type | @unique_symbol_type; +@ast_node_with_symbol = @type_definition | @namespace_definition | @toplevel | @typeaccess | @namespace_access | @var_decl | @function | @invokeexpr | @import_declaration | @external_module_reference; + +ast_node_symbol( + unique int node: @ast_node_with_symbol ref, + int symbol: @symbol ref); + +type_symbol( + unique int typ: @type_with_symbol ref, + int symbol: @symbol ref); + +#keyset[typ, name] +type_property( + int typ: @type ref, + varchar(900) name: string ref, + int propertyType: @type ref); + +type_alias( + unique int aliasType: @type ref, + int underlyingType: @type ref); + +@literal_type = @string_literal_type | @number_literal_type | @boolean_literal_type | @bigint_literal_type; +@type_with_literal_value = @string_literal_type | @number_literal_type | @bigint_literal_type; +type_literal_value( + unique int typ: @type_with_literal_value ref, + varchar(900) value: string ref); + +signature_types ( + unique int id: @signature_type, + int kind: int ref, + varchar(900) tostring: string ref, + int type_parameters: int ref, + int required_params: int ref +); + +is_abstract_signature( + unique int sig: @signature_type ref +); + +signature_rest_parameter( + unique int sig: @signature_type ref, + int rest_param_arra_type: @type ref +); + +case @signature_type.kind of + 0 = @function_signature_type +| 1 = @constructor_signature_type +; + +#keyset[typ, kind, index] +type_contains_signature ( + int typ: @type ref, + int kind: int ref, // constructor/call/index + int index: int ref, // ordering of overloaded signatures + int sig: @signature_type ref +); + +#keyset[parent, index] +signature_contains_type ( + int child: @type ref, + int parent: @signature_type ref, + int index: int ref +); + +#keyset[sig, index] +signature_parameter_name ( + int sig: @signature_type ref, + int index: int ref, + varchar(900) name: string ref +); + +number_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +string_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +base_type_names( + int typeName: @symbol ref, + int baseTypeName: @symbol ref +); + +self_types( + int typeName: @symbol ref, + int selfType: @type_reference ref +); + +tuple_type_min_length( + unique int typ: @type ref, + int minLength: int ref +); + +tuple_type_rest_index( + unique int typ: @type ref, + int index: int ref +); + +// comments +comments (unique int id: @comment, + int kind: int ref, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(900) tostring: string ref); + +case @comment.kind of + 0 = @slashslash_comment +| 1 = @slashstar_comment +| 2 = @doc_comment +| 3 = @html_comment_start +| 4 = @htmlcommentend; + +@html_comment = @html_comment_start | @htmlcommentend; +@line_comment = @slashslash_comment | @html_comment; +@block_comment = @slashstar_comment | @doc_comment; + +// source lines +lines (unique int id: @line, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(2) terminator: string ref); +indentation (int file: @file ref, + int lineno: int ref, + varchar(1) indentChar: string ref, + int indentDepth: int ref); + +// JavaScript parse errors +js_parse_errors (unique int id: @js_parse_error, + int toplevel: @toplevel ref, + varchar(900) message: string ref, + varchar(900) line: string ref); + +// regular expressions +#keyset[parent, idx] +regexpterm (unique int id: @regexpterm, + int kind: int ref, + int parent: @regexpparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +@regexpparent = @regexpterm | @regexp_literal | @string_literal; + +case @regexpterm.kind of + 0 = @regexp_alt +| 1 = @regexp_seq +| 2 = @regexp_caret +| 3 = @regexp_dollar +| 4 = @regexp_wordboundary +| 5 = @regexp_nonwordboundary +| 6 = @regexp_positive_lookahead +| 7 = @regexp_negative_lookahead +| 8 = @regexp_star +| 9 = @regexp_plus +| 10 = @regexp_opt +| 11 = @regexp_range +| 12 = @regexp_dot +| 13 = @regexp_group +| 14 = @regexp_normal_constant +| 15 = @regexp_hex_escape +| 16 = @regexp_unicode_escape +| 17 = @regexp_dec_escape +| 18 = @regexp_oct_escape +| 19 = @regexp_ctrl_escape +| 20 = @regexp_char_class_escape +| 21 = @regexp_id_escape +| 22 = @regexp_backref +| 23 = @regexp_char_class +| 24 = @regexp_char_range +| 25 = @regexp_positive_lookbehind +| 26 = @regexp_negative_lookbehind +| 27 = @regexp_unicode_property_escape; + +regexp_parse_errors (unique int id: @regexp_parse_error, + int regexp: @regexpterm ref, + varchar(900) message: string ref); + +@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range; +@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape; +@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape; +@regexp_constant = @regexp_normal_constant | @regexp_char_escape; +@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead; +@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind; +@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind; +@regexp_anchor = @regexp_dollar | @regexp_caret; + +is_greedy (int id: @regexp_quantifier ref); +range_quantifier_lower_bound (unique int id: @regexp_range ref, int lo: int ref); +range_quantifier_upper_bound (unique int id: @regexp_range ref, int hi: int ref); +is_capture (unique int id: @regexp_group ref, int number: int ref); +is_named_capture (unique int id: @regexp_group ref, string name: string ref); +is_inverted (int id: @regexp_char_class ref); +regexp_const_value (unique int id: @regexp_constant ref, varchar(1) value: string ref); +char_class_escape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref); +backref (unique int id: @regexp_backref ref, int value: int ref); +named_backref (unique int id: @regexp_backref ref, string name: string ref); +unicode_property_escapename (unique int id: @regexp_unicode_property_escape ref, string name: string ref); +unicode_property_escapevalue (unique int id: @regexp_unicode_property_escape ref, string value: string ref); + +// tokens +#keyset[toplevel, idx] +tokeninfo (unique int id: @token, + int kind: int ref, + int toplevel: @toplevel ref, + int idx: int ref, + varchar(900) value: string ref); + +case @token.kind of + 0 = @token_eof +| 1 = @token_null_literal +| 2 = @token_boolean_literal +| 3 = @token_numeric_literal +| 4 = @token_string_literal +| 5 = @token_regular_expression +| 6 = @token_identifier +| 7 = @token_keyword +| 8 = @token_punctuator; + +// associate comments with the token immediately following them (which may be EOF) +next_token (int comment: @comment ref, int token: @token ref); + +// JSON +#keyset[parent, idx] +json (unique int id: @json_value, + int kind: int ref, + int parent: @json_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +json_literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @json_value ref); + +json_properties (int obj: @json_object ref, + varchar(900) property: string ref, + int value: @json_value ref); + +json_errors (unique int id: @json_parse_error, + varchar(900) message: string ref); + +json_locations(unique int locatable: @json_locatable ref, + int location: @location_default ref); + +case @json_value.kind of + 0 = @json_null +| 1 = @json_boolean +| 2 = @json_number +| 3 = @json_string +| 4 = @json_array +| 5 = @json_object; + +@json_parent = @json_object | @json_array | @file; + +@json_locatable = @json_value | @json_parse_error; + +// locations +@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr; + +@locatable = @file + | @ast_node + | @comment + | @line + | @js_parse_error | @regexp_parse_error + | @regexpterm + | @json_locatable + | @token + | @cfg_node + | @jsdoc | @jsdoc_type_expr | @jsdoc_tag + | @yaml_locatable + | @xmllocatable + | @configLocatable + | @template_placeholder_tag; + +hasLocation (unique int locatable: @locatable ref, + int location: @location ref); + +// CFG +entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref); +exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref); +guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref); +case @guard_node.kind of + 0 = @falsy_guard +| 1 = @truthy_guard; +@condition_guard = @falsy_guard | @truthy_guard; + +@synthetic_cfg_node = @entry_node | @exit_node | @guard_node; +@cfg_node = @synthetic_cfg_node | @expr_parent; + +successor (int pred: @cfg_node ref, int succ: @cfg_node ref); + +// JSDoc comments +jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref); +#keyset[parent, idx] +jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref, + int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref); +jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); +jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); + +#keyset[parent, idx] +jsdoc_type_exprs (unique int id: @jsdoc_type_expr, + int kind: int ref, + int parent: @jsdoc_type_expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); +case @jsdoc_type_expr.kind of + 0 = @jsdoc_any_type_expr +| 1 = @jsdoc_null_type_expr +| 2 = @jsdoc_undefined_type_expr +| 3 = @jsdoc_unknown_type_expr +| 4 = @jsdoc_void_type_expr +| 5 = @jsdoc_named_type_expr +| 6 = @jsdoc_applied_type_expr +| 7 = @jsdoc_nullable_type_expr +| 8 = @jsdoc_non_nullable_type_expr +| 9 = @jsdoc_record_type_expr +| 10 = @jsdoc_array_type_expr +| 11 = @jsdoc_union_type_expr +| 12 = @jsdoc_function_type_expr +| 13 = @jsdoc_optional_type_expr +| 14 = @jsdoc_rest_type_expr +; + +#keyset[id, idx] +jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref); +jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref); +jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref); + +@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag; + +jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref); + +// YAML +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + varchar(900) tag: string ref, + varchar(900) tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + varchar(900) anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + varchar(900) target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + varchar(900) value: string ref); + +yaml_errors (unique int id: @yaml_error, + varchar(900) message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/* XML Files */ + +xmlEncoding( + unique int id: @file ref, + varchar(900) encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + varchar(900) root: string ref, + varchar(900) publicId: string ref, + varchar(900) systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + varchar(900) name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + varchar(900) name: string ref, + varchar(3600) value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + varchar(900) prefixName: string ref, + varchar(900) URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property; + +@optionalchainable = @call_expr | @propaccess; + +isOptionalChaining(int id: @optionalchainable ref); + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +/** + * The time taken for the extraction of a file. + * This table contains non-deterministic content. + * + * The sum of the `time` column for each (`file`, `timerKind`) pair + * is the total time taken for extraction of `file`. The `extractionPhase` + * column provides a granular view of the extraction time of the file. + */ +extraction_time( + int file : @file ref, + // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`. + int extractionPhase: int ref, + // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds + int timerKind: int ref, + float time: float ref +) + +/** + * Non-timing related data for the extraction of a single file. + * This table contains non-deterministic content. + */ +extraction_data( + int file : @file ref, + // the absolute path to the cache file + varchar(900) cacheFile: string ref, + boolean fromCache: boolean ref, + int length: int ref +) diff --git a/javascript/upgrades/e34b3e16dba5d11961119818c9beeff334f20a90/semmlecode.javascript.dbscheme b/javascript/upgrades/e34b3e16dba5d11961119818c9beeff334f20a90/semmlecode.javascript.dbscheme new file mode 100644 index 00000000000..e54b35a8a12 --- /dev/null +++ b/javascript/upgrades/e34b3e16dba5d11961119818c9beeff334f20a90/semmlecode.javascript.dbscheme @@ -0,0 +1,1217 @@ +/*** Standard fragments ***/ + +/** Files and folders **/ + +@location = @location_default; + +locations_default(unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref + ); + +@sourceline = @locatable; + +numlines(int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref + ); + +files(unique int id: @file, + varchar(900) name: string ref); + +folders(unique int id: @folder, + varchar(900) name: string ref); + + +@container = @folder | @file ; + + +containerparent(int parent: @container ref, + unique int child: @container ref); + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + +/** Version control data **/ + +svnentries( + int id : @svnentry, + varchar(500) revision : string ref, + varchar(500) author : string ref, + date revisionDate : date ref, + int changeSize : int ref +); + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + varchar(500) action : string ref +); + +svnentrymsg( + int id : @svnentry ref, + varchar(500) message : string ref +); + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +); + + +/*** JavaScript-specific part ***/ + +filetype( + int file: @file ref, + string filetype: string ref +) + +// top-level code fragments +toplevels (unique int id: @toplevel, + int kind: int ref); + +is_externs (int toplevel: @toplevel ref); + +case @toplevel.kind of + 0 = @script +| 1 = @inline_script +| 2 = @event_handler +| 3 = @javascript_url +| 4 = @template_toplevel; + +is_module (int tl: @toplevel ref); +is_nodejs (int tl: @toplevel ref); +is_es2015_module (int tl: @toplevel ref); +is_closure_module (int tl: @toplevel ref); + +@xml_node_with_code = @xmlelement | @xmlattribute | @template_placeholder_tag; +toplevel_parent_xml_node( + unique int toplevel: @toplevel ref, + int xmlnode: @xml_node_with_code ref); + +xml_element_parent_expression( + unique int xmlnode: @xmlelement ref, + int expression: @expr ref, + int index: int ref); + +// statements +#keyset[parent, idx] +stmts (unique int id: @stmt, + int kind: int ref, + int parent: @stmt_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +stmt_containers (unique int stmt: @stmt ref, + int container: @stmt_container ref); + +jump_targets (unique int jump: @stmt ref, + int target: @stmt ref); + +@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr | @static_initializer; +@stmt_container = @toplevel | @function | @namespace_declaration | @external_module_declaration | @global_augmentation_declaration; + +case @stmt.kind of + 0 = @empty_stmt +| 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @labeled_stmt +| 5 = @break_stmt +| 6 = @continue_stmt +| 7 = @with_stmt +| 8 = @switch_stmt +| 9 = @return_stmt +| 10 = @throw_stmt +| 11 = @try_stmt +| 12 = @while_stmt +| 13 = @do_while_stmt +| 14 = @for_stmt +| 15 = @for_in_stmt +| 16 = @debugger_stmt +| 17 = @function_decl_stmt +| 18 = @var_decl_stmt +| 19 = @case +| 20 = @catch_clause +| 21 = @for_of_stmt +| 22 = @const_decl_stmt +| 23 = @let_stmt +| 24 = @legacy_let_stmt +| 25 = @for_each_stmt +| 26 = @class_decl_stmt +| 27 = @import_declaration +| 28 = @export_all_declaration +| 29 = @export_default_declaration +| 30 = @export_named_declaration +| 31 = @namespace_declaration +| 32 = @import_equals_declaration +| 33 = @export_assign_declaration +| 34 = @interface_declaration +| 35 = @type_alias_declaration +| 36 = @enum_declaration +| 37 = @external_module_declaration +| 38 = @export_as_namespace_declaration +| 39 = @global_augmentation_declaration +; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt; + +@export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration; + +@namespace_definition = @namespace_declaration | @enum_declaration; +@type_definition = @class_definition | @interface_declaration | @enum_declaration | @type_alias_declaration | @enum_member; + +is_instantiated(unique int decl: @namespace_declaration ref); + +@declarable_node = @decl_stmt | @namespace_declaration | @class_decl_stmt | @function_decl_stmt | @enum_declaration | @external_module_declaration | @global_augmentation_declaration | @field; +has_declare_keyword(unique int stmt: @declarable_node ref); + +is_for_await_of(unique int forof: @for_of_stmt ref); + +// expressions +#keyset[parent, idx] +exprs (unique int id: @expr, + int kind: int ref, + int parent: @expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @expr_or_type ref); + +enclosing_stmt (unique int expr: @expr_or_type ref, + int stmt: @stmt ref); + +expr_containers (unique int expr: @expr_or_type ref, + int container: @stmt_container ref); + +array_size (unique int ae: @arraylike ref, + int sz: int ref); + +is_delegating (int yield: @yield_expr ref); + +@expr_or_stmt = @expr | @stmt; +@expr_or_type = @expr | @typeexpr; +@expr_parent = @expr_or_stmt | @property | @function_typeexpr; +@arraylike = @array_expr | @array_pattern; +@type_annotation = @typeexpr | @jsdoc_type_expr; +@node_in_stmt_container = @cfg_node | @type_annotation | @toplevel; + +case @expr.kind of + 0 = @label +| 1 = @null_literal +| 2 = @boolean_literal +| 3 = @number_literal +| 4 = @string_literal +| 5 = @regexp_literal +| 6 = @this_expr +| 7 = @array_expr +| 8 = @obj_expr +| 9 = @function_expr +| 10 = @seq_expr +| 11 = @conditional_expr +| 12 = @new_expr +| 13 = @call_expr +| 14 = @dot_expr +| 15 = @index_expr +| 16 = @neg_expr +| 17 = @plus_expr +| 18 = @log_not_expr +| 19 = @bit_not_expr +| 20 = @typeof_expr +| 21 = @void_expr +| 22 = @delete_expr +| 23 = @eq_expr +| 24 = @neq_expr +| 25 = @eqq_expr +| 26 = @neqq_expr +| 27 = @lt_expr +| 28 = @le_expr +| 29 = @gt_expr +| 30 = @ge_expr +| 31 = @lshift_expr +| 32 = @rshift_expr +| 33 = @urshift_expr +| 34 = @add_expr +| 35 = @sub_expr +| 36 = @mul_expr +| 37 = @div_expr +| 38 = @mod_expr +| 39 = @bitor_expr +| 40 = @xor_expr +| 41 = @bitand_expr +| 42 = @in_expr +| 43 = @instanceof_expr +| 44 = @logand_expr +| 45 = @logor_expr +| 47 = @assign_expr +| 48 = @assign_add_expr +| 49 = @assign_sub_expr +| 50 = @assign_mul_expr +| 51 = @assign_div_expr +| 52 = @assign_mod_expr +| 53 = @assign_lshift_expr +| 54 = @assign_rshift_expr +| 55 = @assign_urshift_expr +| 56 = @assign_or_expr +| 57 = @assign_xor_expr +| 58 = @assign_and_expr +| 59 = @preinc_expr +| 60 = @postinc_expr +| 61 = @predec_expr +| 62 = @postdec_expr +| 63 = @par_expr +| 64 = @var_declarator +| 65 = @arrow_function_expr +| 66 = @spread_element +| 67 = @array_pattern +| 68 = @object_pattern +| 69 = @yield_expr +| 70 = @tagged_template_expr +| 71 = @template_literal +| 72 = @template_element +| 73 = @array_comprehension_expr +| 74 = @generator_expr +| 75 = @for_in_comprehension_block +| 76 = @for_of_comprehension_block +| 77 = @legacy_letexpr +| 78 = @var_decl +| 79 = @proper_varaccess +| 80 = @class_expr +| 81 = @super_expr +| 82 = @newtarget_expr +| 83 = @named_import_specifier +| 84 = @import_default_specifier +| 85 = @import_namespace_specifier +| 86 = @named_export_specifier +| 87 = @exp_expr +| 88 = @assign_exp_expr +| 89 = @jsx_element +| 90 = @jsx_qualified_name +| 91 = @jsx_empty_expr +| 92 = @await_expr +| 93 = @function_sent_expr +| 94 = @decorator +| 95 = @export_default_specifier +| 96 = @export_namespace_specifier +| 97 = @bind_expr +| 98 = @external_module_reference +| 99 = @dynamic_import +| 100 = @expression_with_type_arguments +| 101 = @prefix_type_assertion +| 102 = @as_type_assertion +| 103 = @export_varaccess +| 104 = @decorator_list +| 105 = @non_null_assertion +| 106 = @bigint_literal +| 107 = @nullishcoalescing_expr +| 108 = @e4x_xml_anyname +| 109 = @e4x_xml_static_attribute_selector +| 110 = @e4x_xml_dynamic_attribute_selector +| 111 = @e4x_xml_filter_expression +| 112 = @e4x_xml_static_qualident +| 113 = @e4x_xml_dynamic_qualident +| 114 = @e4x_xml_dotdotexpr +| 115 = @import_meta_expr +| 116 = @assignlogandexpr +| 117 = @assignlogorexpr +| 118 = @assignnullishcoalescingexpr +| 119 = @template_pipe_ref +| 120 = @generated_code_expr +; + +@varaccess = @proper_varaccess | @export_varaccess; +@varref = @var_decl | @varaccess; + +@identifier = @label | @varref | @type_identifier; + +@literal = @null_literal | @boolean_literal | @number_literal | @string_literal | @regexp_literal | @bigint_literal; + +@propaccess = @dot_expr | @index_expr; + +@invokeexpr = @new_expr | @call_expr; + +@unaryexpr = @neg_expr | @plus_expr | @log_not_expr | @bit_not_expr | @typeof_expr | @void_expr | @delete_expr | @spread_element; + +@equality_test = @eq_expr | @neq_expr | @eqq_expr | @neqq_expr; + +@comparison = @equality_test | @lt_expr | @le_expr | @gt_expr | @ge_expr; + +@binaryexpr = @comparison | @lshift_expr | @rshift_expr | @urshift_expr | @add_expr | @sub_expr | @mul_expr | @div_expr | @mod_expr | @exp_expr | @bitor_expr | @xor_expr | @bitand_expr | @in_expr | @instanceof_expr | @logand_expr | @logor_expr | @nullishcoalescing_expr; + +@assignment = @assign_expr | @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr | @assign_mod_expr | @assign_exp_expr | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr | @assign_or_expr | @assign_xor_expr | @assign_and_expr | @assignlogandexpr | @assignlogorexpr | @assignnullishcoalescingexpr; + +@updateexpr = @preinc_expr | @postinc_expr | @predec_expr | @postdec_expr; + +@pattern = @varref | @array_pattern | @object_pattern; + +@comprehension_expr = @array_comprehension_expr | @generator_expr; + +@comprehension_block = @for_in_comprehension_block | @for_of_comprehension_block; + +@import_specifier = @named_import_specifier | @import_default_specifier | @import_namespace_specifier; + +@exportspecifier = @named_export_specifier | @export_default_specifier | @export_namespace_specifier; + +@import_or_export_declaration = @import_declaration | @export_declaration; + +@type_assertion = @as_type_assertion | @prefix_type_assertion; + +@class_definition = @class_decl_stmt | @class_expr; +@interface_definition = @interface_declaration | @interface_typeexpr; +@class_or_interface = @class_definition | @interface_definition; + +@lexical_decl = @var_decl | @type_decl; +@lexical_access = @varaccess | @local_type_access | @local_var_type_access | @local_namespace_access; +@lexical_ref = @lexical_decl | @lexical_access; + +@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector; +@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident; + +expr_contains_template_tag_location( + int expr: @expr ref, + int location: @location ref +); + +@template_placeholder_tag_parent = @xmlelement | @xmlattribute | @file; + +template_placeholder_tag_info( + unique int node: @template_placeholder_tag, + int parentNode: @template_placeholder_tag_parent ref, + varchar(900) raw: string ref +); + +// scopes +scopes (unique int id: @scope, + int kind: int ref); + +case @scope.kind of + 0 = @global_scope +| 1 = @function_scope +| 2 = @catch_scope +| 3 = @module_scope +| 4 = @block_scope +| 5 = @for_scope +| 6 = @for_in_scope // for-of scopes work the same as for-in scopes +| 7 = @comprehension_block_scope +| 8 = @class_expr_scope +| 9 = @namespace_scope +| 10 = @class_decl_scope +| 11 = @interface_scope +| 12 = @type_alias_scope +| 13 = @mapped_type_scope +| 14 = @enum_scope +| 15 = @external_module_scope +| 16 = @conditional_type_scope; + +scopenodes (unique int node: @ast_node ref, + int scope: @scope ref); + +scopenesting (unique int inner: @scope ref, + int outer: @scope ref); + +// functions +@function = @function_decl_stmt | @function_expr | @arrow_function_expr; + +@parameterized = @function | @catch_clause; +@type_parameterized = @function | @class_or_interface | @type_alias_declaration | @mapped_typeexpr | @infer_typeexpr; + +is_generator (int fun: @function ref); +has_rest_parameter (int fun: @function ref); +is_async (int fun: @function ref); + +// variables and lexically scoped type names +#keyset[scope, name] +variables (unique int id: @variable, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_type_names (unique int id: @local_type_name, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_namespace_names (unique int id: @local_namespace_name, + varchar(900) name: string ref, + int scope: @scope ref); + +is_arguments_object (int id: @variable ref); + +@lexical_name = @variable | @local_type_name | @local_namespace_name; + +@bind_id = @varaccess | @local_var_type_access; +bind (unique int id: @bind_id ref, + int decl: @variable ref); + +decl (unique int id: @var_decl ref, + int decl: @variable ref); + +@typebind_id = @local_type_access | @export_varaccess; +typebind (unique int id: @typebind_id ref, + int decl: @local_type_name ref); + +@typedecl_id = @type_decl | @var_decl; +typedecl (unique int id: @typedecl_id ref, + int decl: @local_type_name ref); + +namespacedecl (unique int id: @var_decl ref, + int decl: @local_namespace_name ref); + +@namespacebind_id = @local_namespace_access | @export_varaccess; +namespacebind (unique int id: @namespacebind_id ref, + int decl: @local_namespace_name ref); + + +// properties in object literals, property patterns in object patterns, and method declarations in classes +#keyset[parent, index] +properties (unique int id: @property, + int parent: @property_parent ref, + int index: int ref, + int kind: int ref, + varchar(900) tostring: string ref); + +case @property.kind of + 0 = @value_property +| 1 = @property_getter +| 2 = @property_setter +| 3 = @jsx_attribute +| 4 = @function_call_signature +| 5 = @constructor_call_signature +| 6 = @index_signature +| 7 = @enum_member +| 8 = @proper_field +| 9 = @parameter_field +| 10 = @static_initializer +; + +@property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration; +@property_accessor = @property_getter | @property_setter; +@call_signature = @function_call_signature | @constructor_call_signature; +@field = @proper_field | @parameter_field; +@field_or_vardeclarator = @field | @var_declarator; + +is_computed (int id: @property ref); +is_method (int id: @property ref); +is_static (int id: @property ref); +is_abstract_member (int id: @property ref); +is_const_enum (int id: @enum_declaration ref); +is_abstract_class (int id: @class_decl_stmt ref); + +has_public_keyword (int id: @property ref); +has_private_keyword (int id: @property ref); +has_protected_keyword (int id: @property ref); +has_readonly_keyword (int id: @property ref); +has_type_keyword (int id: @import_or_export_declaration ref); +is_optional_member (int id: @property ref); +has_definite_assignment_assertion (int id: @field_or_vardeclarator ref); +is_optional_parameter_declaration (unique int parameter: @pattern ref); + +#keyset[constructor, param_index] +parameter_fields( + unique int field: @parameter_field ref, + int constructor: @function_expr ref, + int param_index: int ref +); + +// types +#keyset[parent, idx] +typeexprs ( + unique int id: @typeexpr, + int kind: int ref, + int parent: @typeexpr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref +); + +case @typeexpr.kind of + 0 = @local_type_access +| 1 = @type_decl +| 2 = @keyword_typeexpr +| 3 = @string_literal_typeexpr +| 4 = @number_literal_typeexpr +| 5 = @boolean_literal_typeexpr +| 6 = @array_typeexpr +| 7 = @union_typeexpr +| 8 = @indexed_access_typeexpr +| 9 = @intersection_typeexpr +| 10 = @parenthesized_typeexpr +| 11 = @tuple_typeexpr +| 12 = @keyof_typeexpr +| 13 = @qualified_type_access +| 14 = @generic_typeexpr +| 15 = @type_label +| 16 = @typeof_typeexpr +| 17 = @local_var_type_access +| 18 = @qualified_var_type_access +| 19 = @this_var_type_access +| 20 = @predicate_typeexpr +| 21 = @interface_typeexpr +| 22 = @type_parameter +| 23 = @plain_function_typeexpr +| 24 = @constructor_typeexpr +| 25 = @local_namespace_access +| 26 = @qualified_namespace_access +| 27 = @mapped_typeexpr +| 28 = @conditional_typeexpr +| 29 = @infer_typeexpr +| 30 = @import_type_access +| 31 = @import_namespace_access +| 32 = @import_var_type_access +| 33 = @optional_typeexpr +| 34 = @rest_typeexpr +| 35 = @bigint_literal_typeexpr +| 36 = @readonly_typeexpr +| 37 = @template_literal_typeexpr +; + +@typeref = @typeaccess | @type_decl; +@type_identifier = @type_decl | @local_type_access | @type_label | @local_var_type_access | @local_namespace_access; +@typeexpr_parent = @expr | @stmt | @property | @typeexpr; +@literal_typeexpr = @string_literal_typeexpr | @number_literal_typeexpr | @boolean_literal_typeexpr | @bigint_literal_typeexpr; +@typeaccess = @local_type_access | @qualified_type_access | @import_type_access; +@vartypeaccess = @local_var_type_access | @qualified_var_type_access | @this_var_type_access | @import_var_type_access; +@namespace_access = @local_namespace_access | @qualified_namespace_access | @import_namespace_access; +@import_typeexpr = @import_type_access | @import_namespace_access | @import_var_type_access; + +@function_typeexpr = @plain_function_typeexpr | @constructor_typeexpr; + +// types +types ( + unique int id: @type, + int kind: int ref, + varchar(900) tostring: string ref +); + +#keyset[parent, idx] +type_child ( + int child: @type ref, + int parent: @type ref, + int idx: int ref +); + +case @type.kind of + 0 = @any_type +| 1 = @string_type +| 2 = @number_type +| 3 = @union_type +| 4 = @true_type +| 5 = @false_type +| 6 = @type_reference +| 7 = @object_type +| 8 = @canonical_type_variable_type +| 9 = @typeof_type +| 10 = @void_type +| 11 = @undefined_type +| 12 = @null_type +| 13 = @never_type +| 14 = @plain_symbol_type +| 15 = @unique_symbol_type +| 16 = @objectkeyword_type +| 17 = @intersection_type +| 18 = @tuple_type +| 19 = @lexical_type_variable_type +| 20 = @this_type +| 21 = @number_literal_type +| 22 = @string_literal_type +| 23 = @unknown_type +| 24 = @bigint_type +| 25 = @bigint_literal_type +; + +@boolean_literal_type = @true_type | @false_type; +@symbol_type = @plain_symbol_type | @unique_symbol_type; +@union_or_intersection_type = @union_type | @intersection_type; +@typevariable_type = @canonical_type_variable_type | @lexical_type_variable_type; + +has_asserts_keyword(int node: @predicate_typeexpr ref); + +@typed_ast_node = @expr | @typeexpr | @function; +ast_node_type( + unique int node: @typed_ast_node ref, + int typ: @type ref); + +declared_function_signature( + unique int node: @function ref, + int sig: @signature_type ref +); + +invoke_expr_signature( + unique int node: @invokeexpr ref, + int sig: @signature_type ref +); + +invoke_expr_overload_index( + unique int node: @invokeexpr ref, + int index: int ref +); + +symbols ( + unique int id: @symbol, + int kind: int ref, + varchar(900) name: string ref +); + +symbol_parent ( + unique int symbol: @symbol ref, + int parent: @symbol ref +); + +symbol_module ( + int symbol: @symbol ref, + varchar(900) moduleName: string ref +); + +symbol_global ( + int symbol: @symbol ref, + varchar(900) globalName: string ref +); + +case @symbol.kind of + 0 = @root_symbol +| 1 = @member_symbol +| 2 = @other_symbol +; + +@type_with_symbol = @type_reference | @typevariable_type | @typeof_type | @unique_symbol_type; +@ast_node_with_symbol = @type_definition | @namespace_definition | @toplevel | @typeaccess | @namespace_access | @var_decl | @function | @invokeexpr | @import_declaration | @external_module_reference; + +ast_node_symbol( + unique int node: @ast_node_with_symbol ref, + int symbol: @symbol ref); + +type_symbol( + unique int typ: @type_with_symbol ref, + int symbol: @symbol ref); + +#keyset[typ, name] +type_property( + int typ: @type ref, + varchar(900) name: string ref, + int propertyType: @type ref); + +type_alias( + unique int aliasType: @type ref, + int underlyingType: @type ref); + +@literal_type = @string_literal_type | @number_literal_type | @boolean_literal_type | @bigint_literal_type; +@type_with_literal_value = @string_literal_type | @number_literal_type | @bigint_literal_type; +type_literal_value( + unique int typ: @type_with_literal_value ref, + varchar(900) value: string ref); + +signature_types ( + unique int id: @signature_type, + int kind: int ref, + varchar(900) tostring: string ref, + int type_parameters: int ref, + int required_params: int ref +); + +is_abstract_signature( + unique int sig: @signature_type ref +); + +signature_rest_parameter( + unique int sig: @signature_type ref, + int rest_param_arra_type: @type ref +); + +case @signature_type.kind of + 0 = @function_signature_type +| 1 = @constructor_signature_type +; + +#keyset[typ, kind, index] +type_contains_signature ( + int typ: @type ref, + int kind: int ref, // constructor/call/index + int index: int ref, // ordering of overloaded signatures + int sig: @signature_type ref +); + +#keyset[parent, index] +signature_contains_type ( + int child: @type ref, + int parent: @signature_type ref, + int index: int ref +); + +#keyset[sig, index] +signature_parameter_name ( + int sig: @signature_type ref, + int index: int ref, + varchar(900) name: string ref +); + +number_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +string_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +base_type_names( + int typeName: @symbol ref, + int baseTypeName: @symbol ref +); + +self_types( + int typeName: @symbol ref, + int selfType: @type_reference ref +); + +tuple_type_min_length( + unique int typ: @type ref, + int minLength: int ref +); + +tuple_type_rest_index( + unique int typ: @type ref, + int index: int ref +); + +// comments +comments (unique int id: @comment, + int kind: int ref, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(900) tostring: string ref); + +case @comment.kind of + 0 = @slashslash_comment +| 1 = @slashstar_comment +| 2 = @doc_comment +| 3 = @html_comment_start +| 4 = @htmlcommentend; + +@html_comment = @html_comment_start | @htmlcommentend; +@line_comment = @slashslash_comment | @html_comment; +@block_comment = @slashstar_comment | @doc_comment; + +// source lines +lines (unique int id: @line, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(2) terminator: string ref); +indentation (int file: @file ref, + int lineno: int ref, + varchar(1) indentChar: string ref, + int indentDepth: int ref); + +// JavaScript parse errors +js_parse_errors (unique int id: @js_parse_error, + int toplevel: @toplevel ref, + varchar(900) message: string ref, + varchar(900) line: string ref); + +// regular expressions +#keyset[parent, idx] +regexpterm (unique int id: @regexpterm, + int kind: int ref, + int parent: @regexpparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +@regexpparent = @regexpterm | @regexp_literal | @string_literal; + +case @regexpterm.kind of + 0 = @regexp_alt +| 1 = @regexp_seq +| 2 = @regexp_caret +| 3 = @regexp_dollar +| 4 = @regexp_wordboundary +| 5 = @regexp_nonwordboundary +| 6 = @regexp_positive_lookahead +| 7 = @regexp_negative_lookahead +| 8 = @regexp_star +| 9 = @regexp_plus +| 10 = @regexp_opt +| 11 = @regexp_range +| 12 = @regexp_dot +| 13 = @regexp_group +| 14 = @regexp_normal_constant +| 15 = @regexp_hex_escape +| 16 = @regexp_unicode_escape +| 17 = @regexp_dec_escape +| 18 = @regexp_oct_escape +| 19 = @regexp_ctrl_escape +| 20 = @regexp_char_class_escape +| 21 = @regexp_id_escape +| 22 = @regexp_backref +| 23 = @regexp_char_class +| 24 = @regexp_char_range +| 25 = @regexp_positive_lookbehind +| 26 = @regexp_negative_lookbehind +| 27 = @regexp_unicode_property_escape; + +regexp_parse_errors (unique int id: @regexp_parse_error, + int regexp: @regexpterm ref, + varchar(900) message: string ref); + +@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range; +@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape; +@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape; +@regexp_constant = @regexp_normal_constant | @regexp_char_escape; +@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead; +@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind; +@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind; +@regexp_anchor = @regexp_dollar | @regexp_caret; + +is_greedy (int id: @regexp_quantifier ref); +range_quantifier_lower_bound (unique int id: @regexp_range ref, int lo: int ref); +range_quantifier_upper_bound (unique int id: @regexp_range ref, int hi: int ref); +is_capture (unique int id: @regexp_group ref, int number: int ref); +is_named_capture (unique int id: @regexp_group ref, string name: string ref); +is_inverted (int id: @regexp_char_class ref); +regexp_const_value (unique int id: @regexp_constant ref, varchar(1) value: string ref); +char_class_escape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref); +backref (unique int id: @regexp_backref ref, int value: int ref); +named_backref (unique int id: @regexp_backref ref, string name: string ref); +unicode_property_escapename (unique int id: @regexp_unicode_property_escape ref, string name: string ref); +unicode_property_escapevalue (unique int id: @regexp_unicode_property_escape ref, string value: string ref); + +// tokens +#keyset[toplevel, idx] +tokeninfo (unique int id: @token, + int kind: int ref, + int toplevel: @toplevel ref, + int idx: int ref, + varchar(900) value: string ref); + +case @token.kind of + 0 = @token_eof +| 1 = @token_null_literal +| 2 = @token_boolean_literal +| 3 = @token_numeric_literal +| 4 = @token_string_literal +| 5 = @token_regular_expression +| 6 = @token_identifier +| 7 = @token_keyword +| 8 = @token_punctuator; + +// associate comments with the token immediately following them (which may be EOF) +next_token (int comment: @comment ref, int token: @token ref); + +// JSON +#keyset[parent, idx] +json (unique int id: @json_value, + int kind: int ref, + int parent: @json_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +json_literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @json_value ref); + +json_properties (int obj: @json_object ref, + varchar(900) property: string ref, + int value: @json_value ref); + +json_errors (unique int id: @json_parse_error, + varchar(900) message: string ref); + +json_locations(unique int locatable: @json_locatable ref, + int location: @location_default ref); + +case @json_value.kind of + 0 = @json_null +| 1 = @json_boolean +| 2 = @json_number +| 3 = @json_string +| 4 = @json_array +| 5 = @json_object; + +@json_parent = @json_object | @json_array | @file; + +@json_locatable = @json_value | @json_parse_error; + +// locations +@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr; + +@locatable = @file + | @ast_node + | @comment + | @line + | @js_parse_error | @regexp_parse_error + | @regexpterm + | @json_locatable + | @token + | @cfg_node + | @jsdoc | @jsdoc_type_expr | @jsdoc_tag + | @yaml_locatable + | @xmllocatable + | @configLocatable + | @template_placeholder_tag; + +hasLocation (unique int locatable: @locatable ref, + int location: @location ref); + +// CFG +entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref); +exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref); +guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref); +case @guard_node.kind of + 0 = @falsy_guard +| 1 = @truthy_guard; +@condition_guard = @falsy_guard | @truthy_guard; + +@synthetic_cfg_node = @entry_node | @exit_node | @guard_node; +@cfg_node = @synthetic_cfg_node | @expr_parent; + +successor (int pred: @cfg_node ref, int succ: @cfg_node ref); + +// JSDoc comments +jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref); +#keyset[parent, idx] +jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref, + int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref); +jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); +jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); + +#keyset[parent, idx] +jsdoc_type_exprs (unique int id: @jsdoc_type_expr, + int kind: int ref, + int parent: @jsdoc_type_expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); +case @jsdoc_type_expr.kind of + 0 = @jsdoc_any_type_expr +| 1 = @jsdoc_null_type_expr +| 2 = @jsdoc_undefined_type_expr +| 3 = @jsdoc_unknown_type_expr +| 4 = @jsdoc_void_type_expr +| 5 = @jsdoc_named_type_expr +| 6 = @jsdoc_applied_type_expr +| 7 = @jsdoc_nullable_type_expr +| 8 = @jsdoc_non_nullable_type_expr +| 9 = @jsdoc_record_type_expr +| 10 = @jsdoc_array_type_expr +| 11 = @jsdoc_union_type_expr +| 12 = @jsdoc_function_type_expr +| 13 = @jsdoc_optional_type_expr +| 14 = @jsdoc_rest_type_expr +; + +#keyset[id, idx] +jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref); +jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref); +jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref); + +@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag; + +jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref); + +// YAML +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + varchar(900) tag: string ref, + varchar(900) tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + varchar(900) anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + varchar(900) target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + varchar(900) value: string ref); + +yaml_errors (unique int id: @yaml_error, + varchar(900) message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/* XML Files */ + +xmlEncoding( + unique int id: @file ref, + varchar(900) encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + varchar(900) root: string ref, + varchar(900) publicId: string ref, + varchar(900) systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + varchar(900) name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + varchar(900) name: string ref, + varchar(3600) value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + varchar(900) prefixName: string ref, + varchar(900) URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property; + +@optionalchainable = @call_expr | @propaccess; + +isOptionalChaining(int id: @optionalchainable ref); + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +/** + * The time taken for the extraction of a file. + * This table contains non-deterministic content. + * + * The sum of the `time` column for each (`file`, `timerKind`) pair + * is the total time taken for extraction of `file`. The `extractionPhase` + * column provides a granular view of the extraction time of the file. + */ +extraction_time( + int file : @file ref, + // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`. + int extractionPhase: int ref, + // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds + int timerKind: int ref, + float time: float ref +) + +/** + * Non-timing related data for the extraction of a single file. + * This table contains non-deterministic content. + */ +extraction_data( + int file : @file ref, + // the absolute path to the cache file + varchar(900) cacheFile: string ref, + boolean fromCache: boolean ref, + int length: int ref +) diff --git a/javascript/upgrades/e34b3e16dba5d11961119818c9beeff334f20a90/upgrade.properties b/javascript/upgrades/e34b3e16dba5d11961119818c9beeff334f20a90/upgrade.properties new file mode 100644 index 00000000000..736a282f9fa --- /dev/null +++ b/javascript/upgrades/e34b3e16dba5d11961119818c9beeff334f20a90/upgrade.properties @@ -0,0 +1,2 @@ +description: add @static_initializer property kind +compatibility: backwards diff --git a/misc/scripts/library-coverage/generate-timeseries.py b/misc/scripts/library-coverage/generate-timeseries.py index bfba9362ff2..49bade6ba03 100644 --- a/misc/scripts/library-coverage/generate-timeseries.py +++ b/misc/scripts/library-coverage/generate-timeseries.py @@ -41,14 +41,15 @@ class Git: return (parent_sha, parent_date) -def get_packages(lang, query, search_path): +def get_packages(config, search_path): try: - db = "empty_" + lang - ql_output = "output-" + lang + ".csv" + db = "empty_" + config.lang + ql_output = "output-" + config.lang + ".csv" if os.path.isdir(db): shutil.rmtree(db) - utils.create_empty_database(lang, ".java", db) - utils.run_codeql_query(query, db, ql_output, search_path) + utils.create_empty_database( + config.lang, config.ext, db, config.dbscheme) + utils.run_codeql_query(config.ql_path, db, ql_output, search_path) return pack.PackageCollection(ql_output) except: @@ -71,9 +72,9 @@ else: configs = [ utils.LanguageConfig( - "java", "Java", ".java", "java/ql/src/meta/frameworks/Coverage.ql"), + "java", "Java", ".java", "java/ql/src/meta/frameworks/Coverage.ql", ["java/ql/lib/config/semmlecode.dbscheme", "java/ql/src/config/semmlecode.dbscheme"]), utils.LanguageConfig( - "csharp", "C#", ".cs", "csharp/ql/src/meta/frameworks/Coverage.ql") + "csharp", "C#", ".cs", "csharp/ql/src/meta/frameworks/Coverage.ql", ["csharp/ql/lib/semmlecode.csharp.dbscheme", "csharp/ql/src/semmlecode.csharp.dbscheme"]) ] output_prefix = "framework-coverage-timeseries-" @@ -102,7 +103,8 @@ for lang in settings.languages: "file_total": file_total, "file_packages": file_packages, "csvwriter_total": csvwriter_total, - "csvwriter_packages": csvwriter_packages + "csvwriter_packages": csvwriter_packages, + "last_row": (None, None, None) } try: @@ -141,15 +143,20 @@ try: frameworks: fr.FrameworkCollection = language_utils[lang]["frameworks"] csvwriter_total = language_utils[lang]["csvwriter_total"] csvwriter_packages = language_utils[lang]["csvwriter_packages"] + last_row = language_utils[lang]["last_row"] - packages = get_packages(lang, config.ql_path, ".") + packages = get_packages(config, ".") - csvwriter_total.writerow([ - current_sha, - current_date, - packages.get_part_count("source"), - packages.get_part_count("sink"), - packages.get_part_count("summary")]) + new_row = (packages.get_part_count("source"), + packages.get_part_count("sink"), + packages.get_part_count("summary")) + + if last_row != new_row: + csvwriter_total.writerow([ + current_sha, + current_date, + new_row[0], new_row[1], new_row[2]]) + language_utils[lang]["last_row"] = new_row matched_packages = set() @@ -158,7 +165,7 @@ try: framework: fr.Framework = framework row = [current_sha, current_date, - framework.name, framework.package_pattern] + framework.name, ", ".join(sorted(framework.package_pattern.split(" ")))] sources = 0 sinks = 0 diff --git a/misc/scripts/library-coverage/utils.py b/misc/scripts/library-coverage/utils.py index b0a55b536d4..b016903cb3d 100644 --- a/misc/scripts/library-coverage/utils.py +++ b/misc/scripts/library-coverage/utils.py @@ -8,7 +8,16 @@ import sys def subprocess_run(cmd): """Runs a command through subprocess.run, with a few tweaks. Raises an Exception if exit code != 0.""" print(shlex.join(cmd)) - return subprocess.run(cmd, capture_output=True, text=True, env=os.environ.copy(), check=True) + try: + ret = subprocess.run(cmd, capture_output=True, + text=True, env=os.environ.copy(), check=True) + if (ret.stdout): + print(ret.stdout) + return ret + except subprocess.CalledProcessError as e: + if (e.stderr): + print(e.stderr) + raise e def subprocess_check_output(cmd): @@ -17,14 +26,23 @@ def subprocess_check_output(cmd): return subprocess.check_output(cmd, text=True, env=os.environ.copy()) -def create_empty_database(lang, extension, database): +def create_empty_database(lang, extension, database, dbscheme=None): """Creates an empty database for the given language.""" subprocess_run(["codeql", "database", "init", "--language=" + lang, "--source-root=/tmp/empty", "--allow-missing-source-root", database]) subprocess_run(["mkdir", "-p", database + "/src/tmp/empty"]) subprocess_run(["touch", database + "/src/tmp/empty/empty" + extension]) - subprocess_run(["codeql", "database", "finalize", - database, "--no-pre-finalize"]) + + finalize_cmd = ["codeql", "database", "finalize", + database, "--no-pre-finalize"] + if dbscheme is not None: + for scheme in dbscheme: + if os.path.exists(scheme): + finalize_cmd.append("--dbscheme") + finalize_cmd.append(scheme) + break + + subprocess_run(finalize_cmd) def run_codeql_query(query, database, output, search_path): @@ -38,11 +56,12 @@ def run_codeql_query(query, database, output, search_path): class LanguageConfig: - def __init__(self, lang, capitalized_lang, ext, ql_path): + def __init__(self, lang, capitalized_lang, ext, ql_path, dbscheme=None): self.lang = lang self.capitalized_lang = capitalized_lang self.ext = ext self.ql_path = ql_path + self.dbscheme = dbscheme def read_cwes(path): diff --git a/python/change-notes/2021-07-16-deprecate-importnode.md b/python/change-notes/2021-07-16-deprecate-importnode.md new file mode 100644 index 00000000000..4acd1243943 --- /dev/null +++ b/python/change-notes/2021-07-16-deprecate-importnode.md @@ -0,0 +1,4 @@ +lgtm,codescanning +* The `importNode` predicate from the data-flow library has been deprecated. In its place, we + recommend using the API graphs library, accessible via `import semmle.python.ApiGraphs`. + \ No newline at end of file diff --git a/python/change-notes/2021-08-30-port-modifying-default-query.md b/python/change-notes/2021-08-30-port-modifying-default-query.md new file mode 100644 index 00000000000..2fcd9a11ded --- /dev/null +++ b/python/change-notes/2021-08-30-port-modifying-default-query.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Updated _Modification of parameter with default_ (`py/modification-of-default-value`) query to use the new data flow library instead of the old taint tracking library and to remove the use of points-to analysis. You may see differences in the results found by the query, but overall this change should result in a more robust and accurate analysis. diff --git a/python/change-notes/2021-09-02-add-Flask-SQLAlchemy-modeling.md b/python/change-notes/2021-09-02-add-Flask-SQLAlchemy-modeling.md new file mode 100644 index 00000000000..82c7dce9cfd --- /dev/null +++ b/python/change-notes/2021-09-02-add-Flask-SQLAlchemy-modeling.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Added modeling of SQL execution in the `Flask-SQLAlchemy` PyPI package, resulting in additional sinks for the SQL Injection query (`py/sql-injection`). diff --git a/python/change-notes/2021-09-02-add-SQLAlchemy-modeling.md b/python/change-notes/2021-09-02-add-SQLAlchemy-modeling.md new file mode 100644 index 00000000000..9ba7a72614b --- /dev/null +++ b/python/change-notes/2021-09-02-add-SQLAlchemy-modeling.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Added modeling of SQL execution in the `SQLAlchemy` PyPI package, resulting in additional sinks for the SQL Injection query (`py/sql-injection`). This modeling was originally [submitted as a contribution by @mrthankyou](https://github.com/github/codeql/pull/5680). diff --git a/python/change-notes/2021-09-02-add-SQLAlchemyTextClauseInjection.md b/python/change-notes/2021-09-02-add-SQLAlchemyTextClauseInjection.md new file mode 100644 index 00000000000..fec1e75e9a8 --- /dev/null +++ b/python/change-notes/2021-09-02-add-SQLAlchemyTextClauseInjection.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Expanded the query _SQL query built from user-controlled sources_ (`py/sql-injection`) to alert if user-input is added to a TextClause from SQLAlchemy, since that can lead to SQL injection. diff --git a/python/change-notes/2021-09-08-add-flow-from-default-values.md b/python/change-notes/2021-09-08-add-flow-from-default-values.md new file mode 100644 index 00000000000..8a65028216c --- /dev/null +++ b/python/change-notes/2021-09-08-add-flow-from-default-values.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Function parameters with default values will now see flow from those values. diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll index 96c1df9fa8a..62afe4ef865 100644 --- a/python/ql/lib/semmle/python/ApiGraphs.qll +++ b/python/ql/lib/semmle/python/ApiGraphs.qll @@ -142,7 +142,7 @@ module API { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -424,13 +424,8 @@ module API { * a value in the module `m`. */ private predicate possible_builtin_defined_in_module(string name, Module m) { - exists(NameNode n | - not exists(LocalVariable v | n.defines(v)) and - n.isStore() and - name = n.getId() and - name = getBuiltInName() and - m = n.getEnclosingModule() - ) + global_name_defined_in_module(name, m) and + name = getBuiltInName() } /** @@ -445,6 +440,51 @@ module API { m = n.getEnclosingModule() } + /** + * Holds if `n` is an access of a variable called `name` (which is _not_ the name of a + * built-in, and which is _not_ a global defined in the enclosing module) inside the scope `s`. + */ + private predicate name_possibly_defined_in_import_star(NameNode n, string name, Scope s) { + n.isLoad() and + name = n.getId() and + // Not already defined in an enclosing scope. + not exists(LocalVariable v | + v.getId() = name and v.getScope() = n.getScope().getEnclosingScope*() + ) and + not name = getBuiltInName() and + s = n.getScope().getEnclosingScope*() and + exists(potential_import_star_base(s)) and + not global_name_defined_in_module(name, n.getEnclosingModule()) + } + + /** Holds if a global variable called `name` is assigned a value in the module `m`. */ + private predicate global_name_defined_in_module(string name, Module m) { + exists(NameNode n | + not exists(LocalVariable v | n.defines(v)) and + n.isStore() and + name = n.getId() and + m = n.getEnclosingModule() + ) + } + + /** + * Gets the API graph node for all modules imported with `from ... import *` inside the scope `s`. + * + * For example, given + * + * `from foo.bar import *` + * + * this would be the API graph node with the path + * + * `moduleImport("foo").getMember("bar")` + */ + private TApiNode potential_import_star_base(Scope s) { + exists(DataFlow::Node ref | + ref.asCfgNode() = any(ImportStarNode n | n.getScope() = s).getModule() and + use(result, ref) + ) + } + /** * Holds if `ref` is a use of a node that should have an incoming edge from `base` labeled * `lbl` in the API graph. @@ -487,6 +527,15 @@ module API { // Built-ins, treated as members of the module `builtins` base = MkModuleImport("builtins") and lbl = Label::member(any(string name | ref = likely_builtin(name))) + or + // Unknown variables that may belong to a module imported with `import *` + exists(Scope s | + base = potential_import_star_base(s) and + lbl = + Label::member(any(string name | + name_possibly_defined_in_import_star(ref.asCfgNode(), name, s) + )) + ) } /** diff --git a/python/ql/lib/semmle/python/Comment.qll b/python/ql/lib/semmle/python/Comment.qll index 94dd429e404..24810b418ac 100644 --- a/python/ql/lib/semmle/python/Comment.qll +++ b/python/ql/lib/semmle/python/Comment.qll @@ -67,7 +67,7 @@ class CommentBlock extends @py_comment { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/lib/semmle/python/Files.qll b/python/ql/lib/semmle/python/Files.qll index 4fa94f46ac6..66dfca681cc 100644 --- a/python/ql/lib/semmle/python/Files.qll +++ b/python/ql/lib/semmle/python/Files.qll @@ -1,9 +1,7 @@ import python /** A file */ -class File extends Container { - File() { files(this, _, _, _, _) } - +class File extends Container, @file { /** DEPRECATED: Use `getAbsolutePath` instead. */ deprecated override string getName() { result = this.getAbsolutePath() } @@ -15,7 +13,7 @@ class File extends Container { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -34,9 +32,7 @@ class File extends Container { } /** Gets a short name for this file (just the file name) */ - string getShortName() { - exists(string simple, string ext | files(this, _, simple, ext, _) | result = simple + ext) - } + string getShortName() { result = this.getBaseName() } private int lastLine() { result = max(int i | exists(Location l | l.getFile() = this and l.getEndLine() = i)) @@ -55,7 +51,7 @@ class File extends Container { ) } - override string getAbsolutePath() { files(this, result, _, _, _) } + override string getAbsolutePath() { files(this, result) } /** Gets the URL of this file. */ override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" } @@ -118,21 +114,16 @@ private predicate occupied_line(File f, int n) { } /** A folder (directory) */ -class Folder extends Container { - Folder() { folders(this, _, _) } - +class Folder extends Container, @folder { /** DEPRECATED: Use `getAbsolutePath` instead. */ deprecated override string getName() { result = this.getAbsolutePath() } - /** DEPRECATED: Use `getBaseName` instead. */ - deprecated string getSimple() { folders(this, _, result) } - /** * Holds if this element is at the specified location. * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -144,7 +135,7 @@ class Folder extends Container { endcolumn = 0 } - override string getAbsolutePath() { folders(this, result, _) } + override string getAbsolutePath() { folders(this, result) } /** Gets the URL of this folder. */ override string getURL() { result = "folder://" + this.getAbsolutePath() } @@ -332,7 +323,7 @@ abstract class Container extends @container { /** * Gets a URL representing the location of this container. * - * For more information see [Providing URLs](https://help.semmle.com/QL/learn-ql/ql/locations.html#providing-urls). + * For more information see [Providing URLs](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/#providing-urls). */ abstract string getURL(); @@ -438,7 +429,7 @@ class Location extends @location { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -466,7 +457,7 @@ class Line extends @py_line { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/lib/semmle/python/Flow.qll b/python/ql/lib/semmle/python/Flow.qll index 83a89b053a7..65246927872 100755 --- a/python/ql/lib/semmle/python/Flow.qll +++ b/python/ql/lib/semmle/python/Flow.qll @@ -653,6 +653,8 @@ class DefinitionNode extends ControlFlowNode { DefinitionNode() { exists(Assign a | a.getATarget().getAFlowNode() = this) or + exists(AnnAssign a | a.getTarget().getAFlowNode() = this and exists(a.getValue())) + or exists(Alias a | a.getAsname().getAFlowNode() = this) or augstore(_, this) @@ -795,6 +797,9 @@ private AstNode assigned_value(Expr lhs) { /* lhs = result */ exists(Assign a | a.getATarget() = lhs and result = a.getValue()) or + /* lhs : annotation = result */ + exists(AnnAssign a | a.getTarget() = lhs and result = a.getValue()) + or /* import result as lhs */ exists(Alias a | a.getAsname() = lhs and result = a.getValue()) or @@ -1106,7 +1111,7 @@ class BasicBlock extends @py_flow_node { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/lib/semmle/python/Frameworks.qll b/python/ql/lib/semmle/python/Frameworks.qll index c6499e13508..b3ff235c3ee 100644 --- a/python/ql/lib/semmle/python/Frameworks.qll +++ b/python/ql/lib/semmle/python/Frameworks.qll @@ -13,6 +13,7 @@ private import semmle.python.frameworks.Dill private import semmle.python.frameworks.Django private import semmle.python.frameworks.Fabric private import semmle.python.frameworks.Flask +private import semmle.python.frameworks.FlaskSqlAlchemy private import semmle.python.frameworks.Idna private import semmle.python.frameworks.Invoke private import semmle.python.frameworks.Jmespath @@ -20,13 +21,14 @@ private import semmle.python.frameworks.MarkupSafe private import semmle.python.frameworks.Multidict private import semmle.python.frameworks.Mysql private import semmle.python.frameworks.MySQLdb +private import semmle.python.frameworks.Peewee private import semmle.python.frameworks.Psycopg2 private import semmle.python.frameworks.PyMySQL private import semmle.python.frameworks.Rsa private import semmle.python.frameworks.Simplejson +private import semmle.python.frameworks.SqlAlchemy private import semmle.python.frameworks.Stdlib private import semmle.python.frameworks.Tornado -private import semmle.python.frameworks.Peewee private import semmle.python.frameworks.Twisted private import semmle.python.frameworks.Ujson private import semmle.python.frameworks.Yaml diff --git a/python/ql/lib/semmle/python/Function.qll b/python/ql/lib/semmle/python/Function.qll index 2c09188ccb1..acaca8655ad 100644 --- a/python/ql/lib/semmle/python/Function.qll +++ b/python/ql/lib/semmle/python/Function.qll @@ -58,6 +58,7 @@ class Function extends Function_, Scope, AstNode { /** Gets the name of the nth argument (for simple arguments) */ string getArgName(int index) { result = this.getArg(index).(Name).getId() } + /** Gets the parameter of this function with the name `name`. */ Parameter getArgByName(string name) { ( result = this.getAnArg() diff --git a/python/ql/lib/semmle/python/GuardedControlFlow.qll b/python/ql/lib/semmle/python/GuardedControlFlow.qll index 37ecfee37d5..73ea183850a 100644 --- a/python/ql/lib/semmle/python/GuardedControlFlow.qll +++ b/python/ql/lib/semmle/python/GuardedControlFlow.qll @@ -9,6 +9,7 @@ class ConditionBlock extends BasicBlock { } /** Basic blocks controlled by this condition, i.e. those BBs for which the condition is testIsTrue */ + pragma[nomagic] predicate controls(BasicBlock controlled, boolean testIsTrue) { /* * For this block to control the block 'controlled' with 'testIsTrue' the following must be true: diff --git a/python/ql/lib/semmle/python/Stmts.qll b/python/ql/lib/semmle/python/Stmts.qll index 0aa34c2a3fe..56612ef7283 100644 --- a/python/ql/lib/semmle/python/Stmts.qll +++ b/python/ql/lib/semmle/python/Stmts.qll @@ -153,6 +153,12 @@ class ExceptStmt extends ExceptStmt_ { override Stmt getASubStatement() { result = this.getAStmt() } override Stmt getLastStatement() { result = this.getBody().getLastItem().getLastStatement() } + + override Expr getType() { + result = super.getType() and not result instanceof Tuple + or + result = super.getType().(Tuple).getAnElt() + } } /** An assert statement, such as `assert a == b, "A is not equal to b"` */ diff --git a/python/ql/lib/semmle/python/concepts/CryptoAlgorithms.qll b/python/ql/lib/semmle/python/concepts/CryptoAlgorithms.qll index d9f25b42c9a..a5bfd6696be 100644 --- a/python/ql/lib/semmle/python/concepts/CryptoAlgorithms.qll +++ b/python/ql/lib/semmle/python/concepts/CryptoAlgorithms.qll @@ -28,7 +28,11 @@ private module AlgorithmNames { name = "SHA256" or name = "SHA384" or name = "SHA512" or - name = "SHA3" + name = "SHA3" or + name = "SHA3224" or + name = "SHA3256" or + name = "SHA3384" or + name = "SHA3512" } predicate isWeakHashingAlgorithm(string name) { diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll index 5c2dbb30084..4ca06c93362 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll index 5c2dbb30084..4ca06c93362 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll index 5c2dbb30084..4ca06c93362 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll index 5c2dbb30084..4ca06c93362 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -923,28 +923,29 @@ private module Stage2 { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } - class Cc = boolean; + class Cc = CallContext; - class CcCall extends Cc { - CcCall() { this = true } + class CcCall = CallContextCall; - /** Holds if this call context may be `call`. */ - predicate matchesCall(DataFlowCall call) { any() } - } + class CcNoCall = CallContextNoCall; - class CcNoCall extends Cc { - CcNoCall() { this = false } - } - - Cc ccNone() { result = false } + Cc ccNone() { result instanceof CallContextAny } private class LocalCc = Unit; bindingset[call, c, outercc] - private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() } + private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { + checkCallContextCall(outercc, call, c) and + if recordDataFlowCallSiteDispatch(call, c) + then result = TSpecificCall(call) + else result = TSomeCall() + } bindingset[call, c, innercc] - private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() } + private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { + checkCallContextReturn(innercc, c, call) and + if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone() + } bindingset[node, cc, config] private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() } @@ -1172,7 +1173,8 @@ private module Stage2 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -1860,7 +1862,8 @@ private module Stage3 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2117,7 +2120,7 @@ private module Stage3 { private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) { exists(AccessPathFront apf | Stage3::revFlow(node, true, _, apf, config) and - Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config) + Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config) ) } @@ -2136,7 +2139,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and - tupleLimit < (tails - 1) * nodes + tupleLimit < (tails - 1) * nodes and + not tc.forceHighPrecision() ) } @@ -2618,7 +2622,8 @@ private module Stage4 { fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap, pragma[only_bind_into](config)) and fwdFlowOutFromArg(call, out, argAp0, ap, config) and - fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0, + fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc), + pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0), pragma[only_bind_into](config)) ) } @@ -2969,12 +2974,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) { * expected to be expensive. Holds with `unfold = true` otherwise. */ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) { - exists(int aps, int nodes, int apLimit, int tupleLimit | - aps = countPotentialAps(apa, config) and - nodes = countNodesUsingAccessPath(apa, config) and - accessPathCostLimits(apLimit, tupleLimit) and - if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true - ) + if apa.getHead().forceHighPrecision() + then unfold = true + else + exists(int aps, int nodes, int apLimit, int tupleLimit | + aps = countPotentialAps(apa, config) and + nodes = countNodesUsingAccessPath(apa, config) and + accessPathCostLimits(apLimit, tupleLimit) and + if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true + ) } /** @@ -3244,7 +3252,7 @@ class PathNode extends TPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -3258,24 +3266,16 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private predicate isHidden() { - hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and - not this.isSource() and - not this instanceof PathNodeSink - or - this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead - } - private PathNode getASuccessorIfHidden() { - this.isHidden() and + this.(PathNodeImpl).isHidden() and result = this.(PathNodeImpl).getASuccessorImpl() } /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.isHidden() and - not result.isHidden() + not this.(PathNodeImpl).isHidden() and + not result.(PathNodeImpl).isHidden() } /** Holds if this node is a source. */ @@ -3287,6 +3287,14 @@ abstract private class PathNodeImpl extends PathNode { abstract NodeEx getNodeEx(); + predicate isHidden() { + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof PathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + } + private string ppAp() { this instanceof PathNodeSink and result = "" or @@ -3313,10 +3321,15 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) } +private predicate directReach(PathNode n) { + n instanceof PathNodeSink or directReach(n.getASuccessor()) +} -/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) } +/** Holds if `n` can reach a sink or is used in a subpath. */ +private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } + +/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ +private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3325,12 +3338,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { reach(n) and key = "semmle.label" and val = n.toString() } + + query predicate subpaths = Subpaths::subpaths/4; } /** @@ -3622,6 +3637,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c ) } +private module Subpaths { + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths01( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and + pathIntoCallable(arg, par, _, innercc, sc, _) and + paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, + unbindConf(arg.getConfiguration())) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by + * `kind`, `sc`, `apout`, and `innercc`. + */ + pragma[nomagic] + private predicate subpaths02( + PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, + NodeEx out, AccessPath apout + ) { + subpaths01(arg, par, sc, innercc, kind, out, apout) and + out.asNode() = kind.getAnOutNode(_) + } + + pragma[nomagic] + private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + */ + pragma[nomagic] + private predicate subpaths03( + PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout + ) { + exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | + subpaths02(arg, par, sc, innercc, kind, out, apout) and + ret.getNodeEx() = retnode and + kind = retnode.getKind() and + innercc = ret.getCallContext() and + sc = ret.getSummaryCtx() and + ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and + apout = ret.getAp() and + not ret.isHidden() + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) { + exists(ParamNodeEx p, NodeEx o, AccessPath apout | + pragma[only_bind_into](arg).getASuccessor() = par and + pragma[only_bind_into](arg).getASuccessor() = out and + subpaths03(arg, p, ret, o, apout) and + par.getNodeEx() = p and + out.getNodeEx() = o and + out.getAp() = apout + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath. + */ + predicate retReach(PathNode n) { + subpaths(_, _, n, _) + or + exists(PathNode mid | + retReach(mid) and + n.getASuccessor() = mid and + not subpaths(_, mid, _, _) + ) + } +} + /** * Holds if data can flow (inter-procedurally) from `source` to `sink`. * @@ -3941,7 +4037,7 @@ private module FlowExploration { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll index 728f7b56c42..f43a550af57 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll @@ -786,13 +786,18 @@ private module Cached { } /** - * Holds if the call context `call` either improves virtual dispatch in - * `callable` or if it allows us to prune unreachable nodes in `callable`. + * Holds if the call context `call` improves virtual dispatch in `callable`. */ cached - predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) { + predicate recordDataFlowCallSiteDispatch(DataFlowCall call, DataFlowCallable callable) { reducedViableImplInCallContext(_, callable, call) - or + } + + /** + * Holds if the call context `call` allows us to prune unreachable nodes in `callable`. + */ + cached + predicate recordDataFlowCallSiteUnreachable(DataFlowCall call, DataFlowCallable callable) { exists(Node n | getNodeEnclosingCallable(n) = callable | isUnreachableInCallCached(n, call)) } @@ -846,6 +851,15 @@ private module Cached { TAccessPathFrontSome(AccessPathFront apf) } +/** + * Holds if the call context `call` either improves virtual dispatch in + * `callable` or if it allows us to prune unreachable nodes in `callable`. + */ +predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) { + recordDataFlowCallSiteDispatch(call, callable) or + recordDataFlowCallSiteUnreachable(call, callable) +} + /** * A `Node` at which a cast can occur such that the type should be checked. */ @@ -1222,6 +1236,13 @@ class TypedContent extends MkTypedContent { /** Gets a textual representation of this content. */ string toString() { result = c.toString() } + + /** + * Holds if access paths with this `TypedContent` at their head always should + * be tracked at high precision. This disables adaptive access path precision + * for such access paths. + */ + predicate forceHighPrecision() { forceHighPrecision(c) } } /** diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll index e047ee048a9..6598c1fffa8 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll @@ -892,6 +892,9 @@ predicate jumpStep(Node nodeFrom, Node nodeTo) { module_export(mv.getScope(), r.getAttributeName(), nodeFrom) and nodeTo = r ) + or + // Default value for parameter flows to that parameter + defaultValueFlowStep(nodeFrom, nodeTo) } /** @@ -1056,6 +1059,19 @@ predicate kwOverflowStoreStep(CfgNode nodeFrom, DictionaryElementContent c, Node ) } +predicate defaultValueFlowStep(CfgNode nodeFrom, CfgNode nodeTo) { + exists(Function f, Parameter p, ParameterDefinition def | + // `getArgByName` supports, unlike `getAnArg`, keyword-only parameters + p = f.getArgByName(_) and + nodeFrom.asExpr() = p.getDefault() and + // The following expresses + // nodeTo.(ParameterNode).getParameter() = p + // without non-monotonic recursion + def.getParameter() = p and + nodeTo.getNode() = def.getDefiningNode() + ) +} + /** * Holds if data can flow from `nodeFrom` to `nodeTo` via a read of content `c`. */ @@ -1627,6 +1643,12 @@ predicate isImmutableOrUnobservable(Node n) { none() } int accessPathLimit() { result = 5 } +/** + * Holds if access paths with `c` at their head always should be tracked at high + * precision. This disables adaptive access path precision for such access paths. + */ +predicate forceHighPrecision(Content c) { none() } + /** Holds if `n` should be hidden from path explanations. */ predicate nodeIsHidden(Node n) { none() } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll index 928082d7e8a..82be6c5ee46 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll @@ -102,7 +102,7 @@ class Node extends TNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowUtil.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowUtil.qll index 174564db96b..9bdb7ede42c 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowUtil.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowUtil.qll @@ -18,6 +18,10 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFr predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) } /** + * DEPRECATED. Use the API graphs library (`semmle.python.ApiGraphs`) instead. + * + * For a drop-in replacement, use `API::moduleImport(name).getAUse()`. + * * Gets a `Node` that refers to the module referenced by `name`. * Note that for the statement `import pkg.mod`, the new variable introduced is `pkg` that is a * reference to the module `pkg`. @@ -37,7 +41,7 @@ predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) } * `mypkg/foo.py` but the variable `foo` containing `42` -- however, `import mypkg.foo` will always cause `mypkg.foo` * to refer to the module. */ -Node importNode(string name) { +deprecated Node importNode(string name) { exists(Variable var, Import imp, Alias alias | alias = imp.getAName() and alias.getAsname() = var.getAStore() and diff --git a/python/ql/lib/semmle/python/dataflow/old/TaintTracking.qll b/python/ql/lib/semmle/python/dataflow/old/TaintTracking.qll index d6d1f9388c4..e7ee6a3ee08 100755 --- a/python/ql/lib/semmle/python/dataflow/old/TaintTracking.qll +++ b/python/ql/lib/semmle/python/dataflow/old/TaintTracking.qll @@ -384,7 +384,7 @@ abstract class TaintSource extends @py_flow_node { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -498,7 +498,7 @@ abstract class TaintSink extends @py_flow_node { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/lib/semmle/python/frameworks/FlaskSqlAlchemy.qll b/python/ql/lib/semmle/python/frameworks/FlaskSqlAlchemy.qll new file mode 100644 index 00000000000..08ba276e6ce --- /dev/null +++ b/python/ql/lib/semmle/python/frameworks/FlaskSqlAlchemy.qll @@ -0,0 +1,56 @@ +/** + * Provides classes modeling security-relevant aspects of the `Flask-SQLAlchemy` PyPI package + * (imported by `flask_sqlalchemy`). + * See + * - https://pypi.org/project/Flask-SQLAlchemy/ + * - https://flask-sqlalchemy.palletsprojects.com/en/2.x/ + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.dataflow.new.TaintTracking +private import semmle.python.ApiGraphs +private import semmle.python.Concepts +private import semmle.python.frameworks.SqlAlchemy + +/** + * INTERNAL: Do not use. + * + * Provides models for the `Flask-SQLAlchemy` PyPI package (imported by `flask_sqlalchemy`). + * See + * - https://pypi.org/project/Flask-SQLAlchemy/ + * - https://flask-sqlalchemy.palletsprojects.com/en/2.x/ + */ +private module FlaskSqlAlchemy { + /** Gets an instance of `flask_sqlalchemy.SQLAlchemy` */ + private API::Node dbInstance() { + result = API::moduleImport("flask_sqlalchemy").getMember("SQLAlchemy").getReturn() + } + + /** A call to the `text` method on a DB. */ + private class DbTextCall extends SqlAlchemy::TextClause::TextClauseConstruction { + DbTextCall() { this = dbInstance().getMember("text").getACall() } + } + + /** Access on a DB resulting in an Engine */ + private class DbEngine extends SqlAlchemy::Engine::InstanceSource { + DbEngine() { + this = dbInstance().getMember("engine").getAUse() + or + this = dbInstance().getMember("get_engine").getACall() + } + } + + /** Access on a DB resulting in a Session */ + private class DbSession extends SqlAlchemy::Session::InstanceSource { + DbSession() { + this = dbInstance().getMember("session").getAUse() + or + this = dbInstance().getMember("create_session").getReturn().getACall() + or + this = dbInstance().getMember("create_session").getReturn().getMember("begin").getACall() + or + this = dbInstance().getMember("create_scoped_session").getACall() + } + } +} diff --git a/python/ql/lib/semmle/python/frameworks/SqlAlchemy.qll b/python/ql/lib/semmle/python/frameworks/SqlAlchemy.qll new file mode 100644 index 00000000000..a74d44573f7 --- /dev/null +++ b/python/ql/lib/semmle/python/frameworks/SqlAlchemy.qll @@ -0,0 +1,344 @@ +/** + * Provides classes modeling security-relevant aspects of the `SQLAlchemy` PyPI package. + * See + * - https://pypi.org/project/SQLAlchemy/ + * - https://docs.sqlalchemy.org/en/14/index.html + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.dataflow.new.TaintTracking +private import semmle.python.ApiGraphs +private import semmle.python.Concepts +// This import is done like this to avoid importing the deprecated top-level things that +// would pollute the namespace +private import semmle.python.frameworks.PEP249::PEP249 as PEP249 + +/** + * INTERNAL: Do not use. + * + * Provides models for the `SQLAlchemy` PyPI package. + * See + * - https://pypi.org/project/SQLAlchemy/ + * - https://docs.sqlalchemy.org/en/14/index.html + */ +module SqlAlchemy { + /** + * Provides models for the `sqlalchemy.engine.Engine` and `sqlalchemy.future.Engine` classes. + * + * These are so similar that we model both in the same way. + * + * See + * - https://docs.sqlalchemy.org/en/14/core/connections.html#sqlalchemy.engine.Engine + * - https://docs.sqlalchemy.org/en/14/core/future.html#sqlalchemy.future.Engine + */ + module Engine { + /** Gets a reference to a SQLAlchemy Engine class. */ + private API::Node classRef() { + result = API::moduleImport("sqlalchemy").getMember("engine").getMember("Engine") + or + result = API::moduleImport("sqlalchemy").getMember("future").getMember("Engine") + } + + /** + * A source of instances of a SQLAlchemy Engine, extend this class to model new instances. + * + * This can include instantiations of the class, return values from function + * calls, or a special parameter that will be set when functions are called by an external + * library. + * + * Use the predicate `Engine::instance()` to get references to instances of a SQLAlchemy Engine. + */ + abstract class InstanceSource extends DataFlow::LocalSourceNode { } + + private class EngineConstruction extends InstanceSource, DataFlow::CallCfgNode { + EngineConstruction() { + this = classRef().getACall() + or + this = API::moduleImport("sqlalchemy").getMember("create_engine").getACall() + or + this = + API::moduleImport("sqlalchemy").getMember("future").getMember("create_engine").getACall() + or + this.(DataFlow::MethodCallNode).calls(instance(), "execution_options") + } + } + + /** Gets a reference to an instance of a SQLAlchemy Engine. */ + private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) { + t.start() and + result instanceof InstanceSource + or + exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t)) + } + + /** Gets a reference to an instance of a SQLAlchemy Engine. */ + DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } + } + + /** + * Provides models for the `sqlalchemy.engine.base.Connection` and `sqlalchemy.future.Connection` classes. + * + * These are so similar that we model both in the same way. + * + * See + * - https://docs.sqlalchemy.org/en/14/core/connections.html#sqlalchemy.engine.Connection + * - https://docs.sqlalchemy.org/en/14/core/future.html#sqlalchemy.future.Connection + */ + module Connection { + /** Gets a reference to a SQLAlchemy Connection class. */ + private API::Node classRef() { + result = + API::moduleImport("sqlalchemy") + .getMember("engine") + .getMember("base") + .getMember("Connection") + or + result = API::moduleImport("sqlalchemy").getMember("future").getMember("Connection") + } + + /** + * A source of instances of a SQLAlchemy Connection, extend this class to model new instances. + * + * This can include instantiations of the class, return values from function + * calls, or a special parameter that will be set when functions are called by an external + * library. + * + * Use the predicate `Connection::instance()` to get references to instances of a SQLAlchemy Connection. + */ + abstract class InstanceSource extends DataFlow::LocalSourceNode { } + + private class ConnectionConstruction extends InstanceSource, DataFlow::CallCfgNode { + ConnectionConstruction() { + this = classRef().getACall() + or + this.(DataFlow::MethodCallNode).calls(Engine::instance(), ["begin", "connect"]) + or + this.(DataFlow::MethodCallNode).calls(instance(), "connect") + or + this.(DataFlow::MethodCallNode).calls(instance(), "execution_options") + } + } + + /** Gets a reference to an instance of a SQLAlchemy Connection. */ + private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) { + t.start() and + result instanceof InstanceSource + or + exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t)) + } + + /** Gets a reference to an instance of a SQLAlchemy Connection. */ + DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } + } + + /** + * Provides models for the underlying DB-API Connection of a SQLAlchemy Connection. + * + * See https://docs.sqlalchemy.org/en/14/core/connections.html#dbapi-connections. + */ + module DBAPIConnection { + /** + * A source of instances of DB-API Connections, extend this class to model new instances. + * + * This can include instantiations of the class, return values from function + * calls, or a special parameter that will be set when functions are called by an external + * library. + * + * Use the predicate `DBAPIConnection::instance()` to get references to instances of DB-API Connections. + */ + abstract class InstanceSource extends DataFlow::LocalSourceNode { } + + private class DBAPIConnectionSources extends InstanceSource, PEP249::Connection::InstanceSource { + DBAPIConnectionSources() { + this.(DataFlow::MethodCallNode).calls(Engine::instance(), "raw_connection") + or + this.(DataFlow::AttrRead).accesses(Connection::instance(), "connection") + } + } + + /** Gets a reference to an instance of DB-API Connections. */ + private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) { + t.start() and + result instanceof InstanceSource + or + exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t)) + } + + /** Gets a reference to an instance of DB-API Connections. */ + DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } + } + + /** + * Provides models for the `sqlalchemy.orm.Session` class + * + * See + * - https://docs.sqlalchemy.org/en/14/orm/session_api.html#sqlalchemy.orm.Session + * - https://docs.sqlalchemy.org/en/14/orm/session_basics.html + */ + module Session { + /** Gets a reference to the `sqlalchemy.orm.Session` class. */ + private API::Node classRef() { + result = API::moduleImport("sqlalchemy").getMember("orm").getMember("Session") + } + + /** + * A source of instances of `sqlalchemy.orm.Session`, extend this class to model new instances. + * + * This can include instantiations of the class, return values from function + * calls, or a special parameter that will be set when functions are called by an external + * library. + * + * Use the predicate `Session::instance()` to get references to instances of `sqlalchemy.orm.Session`. + */ + abstract class InstanceSource extends DataFlow::LocalSourceNode { } + + private class SessionConstruction extends InstanceSource, DataFlow::CallCfgNode { + SessionConstruction() { + this = classRef().getACall() + or + this = + API::moduleImport("sqlalchemy") + .getMember("orm") + .getMember("sessionmaker") + .getReturn() + .getACall() + or + this = + API::moduleImport("sqlalchemy") + .getMember("orm") + .getMember("sessionmaker") + .getReturn() + .getMember("begin") + .getACall() + } + } + + /** Gets a reference to an instance of `sqlalchemy.orm.Session`. */ + private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) { + t.start() and + result instanceof InstanceSource + or + exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t)) + } + + /** Gets a reference to an instance of `sqlalchemy.orm.Session`. */ + DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } + } + + /** + * A call to `execute` on a SQLAlchemy Engine, Connection, or Session. + * See + * - https://docs.sqlalchemy.org/en/14/core/connections.html#sqlalchemy.engine.Engine.execute + * - https://docs.sqlalchemy.org/en/14/core/connections.html#sqlalchemy.engine.Connection.execute + * - https://docs.sqlalchemy.org/en/14/core/future.html#sqlalchemy.future.Connection.execute + * - https://docs.sqlalchemy.org/en/14/orm/session_api.html#sqlalchemy.orm.Session.execute + */ + private class SqlAlchemyExecuteCall extends DataFlow::MethodCallNode, SqlExecution::Range { + SqlAlchemyExecuteCall() { + this.calls(Engine::instance(), "execute") + or + this.calls(Connection::instance(), "execute") + or + this.calls(Session::instance(), "execute") + } + + override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("statement")] } + } + + /** + * A call to `exec_driver_sql` on a SQLAlchemy Connection. + * See + * - https://docs.sqlalchemy.org/en/14/core/connections.html#sqlalchemy.engine.Connection.exec_driver_sql + * - https://docs.sqlalchemy.org/en/14/core/future.html#sqlalchemy.future.Connection.exec_driver_sql + */ + private class SqlAlchemyExecDriverSqlCall extends DataFlow::MethodCallNode, SqlExecution::Range { + SqlAlchemyExecDriverSqlCall() { this.calls(Connection::instance(), "exec_driver_sql") } + + override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("statement")] } + } + + /** + * A call to `scalar` on a SQLAlchemy Engine, Connection, or Session. + * See + * - https://docs.sqlalchemy.org/en/14/core/connections.html#sqlalchemy.engine.Engine.scalar + * - https://docs.sqlalchemy.org/en/14/core/connections.html#sqlalchemy.engine.Connection.scalar + * - https://docs.sqlalchemy.org/en/14/core/future.html#sqlalchemy.future.Connection.scalar + * - https://docs.sqlalchemy.org/en/14/orm/session_api.html#sqlalchemy.orm.Session.scalar + */ + private class SqlAlchemyScalarCall extends DataFlow::MethodCallNode, SqlExecution::Range { + SqlAlchemyScalarCall() { + this.calls(Engine::instance(), "scalar") + or + this.calls(Connection::instance(), "scalar") + or + this.calls(Session::instance(), "scalar") + } + + override DataFlow::Node getSql() { + result in [this.getArg(0), this.getArgByName("statement"), this.getArgByName("object_")] + } + } + + /** + * Provides models for the `sqlalchemy.sql.expression.TextClause` class, + * which represents a textual SQL string directly. + * + * ```py + * session.query(For14).filter_by(description=sqlalchemy.text(f"'{user_input}'")).all() + * ``` + * + * Initially I wanted to add lots of additional taint steps for such that the normal + * SQL injection query would be able to find cases as the one above where an ORM query + * includes a TextClause that includes user-input directly... But that presented 2 + * problems: + * + * - which part of the query construction above should be marked as SQL to fit our + * `SqlExecution` concept. Nothing really fits this well, since all the SQL + * execution happens under the hood. + * - This would require a LOT of modeling for these additional taint steps, since + * there are many many constructs we would need to have models for. (see the 2 + * examples below) + * + * So instead we extended the SQL injection query to include TextClause construction + * as a sink. And so we don't highlight any parts of an ORM constructed query such as + * these as containing SQL, and don't need the additional taint steps either. + * + * See + * - https://docs.sqlalchemy.org/en/14/core/sqlelement.html#sqlalchemy.sql.expression.TextClause. + * - https://docs.sqlalchemy.org/en/14/core/sqlelement.html#sqlalchemy.sql.expression.text + */ + module TextClause { + /** + * A construction of a `sqlalchemy.sql.expression.TextClause`, which represents a + * textual SQL string directly. + */ + abstract class TextClauseConstruction extends DataFlow::CallCfgNode { + /** Gets the argument that specifies the SQL text. */ + DataFlow::Node getTextArg() { result in [this.getArg(0), this.getArgByName("text")] } + } + + /** `TextClause` constructions from the `sqlalchemy` package. */ + private class DefaultTextClauseConstruction extends TextClauseConstruction { + DefaultTextClauseConstruction() { + this = API::moduleImport("sqlalchemy").getMember("text").getACall() + or + this = API::moduleImport("sqlalchemy").getMember("sql").getMember("text").getACall() + or + this = + API::moduleImport("sqlalchemy") + .getMember("sql") + .getMember("expression") + .getMember("text") + .getACall() + or + this = + API::moduleImport("sqlalchemy") + .getMember("sql") + .getMember("expression") + .getMember("TextClause") + .getACall() + } + } + } +} diff --git a/python/ql/lib/semmle/python/objects/ObjectAPI.qll b/python/ql/lib/semmle/python/objects/ObjectAPI.qll index 683bcc5ce36..946eb1de04d 100644 --- a/python/ql/lib/semmle/python/objects/ObjectAPI.qll +++ b/python/ql/lib/semmle/python/objects/ObjectAPI.qll @@ -79,7 +79,7 @@ class Value extends TObject { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/lib/semmle/python/regex.qll b/python/ql/lib/semmle/python/regex.qll index e57737bd6a2..883d2c3fbc4 100644 --- a/python/ql/lib/semmle/python/regex.qll +++ b/python/ql/lib/semmle/python/regex.qll @@ -773,15 +773,18 @@ abstract class RegexString extends Expr { * string is empty. */ predicate multiples(int start, int end, string lower, string upper) { - this.getChar(start) = "{" and - this.getChar(end - 1) = "}" and - exists(string inner | inner = this.getText().substring(start + 1, end - 1) | - inner.regexpMatch("[0-9]+") and + exists(string text, string match, string inner | + text = this.getText() and + end = start + match.length() and + inner = match.substring(1, match.length() - 1) + | + match = text.regexpFind("\\{[0-9]+\\}", _, start) and lower = inner and upper = lower or - inner.regexpMatch("[0-9]*,[0-9]*") and - exists(int commaIndex | commaIndex = inner.indexOf(",") | + match = text.regexpFind("\\{[0-9]*,[0-9]*\\}", _, start) and + exists(int commaIndex | + commaIndex = inner.indexOf(",") and lower = inner.prefix(commaIndex) and upper = inner.suffix(commaIndex + 1) ) diff --git a/python/ql/lib/semmle/python/security/dataflow/ChainedConfigs12.qll b/python/ql/lib/semmle/python/security/dataflow/ChainedConfigs12.qll index ea2af4f8e8d..241ec52c7d0 100644 --- a/python/ql/lib/semmle/python/security/dataflow/ChainedConfigs12.qll +++ b/python/ql/lib/semmle/python/security/dataflow/ChainedConfigs12.qll @@ -46,7 +46,7 @@ class CustomPathNode extends TCustomPathNode { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll index 186ebd3189d..c132878951f 100644 --- a/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll @@ -9,6 +9,7 @@ private import semmle.python.dataflow.new.DataFlow private import semmle.python.Concepts private import semmle.python.dataflow.new.RemoteFlowSources private import semmle.python.dataflow.new.BarrierGuards +private import semmle.python.frameworks.SqlAlchemy /** * Provides default sources, sinks and sanitizers for detecting @@ -48,6 +49,13 @@ module SqlInjection { SqlExecutionAsSink() { this = any(SqlExecution e).getSql() } } + /** + * The text argument of a SQLAlchemy TextClause construction, considered as a flow sink. + */ + class TextArgAsSink extends Sink { + TextArgAsSink() { this = any(SqlAlchemy::TextClause::TextClauseConstruction tcc).getTextArg() } + } + /** * A comparison with a constant string, considered as a sanitizer-guard. */ diff --git a/python/ql/lib/semmle/python/types/Object.qll b/python/ql/lib/semmle/python/types/Object.qll index a9e360080ce..9b5472af69a 100644 --- a/python/ql/lib/semmle/python/types/Object.qll +++ b/python/ql/lib/semmle/python/types/Object.qll @@ -69,7 +69,7 @@ class Object extends @py_object { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/lib/semmle/python/xml/XML.qll b/python/ql/lib/semmle/python/xml/XML.qll index 5871fed0ddd..4c762f4bf65 100755 --- a/python/ql/lib/semmle/python/xml/XML.qll +++ b/python/ql/lib/semmle/python/xml/XML.qll @@ -24,7 +24,7 @@ class XMLLocatable extends @xmllocatable, TXMLLocatable { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/lib/semmlecode.python.dbscheme b/python/ql/lib/semmlecode.python.dbscheme index 4f1806347d7..ff5327c074c 100644 --- a/python/ql/lib/semmlecode.python.dbscheme +++ b/python/ql/lib/semmlecode.python.dbscheme @@ -120,16 +120,11 @@ svnchurn( Python dbscheme ****************************/ -/* fromSource is ignored */ files(unique int id: @file, - varchar(900) name: string ref, - varchar(900) simple: string ref, - varchar(900) ext: string ref, - int fromSource: int ref); + varchar(900) name: string ref); folders(unique int id: @folder, - varchar(900) name: string ref, - varchar(900) simple: string ref); + varchar(900) name: string ref); @container = @folder | @file; diff --git a/python/ql/lib/semmlecode.python.dbscheme.stats b/python/ql/lib/semmlecode.python.dbscheme.stats index 99fa25b3817..31653bf41a9 100644 --- a/python/ql/lib/semmlecode.python.dbscheme.stats +++ b/python/ql/lib/semmlecode.python.dbscheme.stats @@ -4331,18 +4331,6 @@ name 3066 - -simple -1294 - - -ext -1 - - -fromSource -1 - @@ -4362,54 +4350,6 @@ -id -simple - - -12 - - -1 -2 -3066 - - - - - - -id -ext - - -12 - - -1 -2 -3066 - - - - - - -id -fromSource - - -12 - - -1 -2 -3066 - - - - - - name id @@ -4425,276 +4365,6 @@ - -name -simple - - -12 - - -1 -2 -3066 - - - - - - -name -ext - - -12 - - -1 -2 -3066 - - - - - - -name -fromSource - - -12 - - -1 -2 -3066 - - - - - - -simple -id - - -12 - - -1 -2 -1058 - - -2 -3 -132 - - -3 -38 -98 - - -47 -646 -6 - - - - - - -simple -name - - -12 - - -1 -2 -1058 - - -2 -3 -132 - - -3 -38 -98 - - -47 -646 -6 - - - - - - -simple -ext - - -12 - - -1 -2 -1294 - - - - - - -simple -fromSource - - -12 - - -1 -2 -1294 - - - - - - -ext -id - - -12 - - -3066 -3067 -1 - - - - - - -ext -name - - -12 - - -3066 -3067 -1 - - - - - - -ext -simple - - -12 - - -1294 -1295 -1 - - - - - - -ext -fromSource - - -12 - - -1 -2 -1 - - - - - - -fromSource -id - - -12 - - -3066 -3067 -1 - - - - - - -fromSource -name - - -12 - - -3066 -3067 -1 - - - - - - -fromSource -simple - - -12 - - -1294 -1295 -1 - - - - - - -fromSource -ext - - -12 - - -1 -2 -1 - - - - - @@ -4709,10 +4379,6 @@ name 686 - -simple -538 - @@ -4732,22 +4398,6 @@ -id -simple - - -12 - - -1 -2 -686 - - - - - - name id @@ -4763,74 +4413,6 @@ - -name -simple - - -12 - - -1 -2 -686 - - - - - - -simple -id - - -12 - - -1 -2 -481 - - -2 -4 -45 - - -4 -27 -12 - - - - - - -simple -name - - -12 - - -1 -2 -481 - - -2 -4 -45 - - -4 -27 -12 - - - - - diff --git a/python/ql/src/Functions/ModificationOfParameterWithDefault.ql b/python/ql/src/Functions/ModificationOfParameterWithDefault.ql index 03edc35fa17..9ff89d30e3f 100644 --- a/python/ql/src/Functions/ModificationOfParameterWithDefault.ql +++ b/python/ql/src/Functions/ModificationOfParameterWithDefault.ql @@ -12,88 +12,12 @@ */ import python -import semmle.python.security.Paths +import semmle.python.functions.ModificationOfParameterWithDefault +import DataFlow::PathGraph -predicate safe_method(string name) { - name = "count" or - name = "index" or - name = "copy" or - name = "get" or - name = "has_key" or - name = "items" or - name = "keys" or - name = "values" or - name = "iteritems" or - name = "iterkeys" or - name = "itervalues" or - name = "__contains__" or - name = "__getitem__" or - name = "__getattribute__" -} - -/** Gets the truthiness (non emptyness) of the default of `p` if that value is mutable */ -private boolean mutableDefaultValue(Parameter p) { - exists(Dict d | p.getDefault() = d | - exists(d.getAKey()) and result = true - or - not exists(d.getAKey()) and result = false - ) - or - exists(List l | p.getDefault() = l | - exists(l.getAnElt()) and result = true - or - not exists(l.getAnElt()) and result = false - ) -} - -class NonEmptyMutableValue extends TaintKind { - NonEmptyMutableValue() { this = "non-empty mutable value" } -} - -class EmptyMutableValue extends TaintKind { - EmptyMutableValue() { this = "empty mutable value" } - - override boolean booleanValue() { result = false } -} - -class MutableDefaultValue extends TaintSource { - boolean nonEmpty; - - MutableDefaultValue() { nonEmpty = mutableDefaultValue(this.(NameNode).getNode()) } - - override string toString() { result = "mutable default value" } - - override predicate isSourceOf(TaintKind kind) { - nonEmpty = false and kind instanceof EmptyMutableValue - or - nonEmpty = true and kind instanceof NonEmptyMutableValue - } -} - -private ClassValue mutable_class() { - result = Value::named("list") or - result = Value::named("dict") -} - -class Mutation extends TaintSink { - Mutation() { - exists(AugAssign a | a.getTarget().getAFlowNode() = this) - or - exists(Call c, Attribute a | c.getFunc() = a | - a.getObject().getAFlowNode() = this and - not safe_method(a.getName()) and - this.(ControlFlowNode).pointsTo().getClass() = mutable_class() - ) - } - - override predicate sinks(TaintKind kind) { - kind instanceof EmptyMutableValue - or - kind instanceof NonEmptyMutableValue - } -} - -from TaintedPathSource src, TaintedPathSink sink -where src.flowsTo(sink) -select sink.getSink(), src, sink, "$@ flows to here and is mutated.", src.getSource(), +from + ModificationOfParameterWithDefault::Configuration config, DataFlow::PathNode source, + DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "$@ flows to here and is mutated.", source.getNode(), "Default value" diff --git a/python/ql/src/Lexical/CommentedOutCode.qll b/python/ql/src/Lexical/CommentedOutCode.qll index 97315321a79..f0db1180231 100644 --- a/python/ql/src/Lexical/CommentedOutCode.qll +++ b/python/ql/src/Lexical/CommentedOutCode.qll @@ -197,7 +197,7 @@ class CommentedOutCodeBlock extends @py_comment { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/src/Metrics/Internal/Extents.qll b/python/ql/src/Metrics/Internal/Extents.qll index 1e38a4d544d..9ebe86deb36 100644 --- a/python/ql/src/Metrics/Internal/Extents.qll +++ b/python/ql/src/Metrics/Internal/Extents.qll @@ -20,7 +20,7 @@ class RangeFunction extends Function { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn @@ -40,7 +40,7 @@ class RangeClass extends Class { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/src/Security/CWE-089/SqlInjection.qhelp b/python/ql/src/Security/CWE-089/SqlInjection.qhelp index 63941706e84..05ef88a66e9 100644 --- a/python/ql/src/Security/CWE-089/SqlInjection.qhelp +++ b/python/ql/src/Security/CWE-089/SqlInjection.qhelp @@ -9,6 +9,13 @@ If a database query (such as a SQL or NoSQL query) is built from user-provided data without sufficient sanitization, a user may be able to run malicious database queries.

    + +

    +This also includes using the TextClause class in the +SQLAlchemy PyPI package, +which is used to represent a literal SQL fragment and is inserted directly into the +final SQL when used in a query built using the ORM. +

    @@ -52,5 +59,6 @@ vulnerable to SQL injection attacks. In this example, if username w
  • Wikipedia: SQL injection.
  • OWASP: SQL Injection Prevention Cheat Sheet.
  • +
  • SQLAlchemy documentation for TextClause.
  • diff --git a/python/ql/src/Statements/ModificationOfLocals.ql b/python/ql/src/Statements/ModificationOfLocals.ql index 1a76c38c52e..5a87d60edf2 100644 --- a/python/ql/src/Statements/ModificationOfLocals.ql +++ b/python/ql/src/Statements/ModificationOfLocals.ql @@ -30,5 +30,11 @@ predicate modification_of_locals(ControlFlowNode f) { } from AstNode a, ControlFlowNode f -where modification_of_locals(f) and a = f.getNode() +where + modification_of_locals(f) and + a = f.getNode() and + // in module level scope `locals() == globals()` + // see https://docs.python.org/3/library/functions.html#locals + // FP report in https://github.com/github/codeql/issues/6674 + not a.getScope() instanceof ModuleScope select a, "Modification of the locals() dictionary will have no effect on the local variables." diff --git a/python/ql/src/Variables/UnusedLocalVariable.ql b/python/ql/src/Variables/UnusedLocalVariable.ql index de83345f62d..e52c7fccaff 100644 --- a/python/ql/src/Variables/UnusedLocalVariable.ql +++ b/python/ql/src/Variables/UnusedLocalVariable.ql @@ -19,6 +19,7 @@ predicate unused_local(Name unused, LocalVariable v) { def.getVariable() = v and def.isUnused() and not exists(def.getARedef()) and + not exists(annotation_without_assignment(v)) and def.isRelevant() and not v = any(Nonlocal n).getAVariable() and not exists(def.getNode().getParentNode().(FunctionDef).getDefinedFunction().getADecorator()) and @@ -26,6 +27,17 @@ predicate unused_local(Name unused, LocalVariable v) { ) } +/** + * Gets any annotation of the local variable `v` that does not also reassign its value. + * + * TODO: This predicate should not be needed. Rather, annotated "assignments" that do not actually + * assign a value should not result in the creation of an SSA variable (which then goes unused). + */ +private AnnAssign annotation_without_assignment(LocalVariable v) { + result.getTarget() = v.getAStore() and + not exists(result.getValue()) +} + from Name unused, LocalVariable v where unused_local(unused, v) and diff --git a/python/ql/src/analysis/AlertSuppression.ql b/python/ql/src/analysis/AlertSuppression.ql index c8fefc92cc1..9515c0aad8b 100644 --- a/python/ql/src/analysis/AlertSuppression.ql +++ b/python/ql/src/analysis/AlertSuppression.ql @@ -88,7 +88,7 @@ class SuppressionScope extends @py_comment { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/src/analysis/DefinitionTracking.qll b/python/ql/src/analysis/DefinitionTracking.qll index 72dfb6e849c..b64f131e5bc 100644 --- a/python/ql/src/analysis/DefinitionTracking.qll +++ b/python/ql/src/analysis/DefinitionTracking.qll @@ -477,7 +477,7 @@ class NiceLocationExpr extends @py_expr { * The location spans column `bc` of line `bl` to * column `ec` of line `el` in file `f`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo(string f, int bl, int bc, int el, int ec) { /* Attribute location for x.y is that of 'y' so that url does not overlap with that of 'x' */ diff --git a/python/ql/src/experimental/Security/CWE-522/LDAPInsecureAuth.qhelp b/python/ql/src/experimental/Security/CWE-522/LDAPInsecureAuth.qhelp new file mode 100644 index 00000000000..9033697fd59 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-522/LDAPInsecureAuth.qhelp @@ -0,0 +1,23 @@ + + + + +

    Failing to ensure the utilization of SSL in an LDAP connection can cause the entire communication +to be sent in cleartext making it easier for an attacker to intercept it.

    +
    + + +

    Always set use_SSL to True, call start_tls_s() or set a proper option flag (ldap.OPT_X_TLS_XXXXXX).

    +
    + + +

    This example shows both good and bad ways to deal with this issue under Python 3.

    + +

    The first one sets use_SSL to true as a keyword argument whereas the second one fails to provide a value for it, so +the default one is used (False).

    + +
    + +
    diff --git a/python/ql/src/experimental/Security/CWE-522/LDAPInsecureAuth.ql b/python/ql/src/experimental/Security/CWE-522/LDAPInsecureAuth.ql new file mode 100644 index 00000000000..9f99527a3e3 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-522/LDAPInsecureAuth.ql @@ -0,0 +1,21 @@ +/** + * @name Python Insecure LDAP Authentication + * @description Python LDAP Insecure LDAP Authentication + * @kind path-problem + * @problem.severity error + * @id py/insecure-ldap-auth + * @tags experimental + * security + * external/cwe/cwe-522 + * external/cwe/cwe-523 + */ + +// determine precision above +import python +import DataFlow::PathGraph +import experimental.semmle.python.security.LDAPInsecureAuth + +from LDAPInsecureAuthConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "$@ is authenticated insecurely.", sink.getNode(), + "This LDAP host" diff --git a/python/ql/src/experimental/Security/CWE-522/examples/LDAPInsecureAuth.py b/python/ql/src/experimental/Security/CWE-522/examples/LDAPInsecureAuth.py new file mode 100644 index 00000000000..051ca07b0dc --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-522/examples/LDAPInsecureAuth.py @@ -0,0 +1,20 @@ +from ldap3 import Server, Connection, ALL +from flask import request, Flask + +app = Flask(__name__) + + +@app.route("/good") +def good(): + srv = Server(host, port, use_ssl=True) + conn = Connection(srv, dn, password) + conn.search(dn, search_filter) + return conn.response + + +@app.route("/bad") +def bad(): + srv = Server(host, port) + conn = Connection(srv, dn, password) + conn.search(dn, search_filter) + return conn.response diff --git a/python/ql/src/experimental/Security/CWE-643/xpath.qhelp b/python/ql/src/experimental/Security/CWE-643/XpathInjection.qhelp similarity index 100% rename from python/ql/src/experimental/Security/CWE-643/xpath.qhelp rename to python/ql/src/experimental/Security/CWE-643/XpathInjection.qhelp diff --git a/python/ql/src/experimental/Security/CWE-643/XpathInjection.ql b/python/ql/src/experimental/Security/CWE-643/XpathInjection.ql new file mode 100644 index 00000000000..67b4741f610 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-643/XpathInjection.ql @@ -0,0 +1,33 @@ +/** + * @name XPath query built from user-controlled sources + * @description Building a XPath query from user-controlled sources is vulnerable to insertion of + * malicious Xpath code by the user. + * @kind path-problem + * @problem.severity error + * @precision high + * @id py/xpath-injection + * @tags security + * external/cwe/cwe-643 + */ + +private import python +private import semmle.python.Concepts +private import semmle.python.dataflow.new.TaintTracking +private import semmle.python.Concepts +private import semmle.python.ApiGraphs +private import semmle.python.dataflow.new.RemoteFlowSources +private import semmle.python.dataflow.new.BarrierGuards +import XpathInjection::XpathInjection +import DataFlow::PathGraph + +class XpathInjectionConfiguration extends TaintTracking::Configuration { + XpathInjectionConfiguration() { this = "PathNotNormalizedConfiguration" } + + override predicate isSource(DataFlow::Node source) { source instanceof Source } + + override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } +} + +from XpathInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink, source, sink, "This Xpath query depends on $@.", source, "a user-provided value" diff --git a/python/ql/src/experimental/Security/CWE-643/XpathInjection.qll b/python/ql/src/experimental/Security/CWE-643/XpathInjection.qll new file mode 100644 index 00000000000..e0a0815666a --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-643/XpathInjection.qll @@ -0,0 +1,35 @@ +/** + * Provides a taint-tracking configuration for detecting "Xpath Injection" vulnerabilities. + * + * Note, for performance reasons: only import this file if + * `XpathInjection::Configuration` is needed, otherwise + * `XpathInjectionCustomizations` should be imported instead. + */ + +private import python +import semmle.python.dataflow.new.DataFlow +import semmle.python.dataflow.new.TaintTracking + +/** + * Provides a taint-tracking configuration for detecting "Xpath Injection" vulnerabilities. + */ +module XpathInjection { + import XpathInjectionCustomizations::XpathInjection + + /** + * A taint-tracking configuration for detecting "Xpath Injection" vulnerabilities. + */ + class Configuration extends TaintTracking::Configuration { + Configuration() { this = "Xpath Injection" } + + override predicate isSource(DataFlow::Node source) { source instanceof Source } + + override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } + + override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { + guard instanceof SanitizerGuard + } + } +} diff --git a/python/ql/src/experimental/Security/CWE-643/XpathInjectionCustomizations.qll b/python/ql/src/experimental/Security/CWE-643/XpathInjectionCustomizations.qll new file mode 100644 index 00000000000..4a939253636 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-643/XpathInjectionCustomizations.qll @@ -0,0 +1,105 @@ +/** + * Provides class and predicates to track external data that + * may represent malicious xpath query objects. + * + * This module is intended to be imported into a taint-tracking query. + */ + +private import python +private import semmle.python.Concepts +private import semmle.python.dataflow.new.TaintTracking +private import semmle.python.Concepts +private import semmle.python.ApiGraphs +private import semmle.python.dataflow.new.RemoteFlowSources +private import semmle.python.dataflow.new.BarrierGuards + +/** Models Xpath Injection related classes and functions */ +module XpathInjection { + /** + * A data flow source for "XPath injection" vulnerabilities. + */ + abstract class Source extends DataFlow::Node { } + + /** + * A data flow sink for "XPath injection" vulnerabilities. + */ + abstract class Sink extends DataFlow::Node { } + + /** + * A sanitizer for "XPath injection" vulnerabilities. + */ + abstract class Sanitizer extends DataFlow::Node { } + + /** + * A sanitizer guard for "XPath injection" vulnerabilities. + */ + abstract class SanitizerGuard extends DataFlow::BarrierGuard { } + + /** + * A source of remote user input, considered as a flow source. + */ + class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { } + + /** Returns an API node referring to `lxml.etree` */ + API::Node etree() { result = API::moduleImport("lxml").getMember("etree") } + + /** Returns an API node referring to `lxml.etree` */ + API::Node etreeFromString() { result = etree().getMember("fromstring") } + + /** Returns an API node referring to `lxml.etree.parse` */ + API::Node etreeParse() { result = etree().getMember("parse") } + + /** Returns an API node referring to `lxml.etree.parse` */ + API::Node libxml2parseFile() { result = API::moduleImport("libxml2").getMember("parseFile") } + + /** + * A Sink representing an argument to `etree.XPath` or `etree.ETXPath` call. + * + * from lxml import etree + * root = etree.XML("") + * find_text = etree.XPath("`sink`") + * find_text = etree.ETXPath("`sink`") + */ + private class EtreeXpathArgument extends Sink { + EtreeXpathArgument() { this = etree().getMember(["XPath", "ETXPath"]).getACall().getArg(0) } + } + + /** + * A Sink representing an argument to the `etree.XPath` call. + * + * from lxml import etree + * root = etree.fromstring(file(XML_DB).read(), XMLParser()) + * find_text = root.xpath("`sink`") + */ + private class EtreeFromstringXpathArgument extends Sink { + EtreeFromstringXpathArgument() { + this = etreeFromString().getReturn().getMember("xpath").getACall().getArg(0) + } + } + + /** + * A Sink representing an argument to the `xpath` call to a parsed xml document. + * + * from lxml import etree + * from io import StringIO + * f = StringIO('') + * tree = etree.parse(f) + * r = tree.xpath('`sink`') + */ + private class ParseXpathArgument extends Sink { + ParseXpathArgument() { this = etreeParse().getReturn().getMember("xpath").getACall().getArg(0) } + } + + /** + * A Sink representing an argument to the `xpathEval` call to a parsed libxml2 document. + * + * import libxml2 + * tree = libxml2.parseFile("file.xml") + * r = tree.xpathEval('`sink`') + */ + private class ParseFileXpathEvalArgument extends Sink { + ParseFileXpathEvalArgument() { + this = libxml2parseFile().getReturn().getMember("xpathEval").getACall().getArg(0) + } + } +} diff --git a/python/ql/src/experimental/Security/CWE-643/xpath.ql b/python/ql/src/experimental/Security/CWE-643/xpath.ql deleted file mode 100644 index 15720c408ee..00000000000 --- a/python/ql/src/experimental/Security/CWE-643/xpath.ql +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @name XPath query built from user-controlled sources - * @description Building a XPath query from user-controlled sources is vulnerable to insertion of - * malicious Xpath code by the user. - * @kind path-problem - * @problem.severity error - * @precision high - * @id py/xpath-injection - * @tags security - * external/cwe/cwe-643 - */ - -import python -import semmle.python.security.Paths -import semmle.python.security.strings.Untrusted -/* Sources */ -import semmle.python.web.HttpRequest -/* Sinks */ -import experimental.semmle.python.security.injection.Xpath - -class XpathInjectionConfiguration extends TaintTracking::Configuration { - XpathInjectionConfiguration() { this = "Xpath injection configuration" } - - override predicate isSource(TaintTracking::Source source) { - source instanceof HttpRequestTaintSource - } - - override predicate isSink(TaintTracking::Sink sink) { - sink instanceof XpathInjection::XpathInjectionSink - } -} - -from XpathInjectionConfiguration config, TaintedPathSource src, TaintedPathSink sink -where config.hasFlowPath(src, sink) -select sink.getSink(), src, sink, "This Xpath query depends on $@.", src.getSource(), - "a user-provided value" diff --git a/python/ql/src/experimental/semmle/python/Concepts.qll b/python/ql/src/experimental/semmle/python/Concepts.qll index f87caa88497..18e0a114b59 100644 --- a/python/ql/src/experimental/semmle/python/Concepts.qll +++ b/python/ql/src/experimental/semmle/python/Concepts.qll @@ -156,10 +156,20 @@ module LDAPBind { * extend `LDAPBind` instead. */ abstract class Range extends DataFlow::Node { + /** + * Gets the argument containing the binding host. + */ + abstract DataFlow::Node getHost(); + /** * Gets the argument containing the binding expression. */ abstract DataFlow::Node getPassword(); + + /** + * Holds if the binding process use SSL. + */ + abstract predicate useSSL(); } } @@ -174,7 +184,20 @@ class LDAPBind extends DataFlow::Node { LDAPBind() { this = range } + /** + * Gets the argument containing the binding host. + */ + DataFlow::Node getHost() { result = range.getHost() } + + /** + * Gets the argument containing the binding expression. + */ DataFlow::Node getPassword() { result = range.getPassword() } + + /** + * Holds if the binding process use SSL. + */ + predicate useSSL() { range.useSSL() } } /** Provides classes for modeling SQL sanitization libraries. */ diff --git a/python/ql/src/experimental/semmle/python/frameworks/LDAP.qll b/python/ql/src/experimental/semmle/python/frameworks/LDAP.qll index 83b1accafc1..9286129cf6e 100644 --- a/python/ql/src/experimental/semmle/python/frameworks/LDAP.qll +++ b/python/ql/src/experimental/semmle/python/frameworks/LDAP.qll @@ -88,6 +88,11 @@ private module LDAP { result.(DataFlow::AttrRead).getAttributeName() instanceof LDAP2BindMethods } + /**List of SSL-demanding options */ + private class LDAPSSLOptions extends DataFlow::Node { + LDAPSSLOptions() { this = ldap().getMember("OPT_X_TLS_" + ["DEMAND", "HARD"]).getAUse() } + } + /** * A class to find `ldap` methods binding a connection. * @@ -99,6 +104,44 @@ private module LDAP { override DataFlow::Node getPassword() { result in [this.getArg(1), this.getArgByName("cred")] } + + override DataFlow::Node getHost() { + exists(DataFlow::CallCfgNode initialize | + this.getFunction().(DataFlow::AttrRead).getObject().getALocalSource() = initialize and + initialize = ldapInitialize().getACall() and + result = initialize.getArg(0) + ) + } + + override predicate useSSL() { + // use initialize to correlate `this` and so avoid FP in several instances + exists(DataFlow::CallCfgNode initialize | + // ldap.set_option(ldap.OPT_X_TLS_%s) + ldap().getMember("set_option").getACall().getArg(_) instanceof LDAPSSLOptions + or + this.getFunction().(DataFlow::AttrRead).getObject().getALocalSource() = initialize and + initialize = ldapInitialize().getACall() and + ( + // ldap_connection.start_tls_s() + // see https://www.python-ldap.org/en/python-ldap-3.3.0/reference/ldap.html#ldap.LDAPObject.start_tls_s + exists(DataFlow::MethodCallNode startTLS | + startTLS.getObject().getALocalSource() = initialize and + startTLS.getMethodName() = "start_tls_s" + ) + or + // ldap_connection.set_option(ldap.OPT_X_TLS_%s, True) + exists(DataFlow::CallCfgNode setOption | + setOption.getFunction().(DataFlow::AttrRead).getObject().getALocalSource() = + initialize and + setOption.getFunction().(DataFlow::AttrRead).getAttributeName() = "set_option" and + setOption.getArg(0) instanceof LDAPSSLOptions and + not DataFlow::exprNode(any(False falseExpr)) + .(DataFlow::LocalSourceNode) + .flowsTo(setOption.getArg(1)) + ) + ) + ) + } } /** @@ -166,6 +209,31 @@ private module LDAP { override DataFlow::Node getPassword() { result in [this.getArg(2), this.getArgByName("password")] } + + override DataFlow::Node getHost() { + exists(DataFlow::CallCfgNode serverCall | + serverCall = ldap3Server().getACall() and + this.getArg(0).getALocalSource() = serverCall and + result = serverCall.getArg(0) + ) + } + + override predicate useSSL() { + exists(DataFlow::CallCfgNode serverCall | + serverCall = ldap3Server().getACall() and + this.getArg(0).getALocalSource() = serverCall and + DataFlow::exprNode(any(True trueExpr)) + .(DataFlow::LocalSourceNode) + .flowsTo([serverCall.getArg(2), serverCall.getArgByName("use_ssl")]) + ) + or + // ldap_connection.start_tls_s() + // see https://www.python-ldap.org/en/python-ldap-3.3.0/reference/ldap.html#ldap.LDAPObject.start_tls_s + exists(DataFlow::MethodCallNode startTLS | + startTLS.getMethodName() = "start_tls_s" and + startTLS.getObject().getALocalSource() = this + ) + } } /** diff --git a/python/ql/src/experimental/semmle/python/frameworks/SqlAlchemy.qll b/python/ql/src/experimental/semmle/python/frameworks/SqlAlchemy.qll deleted file mode 100644 index 00d550d9844..00000000000 --- a/python/ql/src/experimental/semmle/python/frameworks/SqlAlchemy.qll +++ /dev/null @@ -1,148 +0,0 @@ -/** - * Provides classes modeling security-relevant aspects of the 'SqlAlchemy' package. - * See https://pypi.org/project/SQLAlchemy/. - */ - -private import python -private import semmle.python.dataflow.new.DataFlow -private import semmle.python.dataflow.new.TaintTracking -private import semmle.python.ApiGraphs -private import semmle.python.Concepts -private import experimental.semmle.python.Concepts - -private module SqlAlchemy { - /** - * Returns an instantization of a SqlAlchemy Session object. - * See https://docs.sqlalchemy.org/en/14/orm/session_api.html#sqlalchemy.orm.Session and - * https://docs.sqlalchemy.org/en/14/orm/session_api.html#sqlalchemy.orm.sessionmaker - */ - private API::Node getSqlAlchemySessionInstance() { - result = API::moduleImport("sqlalchemy.orm").getMember("Session").getReturn() or - result = API::moduleImport("sqlalchemy.orm").getMember("sessionmaker").getReturn().getReturn() - } - - /** - * Returns an instantization of a SqlAlchemy Engine object. - * See https://docs.sqlalchemy.org/en/14/core/engines.html#sqlalchemy.create_engine - */ - private API::Node getSqlAlchemyEngineInstance() { - result = API::moduleImport("sqlalchemy").getMember("create_engine").getReturn() - } - - /** - * Returns an instantization of a SqlAlchemy Query object. - * See https://docs.sqlalchemy.org/en/14/orm/query.html?highlight=query#sqlalchemy.orm.Query - */ - private API::Node getSqlAlchemyQueryInstance() { - result = getSqlAlchemySessionInstance().getMember("query").getReturn() - } - - /** - * A call to `execute` meant to execute an SQL expression - * See the following links: - * - https://docs.sqlalchemy.org/en/14/core/connections.html?highlight=execute#sqlalchemy.engine.Connection.execute - * - https://docs.sqlalchemy.org/en/14/core/connections.html?highlight=execute#sqlalchemy.engine.Engine.execute - * - https://docs.sqlalchemy.org/en/14/orm/session_api.html?highlight=execute#sqlalchemy.orm.Session.execute - */ - private class SqlAlchemyExecuteCall extends DataFlow::CallCfgNode, SqlExecution::Range { - SqlAlchemyExecuteCall() { - // new way - this = getSqlAlchemySessionInstance().getMember("execute").getACall() or - this = - getSqlAlchemyEngineInstance() - .getMember(["connect", "begin"]) - .getReturn() - .getMember("execute") - .getACall() - } - - override DataFlow::Node getSql() { result = this.getArg(0) } - } - - /** - * A call to `scalar` meant to execute an SQL expression - * See https://docs.sqlalchemy.org/en/14/orm/session_api.html#sqlalchemy.orm.Session.scalar and - * https://docs.sqlalchemy.org/en/14/core/connections.html?highlight=scalar#sqlalchemy.engine.Engine.scalar - */ - private class SqlAlchemyScalarCall extends DataFlow::CallCfgNode, SqlExecution::Range { - SqlAlchemyScalarCall() { - this = - [getSqlAlchemySessionInstance(), getSqlAlchemyEngineInstance()] - .getMember("scalar") - .getACall() - } - - override DataFlow::Node getSql() { result = this.getArg(0) } - } - - /** - * A call on a Query object - * See https://docs.sqlalchemy.org/en/14/orm/query.html?highlight=query#sqlalchemy.orm.Query - */ - private class SqlAlchemyQueryCall extends DataFlow::CallCfgNode, SqlExecution::Range { - SqlAlchemyQueryCall() { - this = - getSqlAlchemyQueryInstance() - .getMember(any(SqlAlchemyVulnerableMethodNames methodName)) - .getACall() - } - - override DataFlow::Node getSql() { result = this.getArg(0) } - } - - /** - * This class represents a list of methods vulnerable to sql injection. - * - * See https://github.com/jty-team/codeql/pull/2#issue-611592361 - */ - private class SqlAlchemyVulnerableMethodNames extends string { - SqlAlchemyVulnerableMethodNames() { this in ["filter", "filter_by", "group_by", "order_by"] } - } - - /** - * Additional taint-steps for `sqlalchemy.text()` - * - * See https://docs.sqlalchemy.org/en/14/core/sqlelement.html#sqlalchemy.sql.expression.text - * See https://docs.sqlalchemy.org/en/14/core/sqlelement.html#sqlalchemy.sql.expression.TextClause - */ - class SqlAlchemyTextAdditionalTaintSteps extends TaintTracking::AdditionalTaintStep { - override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - exists(DataFlow::CallCfgNode call | - ( - call = API::moduleImport("sqlalchemy").getMember("text").getACall() - or - call = API::moduleImport("sqlalchemy").getMember("sql").getMember("text").getACall() - or - call = - API::moduleImport("sqlalchemy") - .getMember("sql") - .getMember("expression") - .getMember("text") - .getACall() - or - call = - API::moduleImport("sqlalchemy") - .getMember("sql") - .getMember("expression") - .getMember("TextClause") - .getACall() - ) and - nodeFrom in [call.getArg(0), call.getArgByName("text")] and - nodeTo = call - ) - } - } - - /** - * Gets a reference to `sqlescapy.sqlescape`. - * - * See https://pypi.org/project/sqlescapy/ - */ - class SQLEscapySanitizerCall extends DataFlow::CallCfgNode, SQLEscape::Range { - SQLEscapySanitizerCall() { - this = API::moduleImport("sqlescapy").getMember("sqlescape").getACall() - } - - override DataFlow::Node getAnInput() { result = this.getArg(0) } - } -} diff --git a/python/ql/src/experimental/semmle/python/security/LDAPInsecureAuth.qll b/python/ql/src/experimental/semmle/python/security/LDAPInsecureAuth.qll new file mode 100644 index 00000000000..442a21de30f --- /dev/null +++ b/python/ql/src/experimental/semmle/python/security/LDAPInsecureAuth.qll @@ -0,0 +1,106 @@ +/** + * Provides a taint-tracking configuration for detecting LDAP injection vulnerabilities + */ + +import python +import semmle.python.dataflow.new.DataFlow +import semmle.python.dataflow.new.TaintTracking +import semmle.python.dataflow.new.RemoteFlowSources +import experimental.semmle.python.Concepts + +string getFullHostRegex() { result = "(?i)ldap://.+" } + +string getSchemaRegex() { result = "(?i)ldap(://)?" } + +string getPrivateHostRegex() { + result = + "(?i)localhost(?:[:/?#].*)?|127\\.0\\.0\\.1(?:[:/?#].*)?|10(?:\\.[0-9]+){3}(?:[:/?#].*)?|172\\.16(?:\\.[0-9]+){2}(?:[:/?#].*)?|192.168(?:\\.[0-9]+){2}(?:[:/?#].*)?|\\[?0:0:0:0:0:0:0:1\\]?(?:[:/?#].*)?|\\[?::1\\]?(?:[:/?#].*)?" +} + +// "ldap://somethingon.theinternet.com" +class LDAPFullHost extends StrConst { + LDAPFullHost() { + exists(string s | + s = this.getText() and + s.regexpMatch(getFullHostRegex()) and + // check what comes after the `ldap://` prefix + not s.substring(7, s.length()).regexpMatch(getPrivateHostRegex()) + ) + } +} + +class LDAPSchema extends StrConst { + LDAPSchema() { this.getText().regexpMatch(getSchemaRegex()) } +} + +class LDAPPrivateHost extends StrConst { + LDAPPrivateHost() { this.getText().regexpMatch(getPrivateHostRegex()) } +} + +predicate concatAndCompareAgainstFullHostRegex(LDAPSchema schema, StrConst host) { + not host instanceof LDAPPrivateHost and + (schema.getText() + host.getText()).regexpMatch(getFullHostRegex()) +} + +// "ldap://" + "somethingon.theinternet.com" +class LDAPBothStrings extends BinaryExpr { + LDAPBothStrings() { concatAndCompareAgainstFullHostRegex(this.getLeft(), this.getRight()) } +} + +// schema + host +class LDAPBothVar extends BinaryExpr { + LDAPBothVar() { + exists(SsaVariable schemaVar, SsaVariable hostVar | + this.getLeft() = schemaVar.getVariable().getALoad() and // getAUse is incompatible with Expr + this.getRight() = hostVar.getVariable().getALoad() and + concatAndCompareAgainstFullHostRegex(schemaVar + .getDefinition() + .getImmediateDominator() + .getNode(), hostVar.getDefinition().getImmediateDominator().getNode()) + ) + } +} + +// schema + "somethingon.theinternet.com" +class LDAPVarString extends BinaryExpr { + LDAPVarString() { + exists(SsaVariable schemaVar | + this.getLeft() = schemaVar.getVariable().getALoad() and + concatAndCompareAgainstFullHostRegex(schemaVar + .getDefinition() + .getImmediateDominator() + .getNode(), this.getRight()) + ) + } +} + +// "ldap://" + host +class LDAPStringVar extends BinaryExpr { + LDAPStringVar() { + exists(SsaVariable hostVar | + this.getRight() = hostVar.getVariable().getALoad() and + concatAndCompareAgainstFullHostRegex(this.getLeft(), + hostVar.getDefinition().getImmediateDominator().getNode()) + ) + } +} + +/** + * A taint-tracking configuration for detecting LDAP insecure authentications. + */ +class LDAPInsecureAuthConfig extends TaintTracking::Configuration { + LDAPInsecureAuthConfig() { this = "LDAPInsecureAuthConfig" } + + override predicate isSource(DataFlow::Node source) { + source instanceof RemoteFlowSource or + source.asExpr() instanceof LDAPFullHost or + source.asExpr() instanceof LDAPBothStrings or + source.asExpr() instanceof LDAPBothVar or + source.asExpr() instanceof LDAPVarString or + source.asExpr() instanceof LDAPStringVar + } + + override predicate isSink(DataFlow::Node sink) { + exists(LDAPBind ldapBind | not ldapBind.useSSL() and sink = ldapBind.getHost()) + } +} diff --git a/python/ql/src/experimental/semmle/python/security/injection/Xpath.qll b/python/ql/src/experimental/semmle/python/security/injection/Xpath.qll deleted file mode 100644 index fa5c7647f1f..00000000000 --- a/python/ql/src/experimental/semmle/python/security/injection/Xpath.qll +++ /dev/null @@ -1,115 +0,0 @@ -/** - * Provides class and predicates to track external data that - * may represent malicious xpath query objects. - * - * This module is intended to be imported into a taint-tracking query - * to extend `TaintKind` and `TaintSink`. - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.web.HttpRequest - -/** Models Xpath Injection related classes and functions */ -module XpathInjection { - /** Returns a class value which refers to `lxml.etree` */ - Value etree() { result = Value::named("lxml.etree") } - - /** Returns a class value which refers to `lxml.etree` */ - Value libxml2parseFile() { result = Value::named("libxml2.parseFile") } - - /** A generic taint sink that is vulnerable to Xpath injection. */ - abstract class XpathInjectionSink extends TaintSink { } - - /** - * A Sink representing an argument to the `etree.XPath` call. - * - * from lxml import etree - * root = etree.XML("") - * find_text = etree.XPath("`sink`") - */ - private class EtreeXpathArgument extends XpathInjectionSink { - override string toString() { result = "lxml.etree.XPath" } - - EtreeXpathArgument() { - exists(CallNode call | call.getFunction().(AttrNode).getObject("XPath").pointsTo(etree()) | - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } - } - - /** - * A Sink representing an argument to the `etree.EtXpath` call. - * - * from lxml import etree - * root = etree.XML("") - * find_text = etree.EtXPath("`sink`") - */ - private class EtreeETXpathArgument extends XpathInjectionSink { - override string toString() { result = "lxml.etree.ETXpath" } - - EtreeETXpathArgument() { - exists(CallNode call | call.getFunction().(AttrNode).getObject("ETXPath").pointsTo(etree()) | - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } - } - - /** - * A Sink representing an argument to the `xpath` call to a parsed xml document. - * - * from lxml import etree - * from io import StringIO - * f = StringIO('') - * tree = etree.parse(f) - * r = tree.xpath('`sink`') - */ - private class ParseXpathArgument extends XpathInjectionSink { - override string toString() { result = "lxml.etree.parse.xpath" } - - ParseXpathArgument() { - exists( - CallNode parseCall, CallNode xpathCall, ControlFlowNode obj, Variable var, AssignStmt assign - | - parseCall.getFunction().(AttrNode).getObject("parse").pointsTo(etree()) and - assign.getValue().(Call).getAFlowNode() = parseCall and - xpathCall.getFunction().(AttrNode).getObject("xpath") = obj and - var.getAUse() = obj and - assign.getATarget() = var.getAStore() and - xpathCall.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } - } - - /** - * A Sink representing an argument to the `xpathEval` call to a parsed libxml2 document. - * - * import libxml2 - * tree = libxml2.parseFile("file.xml") - * r = tree.xpathEval('`sink`') - */ - private class ParseFileXpathEvalArgument extends XpathInjectionSink { - override string toString() { result = "libxml2.parseFile.xpathEval" } - - ParseFileXpathEvalArgument() { - exists( - CallNode parseCall, CallNode xpathCall, ControlFlowNode obj, Variable var, AssignStmt assign - | - parseCall.getFunction().(AttrNode).pointsTo(libxml2parseFile()) and - assign.getValue().(Call).getAFlowNode() = parseCall and - xpathCall.getFunction().(AttrNode).getObject("xpathEval") = obj and - var.getAUse() = obj and - assign.getATarget() = var.getAStore() and - xpathCall.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } - } -} diff --git a/python/ql/src/external/DefectFilter.qll b/python/ql/src/external/DefectFilter.qll index 62704b9fd0e..1421c6bb475 100644 --- a/python/ql/src/external/DefectFilter.qll +++ b/python/ql/src/external/DefectFilter.qll @@ -8,7 +8,7 @@ import semmle.python.Files * column `startcol` of line `startline` to column `endcol` of line `endline` * in file `filepath`. * - * For more information, see [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * For more information, see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ external predicate defectResults( int id, string queryPath, string filepath, int startline, int startcol, int endline, int endcol, @@ -54,7 +54,7 @@ class DefectResult extends int { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/src/external/Thrift.qll b/python/ql/src/external/Thrift.qll index f9f8d67701d..8ea9a7dc87f 100644 --- a/python/ql/src/external/Thrift.qll +++ b/python/ql/src/external/Thrift.qll @@ -38,7 +38,7 @@ class ThriftElement extends ExternalData { * The location spans column `startcolumn` of line `startline` to * column `endcolumn` of line `endline` in file `filepath`. * For more information, see - * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ predicate hasLocationInfo( string filepath, int startline, int startcolumn, int endline, int endcolumn diff --git a/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll b/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll new file mode 100644 index 00000000000..24103a33ace --- /dev/null +++ b/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll @@ -0,0 +1,46 @@ +/** + * Provides a data-flow configuration for detecting modifications of a parameters default value. + * + * Note, for performance reasons: only import this file if + * `ModificationOfParameterWithDefault::Configuration` is needed, otherwise + * `ModificationOfParameterWithDefaultCustomizations` should be imported instead. + */ + +private import python +import semmle.python.dataflow.new.DataFlow + +/** + * Provides a data-flow configuration for detecting modifications of a parameters default value. + */ +module ModificationOfParameterWithDefault { + import ModificationOfParameterWithDefaultCustomizations::ModificationOfParameterWithDefault + + /** + * A data-flow configuration for detecting modifications of a parameters default value. + */ + class Configuration extends DataFlow::Configuration { + /** Record whether the default value being tracked is non-empty. */ + boolean nonEmptyDefault; + + Configuration() { + nonEmptyDefault in [true, false] and + this = "ModificationOfParameterWithDefault:" + nonEmptyDefault.toString() + } + + override predicate isSource(DataFlow::Node source) { + source.(Source).isNonEmpty() = nonEmptyDefault + } + + override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + override predicate isBarrier(DataFlow::Node node) { + // if we are tracking a non-empty default, then it is ok to modify empty values, + // so our tracking ends at those. + nonEmptyDefault = true and node instanceof MustBeEmpty + or + // if we are tracking a empty default, then it is ok to modify non-empty values, + // so our tracking ends at those. + nonEmptyDefault = false and node instanceof MustBeNonEmpty + } + } +} diff --git a/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefaultCustomizations.qll b/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefaultCustomizations.qll new file mode 100644 index 00000000000..6abb3f80085 --- /dev/null +++ b/python/ql/src/semmle/python/functions/ModificationOfParameterWithDefaultCustomizations.qll @@ -0,0 +1,190 @@ +/** + * Provides default sources, sinks and sanitizers for detecting + * modifications of a parameters default value, as well as extension points for adding your own. + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.dataflow.new.BarrierGuards + +/** + * Provides default sources, sinks and sanitizers for detecting + * "command injection" + * vulnerabilities, as well as extension points for adding your own. + */ +module ModificationOfParameterWithDefault { + /** + * A data flow source for detecting modifications of a parameters default value, + * that is a default value for some parameter. + */ + abstract class Source extends DataFlow::Node { + /** Result is true if the default value is non-empty for this source and false if not. */ + abstract boolean isNonEmpty(); + } + + /** + * A data flow sink for detecting modifications of a parameters default value, + * that is a node representing a modification. + */ + abstract class Sink extends DataFlow::Node { } + + /** + * A sanitizer for detecting modifications of a parameters default value + * should determine if the node (which is perhaps about to be modified) + * can be the default value or not. + * + * In this query we do not track the default value exactly, but rather wheter + * it is empty or not (see `Source`). + * + * This is the extension point for determining that a node must be empty and + * therefor is allowed to be modified if the tracked default value is non-empty. + */ + abstract class MustBeEmpty extends DataFlow::Node { } + + /** + * A sanitizer for detecting modifications of a parameters default value + * should determine if the node (which is perhaps about to be modified) + * can be the default value or not. + * + * In this query we do not track the default value exactly, but rather wheter + * it is empty or not (see `Source`). + * + * This is the extension point for determining that a node must be non-empty + * and therefor is allowed to be modified if the tracked default value is empty. + */ + abstract class MustBeNonEmpty extends DataFlow::Node { } + + /** Gets the truthiness (non emptyness) of the default of `p` if that value is mutable */ + private boolean mutableDefaultValue(Parameter p) { + exists(Dict d | p.getDefault() = d | + exists(d.getAKey()) and result = true + or + not exists(d.getAKey()) and result = false + ) + or + exists(List l | p.getDefault() = l | + exists(l.getAnElt()) and result = true + or + not exists(l.getAnElt()) and result = false + ) + } + + /** + * A mutable default value for a parameter, considered as a flow source. + */ + class MutableDefaultValue extends Source { + boolean nonEmpty; + + MutableDefaultValue() { nonEmpty = mutableDefaultValue(this.asCfgNode().(NameNode).getNode()) } + + override boolean isNonEmpty() { result = nonEmpty } + } + + /** + * A name of a list function that modifies the list. + * See https://docs.python.org/3/tutorial/datastructures.html#more-on-lists + */ + string list_modifying_method() { + result in ["append", "extend", "insert", "remove", "pop", "clear", "sort", "reverse"] + } + + /** + * A name of a dict function that modifies the dict. + * See https://docs.python.org/3/library/stdtypes.html#dict + */ + string dict_modifying_method() { result in ["clear", "pop", "popitem", "setdefault", "update"] } + + /** + * A mutation of the default value is a flow sink. + * + * Syntactic constructs that modify a list are: + * - s[i] = x + * - s[i:j] = t + * - del s[i:j] + * - s[i:j:k] = t + * - del s[i:j:k] + * - s += t + * - s *= n + * See https://docs.python.org/3/library/stdtypes.html#mutable-sequence-types + * + * Syntactic constructs that modify a dictionary are: + * - d[key] = value + * - del d[key] + * - d |= other + * See https://docs.python.org/3/library/stdtypes.html#dict + * + * These are all covered by: + * - assignment to a subscript (includes slices) + * - deletion of a subscript + * - augmented assignment to the value + */ + class Mutation extends Sink { + Mutation() { + // assignment to a subscript (includes slices) + exists(DefinitionNode d | d.(SubscriptNode).getObject() = this.asCfgNode()) + or + // deletion of a subscript + exists(DeletionNode d | d.getTarget().(SubscriptNode).getObject() = this.asCfgNode()) + or + // augmented assignment to the value + exists(AugAssign a | a.getTarget().getAFlowNode() = this.asCfgNode()) + or + // modifying function call + exists(DataFlow::CallCfgNode c, DataFlow::AttrRead a | c.getFunction() = a | + a.getObject() = this and + a.getAttributeName() in [list_modifying_method(), dict_modifying_method()] + ) + } + } + + // This to reimplement some of the functionality of the DataFlow::BarrierGuard + private import semmle.python.essa.SsaCompute + + /** + * A data-flow node that is known to be either truthy or falsey. + * + * It handles the cases `if x` and `if not x`. + * + * For example, in the following code, `this` will be the `x` that is printed, + * which we will know is truthy: + * + * ```py + * if x: + * print(x) + * ``` + */ + private class MustBe extends DataFlow::Node { + boolean truthy; + + MustBe() { + exists(DataFlow::GuardNode guard, NameNode guarded, boolean branch | + // case: if x + guard = guarded and + branch = truthy + or + // case: if not x + guard.(UnaryExprNode).getNode().getOp() instanceof Not and + guarded = guard.(UnaryExprNode).getOperand() and + branch = truthy.booleanNot() + | + // guard controls this + guard.controlsBlock(this.asCfgNode().getBasicBlock(), branch) and + // there is a definition tying the guarded value to this + exists(EssaDefinition def | + AdjacentUses::useOfDef(def, this.asCfgNode()) and + AdjacentUses::useOfDef(def, guarded) + ) + ) + } + } + + /** Simple guard detecting truthy values. */ + private class MustBeTruthy extends MustBe, MustBeNonEmpty { + MustBeTruthy() { truthy = true } + } + + /** Simple guard detecting falsey values. */ + private class MustBeFalsey extends MustBe, MustBeEmpty { + MustBeFalsey() { truthy = false } + } +} diff --git a/python/ql/test/experimental/dataflow/import-helper/dataflow-consistency.expected b/python/ql/test/experimental/dataflow/ApiGraphs/dataflow-consistency.expected similarity index 100% rename from python/ql/test/experimental/dataflow/import-helper/dataflow-consistency.expected rename to python/ql/test/experimental/dataflow/ApiGraphs/dataflow-consistency.expected diff --git a/python/ql/test/experimental/dataflow/import-helper/dataflow-consistency.ql b/python/ql/test/experimental/dataflow/ApiGraphs/dataflow-consistency.ql similarity index 100% rename from python/ql/test/experimental/dataflow/import-helper/dataflow-consistency.ql rename to python/ql/test/experimental/dataflow/ApiGraphs/dataflow-consistency.ql diff --git a/python/ql/test/experimental/dataflow/ApiGraphs/test.py b/python/ql/test/experimental/dataflow/ApiGraphs/test.py index f4988e41a0f..084ada0e801 100644 --- a/python/ql/test/experimental/dataflow/ApiGraphs/test.py +++ b/python/ql/test/experimental/dataflow/ApiGraphs/test.py @@ -74,12 +74,6 @@ def f(): change_foo() sink(foo) #$ use=moduleImport("danger").getMember("SOURCE") -# Star imports - -from unknown import * #$ use=moduleImport("unknown") - -hello() #$ MISSING: use=moduleImport("unknown").getMember("hello").getReturn() - # Subclasses diff --git a/python/ql/test/experimental/dataflow/ApiGraphs/test_import_star.py b/python/ql/test/experimental/dataflow/ApiGraphs/test_import_star.py new file mode 100644 index 00000000000..7b2934357be --- /dev/null +++ b/python/ql/test/experimental/dataflow/ApiGraphs/test_import_star.py @@ -0,0 +1,36 @@ +# Star imports + +from unknown import * #$ use=moduleImport("unknown") + +# Currently missing, as we do not consider `hello` to be a `LocalSourceNode`, since it has flow +# going into it from its corresponding `GlobalSsaVariable`. +hello() #$ MISSING: use=moduleImport("unknown").getMember("hello").getReturn() + +# We don't want our analysis to think that either `non_module_member` or `outer_bar` can +# come from `from unknown import *` +non_module_member + +outer_bar = 5 +outer_bar + +def foo(): + world() #$ use=moduleImport("unknown").getMember("world").getReturn() + bar = 5 + bar + non_module_member + print(bar) #$ use=moduleImport("builtins").getMember("print").getReturn() + +def quux(): + global non_module_member + non_module_member = 5 + +def func1(): + var() #$ use=moduleImport("unknown").getMember("var").getReturn() + def func2(): + var = "FOO" + +def func3(): + var2 = print #$ use=moduleImport("builtins").getMember("print") + def func4(): + var2() #$ MISSING: use=moduleImport("builtins").getMember("print").getReturn() + func4() diff --git a/python/ql/test/experimental/dataflow/ApiGraphs/test_import_star2.py b/python/ql/test/experimental/dataflow/ApiGraphs/test_import_star2.py new file mode 100644 index 00000000000..a73f1f43548 --- /dev/null +++ b/python/ql/test/experimental/dataflow/ApiGraphs/test_import_star2.py @@ -0,0 +1,15 @@ +# Star imports in local scope + +hello2() + +def foo(): + from unknown2 import * #$ use=moduleImport("unknown2") + world2() #$ use=moduleImport("unknown2").getMember("world2").getReturn() + bar2 = 5 + bar2 + non_module_member2 + print(bar2) #$ use=moduleImport("builtins").getMember("print").getReturn() + +def quux2(): + global non_module_member2 + non_module_member2 = 5 diff --git a/python/ql/test/experimental/dataflow/coverage/argumentPassing.py b/python/ql/test/experimental/dataflow/coverage/argumentPassing.py index cbbac6c0d68..94a9e512313 100644 --- a/python/ql/test/experimental/dataflow/coverage/argumentPassing.py +++ b/python/ql/test/experimental/dataflow/coverage/argumentPassing.py @@ -66,9 +66,9 @@ def argument_passing( b, /, c, - d=arg4, + d=arg4, #$ arg4 func=argument_passing *, - e=arg5, + e=arg5, #$ arg5 func=argument_passing f, **g, ): @@ -120,7 +120,7 @@ def test_multiple_kw_args(): with_multiple_kw_args(**{"b": arg2}, **{"c": arg3}, **{"a": arg1}) #$ arg1 arg2 arg3 func=with_multiple_kw_args -def with_default_arguments(a=arg1, b=arg2, c=arg3): # Need a mechanism to test default arguments +def with_default_arguments(a=arg1, b=arg2, c=arg3): #$ arg1 arg2 arg3 func=with_default_arguments SINK1(a) SINK2(b) SINK3(c) diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRouting1.expected b/python/ql/test/experimental/dataflow/coverage/argumentRouting1.expected index ea80fa74c96..1f00190c5c7 100644 --- a/python/ql/test/experimental/dataflow/coverage/argumentRouting1.expected +++ b/python/ql/test/experimental/dataflow/coverage/argumentRouting1.expected @@ -14,6 +14,8 @@ edges | argumentPassing.py:120:59:120:69 | ControlFlowNode for Dict [Dictionary element at key a] | argumentPassing.py:120:5:120:70 | KwUnpacked a | | argumentPassing.py:120:65:120:68 | ControlFlowNode for arg1 | argumentPassing.py:120:59:120:69 | ControlFlowNode for Dict [Dictionary element at key a] | | argumentPassing.py:123:28:123:28 | ControlFlowNode for a | argumentPassing.py:124:11:124:11 | ControlFlowNode for a | +| argumentPassing.py:123:28:123:28 | ControlFlowNode for a | argumentPassing.py:124:11:124:11 | ControlFlowNode for a | +| argumentPassing.py:123:30:123:33 | ControlFlowNode for arg1 | argumentPassing.py:123:28:123:28 | ControlFlowNode for a | | argumentPassing.py:132:28:132:31 | ControlFlowNode for arg1 | argumentPassing.py:123:28:123:28 | ControlFlowNode for a | | argumentPassing.py:138:22:138:24 | ControlFlowNode for foo | argumentPassing.py:139:11:139:13 | ControlFlowNode for foo | | argumentPassing.py:160:46:160:49 | ControlFlowNode for arg1 | argumentPassing.py:138:22:138:24 | ControlFlowNode for foo | @@ -102,6 +104,8 @@ nodes | argumentPassing.py:120:59:120:69 | ControlFlowNode for Dict [Dictionary element at key a] | semmle.label | ControlFlowNode for Dict [Dictionary element at key a] | | argumentPassing.py:120:65:120:68 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 | | argumentPassing.py:123:28:123:28 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | +| argumentPassing.py:123:28:123:28 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | +| argumentPassing.py:123:30:123:33 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 | | argumentPassing.py:124:11:124:11 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | | argumentPassing.py:132:28:132:31 | ControlFlowNode for arg1 | semmle.label | ControlFlowNode for arg1 | | argumentPassing.py:138:22:138:24 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo | @@ -196,6 +200,7 @@ nodes | classes.py:860:15:860:18 | ControlFlowNode for self | semmle.label | ControlFlowNode for self | | classes.py:866:5:866:11 | SSA variable with_or | semmle.label | SSA variable with_or | | classes.py:868:5:868:11 | ControlFlowNode for with_or | semmle.label | ControlFlowNode for with_or | +subpaths #select | argumentPassing.py:89:22:89:25 | ControlFlowNode for arg1 | argumentPassing.py:89:22:89:25 | ControlFlowNode for arg1 | argumentPassing.py:75:11:75:11 | ControlFlowNode for a | Flow found | | argumentPassing.py:94:22:94:25 | ControlFlowNode for arg1 | argumentPassing.py:94:22:94:25 | ControlFlowNode for arg1 | argumentPassing.py:75:11:75:11 | ControlFlowNode for a | Flow found | @@ -206,6 +211,7 @@ nodes | argumentPassing.py:118:27:118:30 | ControlFlowNode for arg1 | argumentPassing.py:118:27:118:30 | ControlFlowNode for arg1 | argumentPassing.py:110:11:110:11 | ControlFlowNode for a | Flow found | | argumentPassing.py:119:27:119:30 | ControlFlowNode for arg1 | argumentPassing.py:119:27:119:30 | ControlFlowNode for arg1 | argumentPassing.py:110:11:110:11 | ControlFlowNode for a | Flow found | | argumentPassing.py:120:65:120:68 | ControlFlowNode for arg1 | argumentPassing.py:120:65:120:68 | ControlFlowNode for arg1 | argumentPassing.py:110:11:110:11 | ControlFlowNode for a | Flow found | +| argumentPassing.py:123:30:123:33 | ControlFlowNode for arg1 | argumentPassing.py:123:30:123:33 | ControlFlowNode for arg1 | argumentPassing.py:124:11:124:11 | ControlFlowNode for a | Flow found | | argumentPassing.py:132:28:132:31 | ControlFlowNode for arg1 | argumentPassing.py:132:28:132:31 | ControlFlowNode for arg1 | argumentPassing.py:124:11:124:11 | ControlFlowNode for a | Flow found | | argumentPassing.py:160:46:160:49 | ControlFlowNode for arg1 | argumentPassing.py:160:46:160:49 | ControlFlowNode for arg1 | argumentPassing.py:139:11:139:13 | ControlFlowNode for foo | Flow found | | argumentPassing.py:168:14:168:17 | ControlFlowNode for arg1 | argumentPassing.py:168:14:168:17 | ControlFlowNode for arg1 | argumentPassing.py:166:15:166:15 | ControlFlowNode for a | Flow found | diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRouting2.expected b/python/ql/test/experimental/dataflow/coverage/argumentRouting2.expected index b5188b55a9e..ed816d030be 100644 --- a/python/ql/test/experimental/dataflow/coverage/argumentRouting2.expected +++ b/python/ql/test/experimental/dataflow/coverage/argumentRouting2.expected @@ -10,6 +10,8 @@ edges | argumentPassing.py:120:29:120:39 | ControlFlowNode for Dict [Dictionary element at key b] | argumentPassing.py:120:5:120:70 | KwUnpacked b | | argumentPassing.py:120:35:120:38 | ControlFlowNode for arg2 | argumentPassing.py:120:29:120:39 | ControlFlowNode for Dict [Dictionary element at key b] | | argumentPassing.py:123:36:123:36 | ControlFlowNode for b | argumentPassing.py:125:11:125:11 | ControlFlowNode for b | +| argumentPassing.py:123:36:123:36 | ControlFlowNode for b | argumentPassing.py:125:11:125:11 | ControlFlowNode for b | +| argumentPassing.py:123:38:123:41 | ControlFlowNode for arg2 | argumentPassing.py:123:36:123:36 | ControlFlowNode for b | | argumentPassing.py:133:30:133:33 | ControlFlowNode for arg2 | argumentPassing.py:123:36:123:36 | ControlFlowNode for b | | argumentPassing.py:138:29:138:34 | ControlFlowNode for kwargs [Dictionary element at key bar] | argumentPassing.py:140:20:140:25 | ControlFlowNode for kwargs [Dictionary element at key bar] | | argumentPassing.py:140:5:140:26 | KwUnpacked bar | argumentPassing.py:145:18:145:20 | ControlFlowNode for bar | @@ -64,6 +66,8 @@ nodes | argumentPassing.py:120:29:120:39 | ControlFlowNode for Dict [Dictionary element at key b] | semmle.label | ControlFlowNode for Dict [Dictionary element at key b] | | argumentPassing.py:120:35:120:38 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 | | argumentPassing.py:123:36:123:36 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | +| argumentPassing.py:123:36:123:36 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | +| argumentPassing.py:123:38:123:41 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 | | argumentPassing.py:125:11:125:11 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | | argumentPassing.py:133:30:133:33 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 | | argumentPassing.py:138:29:138:34 | ControlFlowNode for kwargs [Dictionary element at key bar] | semmle.label | ControlFlowNode for kwargs [Dictionary element at key bar] | @@ -121,12 +125,14 @@ nodes | classes.py:858:22:858:26 | ControlFlowNode for other | semmle.label | ControlFlowNode for other | | classes.py:859:15:859:19 | ControlFlowNode for other | semmle.label | ControlFlowNode for other | | classes.py:868:15:868:18 | ControlFlowNode for arg2 | semmle.label | ControlFlowNode for arg2 | +subpaths #select | argumentPassing.py:94:28:94:31 | ControlFlowNode for arg2 | argumentPassing.py:94:28:94:31 | ControlFlowNode for arg2 | argumentPassing.py:76:11:76:11 | ControlFlowNode for b | Flow found | | argumentPassing.py:104:25:104:28 | ControlFlowNode for arg2 | argumentPassing.py:104:25:104:28 | ControlFlowNode for arg2 | argumentPassing.py:99:11:99:11 | ControlFlowNode for b | Flow found | | argumentPassing.py:105:27:105:30 | ControlFlowNode for arg2 | argumentPassing.py:105:27:105:30 | ControlFlowNode for arg2 | argumentPassing.py:99:11:99:11 | ControlFlowNode for b | Flow found | | argumentPassing.py:117:29:117:32 | ControlFlowNode for arg2 | argumentPassing.py:117:29:117:32 | ControlFlowNode for arg2 | argumentPassing.py:111:11:111:11 | ControlFlowNode for b | Flow found | | argumentPassing.py:120:35:120:38 | ControlFlowNode for arg2 | argumentPassing.py:120:35:120:38 | ControlFlowNode for arg2 | argumentPassing.py:111:11:111:11 | ControlFlowNode for b | Flow found | +| argumentPassing.py:123:38:123:41 | ControlFlowNode for arg2 | argumentPassing.py:123:38:123:41 | ControlFlowNode for arg2 | argumentPassing.py:125:11:125:11 | ControlFlowNode for b | Flow found | | argumentPassing.py:133:30:133:33 | ControlFlowNode for arg2 | argumentPassing.py:133:30:133:33 | ControlFlowNode for arg2 | argumentPassing.py:125:11:125:11 | ControlFlowNode for b | Flow found | | argumentPassing.py:160:36:160:39 | ControlFlowNode for arg2 | argumentPassing.py:160:36:160:39 | ControlFlowNode for arg2 | argumentPassing.py:146:11:146:13 | ControlFlowNode for bar | Flow found | | classes.py:565:18:565:21 | ControlFlowNode for arg2 | classes.py:565:18:565:21 | ControlFlowNode for arg2 | classes.py:556:15:556:17 | ControlFlowNode for key | Flow found | diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRouting3.expected b/python/ql/test/experimental/dataflow/coverage/argumentRouting3.expected index 0d359646a7e..12f5d39ddbd 100644 --- a/python/ql/test/experimental/dataflow/coverage/argumentRouting3.expected +++ b/python/ql/test/experimental/dataflow/coverage/argumentRouting3.expected @@ -10,6 +10,8 @@ edges | argumentPassing.py:120:44:120:54 | ControlFlowNode for Dict [Dictionary element at key c] | argumentPassing.py:120:5:120:70 | KwUnpacked c | | argumentPassing.py:120:50:120:53 | ControlFlowNode for arg3 | argumentPassing.py:120:44:120:54 | ControlFlowNode for Dict [Dictionary element at key c] | | argumentPassing.py:123:44:123:44 | ControlFlowNode for c | argumentPassing.py:126:11:126:11 | ControlFlowNode for c | +| argumentPassing.py:123:44:123:44 | ControlFlowNode for c | argumentPassing.py:126:11:126:11 | ControlFlowNode for c | +| argumentPassing.py:123:46:123:49 | ControlFlowNode for arg3 | argumentPassing.py:123:44:123:44 | ControlFlowNode for c | | argumentPassing.py:134:5:134:41 | KwUnpacked c | argumentPassing.py:123:44:123:44 | ControlFlowNode for c | | argumentPassing.py:134:30:134:40 | ControlFlowNode for Dict [Dictionary element at key c] | argumentPassing.py:134:5:134:41 | KwUnpacked c | | argumentPassing.py:134:36:134:39 | ControlFlowNode for arg3 | argumentPassing.py:134:30:134:40 | ControlFlowNode for Dict [Dictionary element at key c] | @@ -37,6 +39,8 @@ nodes | argumentPassing.py:120:44:120:54 | ControlFlowNode for Dict [Dictionary element at key c] | semmle.label | ControlFlowNode for Dict [Dictionary element at key c] | | argumentPassing.py:120:50:120:53 | ControlFlowNode for arg3 | semmle.label | ControlFlowNode for arg3 | | argumentPassing.py:123:44:123:44 | ControlFlowNode for c | semmle.label | ControlFlowNode for c | +| argumentPassing.py:123:44:123:44 | ControlFlowNode for c | semmle.label | ControlFlowNode for c | +| argumentPassing.py:123:46:123:49 | ControlFlowNode for arg3 | semmle.label | ControlFlowNode for arg3 | | argumentPassing.py:126:11:126:11 | ControlFlowNode for c | semmle.label | ControlFlowNode for c | | argumentPassing.py:134:5:134:41 | KwUnpacked c | semmle.label | KwUnpacked c | | argumentPassing.py:134:30:134:40 | ControlFlowNode for Dict [Dictionary element at key c] | semmle.label | ControlFlowNode for Dict [Dictionary element at key c] | @@ -53,11 +57,13 @@ nodes | classes.py:570:32:570:36 | ControlFlowNode for value | semmle.label | ControlFlowNode for value | | classes.py:571:15:571:19 | ControlFlowNode for value | semmle.label | ControlFlowNode for value | | classes.py:581:26:581:29 | ControlFlowNode for arg3 | semmle.label | ControlFlowNode for arg3 | +subpaths #select | argumentPassing.py:94:34:94:37 | ControlFlowNode for arg3 | argumentPassing.py:94:34:94:37 | ControlFlowNode for arg3 | argumentPassing.py:77:11:77:11 | ControlFlowNode for c | Flow found | | argumentPassing.py:117:37:117:40 | ControlFlowNode for arg3 | argumentPassing.py:117:37:117:40 | ControlFlowNode for arg3 | argumentPassing.py:112:11:112:11 | ControlFlowNode for c | Flow found | | argumentPassing.py:119:41:119:44 | ControlFlowNode for arg3 | argumentPassing.py:119:41:119:44 | ControlFlowNode for arg3 | argumentPassing.py:112:11:112:11 | ControlFlowNode for c | Flow found | | argumentPassing.py:120:50:120:53 | ControlFlowNode for arg3 | argumentPassing.py:120:50:120:53 | ControlFlowNode for arg3 | argumentPassing.py:112:11:112:11 | ControlFlowNode for c | Flow found | +| argumentPassing.py:123:46:123:49 | ControlFlowNode for arg3 | argumentPassing.py:123:46:123:49 | ControlFlowNode for arg3 | argumentPassing.py:126:11:126:11 | ControlFlowNode for c | Flow found | | argumentPassing.py:134:36:134:39 | ControlFlowNode for arg3 | argumentPassing.py:134:36:134:39 | ControlFlowNode for arg3 | argumentPassing.py:126:11:126:11 | ControlFlowNode for c | Flow found | | argumentPassing.py:160:26:160:29 | ControlFlowNode for arg3 | argumentPassing.py:160:26:160:29 | ControlFlowNode for arg3 | argumentPassing.py:155:11:155:13 | ControlFlowNode for baz | Flow found | | classes.py:581:26:581:29 | ControlFlowNode for arg3 | classes.py:581:26:581:29 | ControlFlowNode for arg3 | classes.py:571:15:571:19 | ControlFlowNode for value | Flow found | diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRouting4.expected b/python/ql/test/experimental/dataflow/coverage/argumentRouting4.expected index 58e3dda0964..23432180c79 100644 --- a/python/ql/test/experimental/dataflow/coverage/argumentRouting4.expected +++ b/python/ql/test/experimental/dataflow/coverage/argumentRouting4.expected @@ -1,3 +1,10 @@ edges +| argumentPassing.py:69:5:69:5 | ControlFlowNode for d | argumentPassing.py:78:11:78:11 | ControlFlowNode for d | +| argumentPassing.py:69:7:69:10 | ControlFlowNode for arg4 | argumentPassing.py:69:5:69:5 | ControlFlowNode for d | nodes +| argumentPassing.py:69:5:69:5 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| argumentPassing.py:69:7:69:10 | ControlFlowNode for arg4 | semmle.label | ControlFlowNode for arg4 | +| argumentPassing.py:78:11:78:11 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +subpaths #select +| argumentPassing.py:69:7:69:10 | ControlFlowNode for arg4 | argumentPassing.py:69:7:69:10 | ControlFlowNode for arg4 | argumentPassing.py:78:11:78:11 | ControlFlowNode for d | Flow found | diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRouting5.expected b/python/ql/test/experimental/dataflow/coverage/argumentRouting5.expected index 58e3dda0964..dea4556c307 100644 --- a/python/ql/test/experimental/dataflow/coverage/argumentRouting5.expected +++ b/python/ql/test/experimental/dataflow/coverage/argumentRouting5.expected @@ -1,3 +1,10 @@ edges +| argumentPassing.py:71:5:71:5 | ControlFlowNode for e | argumentPassing.py:79:11:79:11 | ControlFlowNode for e | +| argumentPassing.py:71:7:71:10 | ControlFlowNode for arg5 | argumentPassing.py:71:5:71:5 | ControlFlowNode for e | nodes +| argumentPassing.py:71:5:71:5 | ControlFlowNode for e | semmle.label | ControlFlowNode for e | +| argumentPassing.py:71:7:71:10 | ControlFlowNode for arg5 | semmle.label | ControlFlowNode for arg5 | +| argumentPassing.py:79:11:79:11 | ControlFlowNode for e | semmle.label | ControlFlowNode for e | +subpaths #select +| argumentPassing.py:71:7:71:10 | ControlFlowNode for arg5 | argumentPassing.py:71:7:71:10 | ControlFlowNode for arg5 | argumentPassing.py:79:11:79:11 | ControlFlowNode for e | Flow found | diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRouting6.expected b/python/ql/test/experimental/dataflow/coverage/argumentRouting6.expected index 58e3dda0964..e217064d1df 100644 --- a/python/ql/test/experimental/dataflow/coverage/argumentRouting6.expected +++ b/python/ql/test/experimental/dataflow/coverage/argumentRouting6.expected @@ -1,3 +1,4 @@ edges nodes +subpaths #select diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRouting7.expected b/python/ql/test/experimental/dataflow/coverage/argumentRouting7.expected index 7f57aa3e435..20e25e0e955 100644 --- a/python/ql/test/experimental/dataflow/coverage/argumentRouting7.expected +++ b/python/ql/test/experimental/dataflow/coverage/argumentRouting7.expected @@ -11,5 +11,6 @@ nodes | argumentPassing.py:89:5:89:81 | KwOverflowNode for argument_passing() [Dictionary element at key g] | semmle.label | KwOverflowNode for argument_passing() [Dictionary element at key g] | | argumentPassing.py:89:59:89:80 | ControlFlowNode for Dict [Dictionary element at key g] | semmle.label | ControlFlowNode for Dict [Dictionary element at key g] | | argumentPassing.py:89:76:89:79 | ControlFlowNode for arg7 | semmle.label | ControlFlowNode for arg7 | +subpaths #select | argumentPassing.py:89:76:89:79 | ControlFlowNode for arg7 | argumentPassing.py:89:76:89:79 | ControlFlowNode for arg7 | argumentPassing.py:82:15:82:20 | ControlFlowNode for Subscript | Flow found | diff --git a/python/ql/test/experimental/dataflow/coverage/dataflow.expected b/python/ql/test/experimental/dataflow/coverage/dataflow.expected index a98fc0b5e2a..68cd9dc50ee 100644 --- a/python/ql/test/experimental/dataflow/coverage/dataflow.expected +++ b/python/ql/test/experimental/dataflow/coverage/dataflow.expected @@ -1,8 +1,16 @@ edges +| datamodel.py:35:7:35:7 | ControlFlowNode for a | datamodel.py:36:10:36:10 | ControlFlowNode for a | +| datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:35:7:35:7 | ControlFlowNode for a | | datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:38:6:38:17 | ControlFlowNode for f() | +| datamodel.py:44:22:44:22 | ControlFlowNode for x | datamodel.py:46:16:46:16 | ControlFlowNode for x | +| datamodel.py:49:26:49:26 | ControlFlowNode for x | datamodel.py:50:16:50:16 | ControlFlowNode for x | +| datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:44:22:44:22 | ControlFlowNode for x | | datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | +| datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:44:22:44:22 | ControlFlowNode for x | | datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | +| datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:49:26:49:26 | ControlFlowNode for x | | datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | +| datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:49:26:49:26 | ControlFlowNode for x | | datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | | datamodel.py:152:5:152:8 | [post store] ControlFlowNode for self [Attribute b] | datamodel.py:155:14:155:25 | ControlFlowNode for Customized() [Attribute b] | | datamodel.py:152:14:152:19 | ControlFlowNode for SOURCE | datamodel.py:152:5:152:8 | [post store] ControlFlowNode for self [Attribute b] | @@ -121,25 +129,49 @@ edges | test.py:353:11:353:16 | ControlFlowNode for SOURCE | test.py:353:10:353:17 | ControlFlowNode for List [List element] | | test.py:357:10:357:22 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:357:10:357:27 | ControlFlowNode for Subscript | | test.py:357:16:357:21 | ControlFlowNode for SOURCE | test.py:357:10:357:22 | ControlFlowNode for Dict [Dictionary element at key s] | +| test.py:375:15:375:15 | ControlFlowNode for b | test.py:376:12:376:12 | ControlFlowNode for b | +| test.py:380:28:380:33 | ControlFlowNode for SOURCE | test.py:375:15:375:15 | ControlFlowNode for b | | test.py:380:28:380:33 | ControlFlowNode for SOURCE | test.py:380:10:380:34 | ControlFlowNode for second() | +| test.py:388:30:388:35 | ControlFlowNode for SOURCE | test.py:375:15:375:15 | ControlFlowNode for b | | test.py:388:30:388:35 | ControlFlowNode for SOURCE | test.py:388:10:388:36 | ControlFlowNode for second() | +| test.py:396:10:396:43 | KwUnpacked b | test.py:375:15:375:15 | ControlFlowNode for b | | test.py:396:10:396:43 | KwUnpacked b | test.py:396:10:396:43 | ControlFlowNode for second() | | test.py:396:30:396:42 | ControlFlowNode for Dict [Dictionary element at key b] | test.py:396:10:396:43 | KwUnpacked b | | test.py:396:36:396:41 | ControlFlowNode for SOURCE | test.py:396:30:396:42 | ControlFlowNode for Dict [Dictionary element at key b] | +| test.py:399:21:399:21 | ControlFlowNode for b [Tuple element at index 0] | test.py:400:12:400:12 | ControlFlowNode for b [Tuple element at index 0] | +| test.py:400:12:400:12 | ControlFlowNode for b [Tuple element at index 0] | test.py:400:12:400:15 | ControlFlowNode for Subscript | +| test.py:404:10:404:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:399:21:399:21 | ControlFlowNode for b [Tuple element at index 0] | | test.py:404:10:404:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:404:10:404:39 | ControlFlowNode for f_extra_pos() | | test.py:404:33:404:38 | ControlFlowNode for SOURCE | test.py:404:10:404:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | +| test.py:407:26:407:26 | ControlFlowNode for b [Dictionary element at key b] | test.py:408:12:408:12 | ControlFlowNode for b [Dictionary element at key b] | +| test.py:408:12:408:12 | ControlFlowNode for b [Dictionary element at key b] | test.py:408:12:408:17 | ControlFlowNode for Subscript | +| test.py:412:10:412:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:407:26:407:26 | ControlFlowNode for b [Dictionary element at key b] | | test.py:412:10:412:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:412:10:412:45 | ControlFlowNode for f_extra_keyword() | | test.py:412:39:412:44 | ControlFlowNode for SOURCE | test.py:412:10:412:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | | test.py:433:10:433:15 | ControlFlowNode for SOURCE | test.py:433:10:433:38 | ControlFlowNode for IfExp | | test.py:441:34:441:39 | ControlFlowNode for SOURCE | test.py:441:10:441:39 | ControlFlowNode for IfExp | +| test.py:462:11:462:11 | ControlFlowNode for x | test.py:463:16:463:16 | ControlFlowNode for x | +| test.py:465:12:465:17 | ControlFlowNode for SOURCE | test.py:462:11:462:11 | ControlFlowNode for x | | test.py:465:12:465:17 | ControlFlowNode for SOURCE | test.py:465:10:465:18 | ControlFlowNode for f() | +| test.py:469:19:469:19 | ControlFlowNode for b | test.py:470:16:470:16 | ControlFlowNode for b | +| test.py:472:28:472:33 | ControlFlowNode for SOURCE | test.py:469:19:469:19 | ControlFlowNode for b | | test.py:472:28:472:33 | ControlFlowNode for SOURCE | test.py:472:10:472:34 | ControlFlowNode for second() | +| test.py:483:19:483:19 | ControlFlowNode for b | test.py:484:16:484:16 | ControlFlowNode for b | +| test.py:486:30:486:35 | ControlFlowNode for SOURCE | test.py:483:19:483:19 | ControlFlowNode for b | | test.py:486:30:486:35 | ControlFlowNode for SOURCE | test.py:486:10:486:36 | ControlFlowNode for second() | +| test.py:497:19:497:19 | ControlFlowNode for b | test.py:498:16:498:16 | ControlFlowNode for b | +| test.py:500:10:500:43 | KwUnpacked b | test.py:497:19:497:19 | ControlFlowNode for b | | test.py:500:10:500:43 | KwUnpacked b | test.py:500:10:500:43 | ControlFlowNode for second() | | test.py:500:30:500:42 | ControlFlowNode for Dict [Dictionary element at key b] | test.py:500:10:500:43 | KwUnpacked b | | test.py:500:36:500:41 | ControlFlowNode for SOURCE | test.py:500:30:500:42 | ControlFlowNode for Dict [Dictionary element at key b] | +| test.py:504:30:504:30 | ControlFlowNode for b [Tuple element at index 0] | test.py:504:33:504:33 | ControlFlowNode for b [Tuple element at index 0] | +| test.py:504:33:504:33 | ControlFlowNode for b [Tuple element at index 0] | test.py:504:33:504:36 | ControlFlowNode for Subscript | +| test.py:505:10:505:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:504:30:504:30 | ControlFlowNode for b [Tuple element at index 0] | | test.py:505:10:505:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:505:10:505:39 | ControlFlowNode for f_extra_pos() | | test.py:505:33:505:38 | ControlFlowNode for SOURCE | test.py:505:10:505:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | +| test.py:509:35:509:35 | ControlFlowNode for b [Dictionary element at key b] | test.py:509:38:509:38 | ControlFlowNode for b [Dictionary element at key b] | +| test.py:509:38:509:38 | ControlFlowNode for b [Dictionary element at key b] | test.py:509:38:509:43 | ControlFlowNode for Subscript | +| test.py:510:10:510:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:509:35:509:35 | ControlFlowNode for b [Dictionary element at key b] | | test.py:510:10:510:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:510:10:510:45 | ControlFlowNode for f_extra_keyword() | | test.py:510:39:510:44 | ControlFlowNode for SOURCE | test.py:510:10:510:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | | test.py:522:9:522:14 | ControlFlowNode for SOURCE | test.py:524:10:524:10 | ControlFlowNode for a | @@ -347,9 +379,21 @@ edges | test.py:686:43:686:48 | ControlFlowNode for SOURCE | test.py:686:3:686:52 | PosOverflowNode for iterate_star_args() [Tuple element at index 0] | | test.py:686:51:686:51 | ControlFlowNode for s | test.py:686:3:686:52 | PosOverflowNode for iterate_star_args() [Tuple element at index 1] | | test.py:757:16:757:21 | ControlFlowNode for SOURCE | test.py:760:10:760:36 | ControlFlowNode for return_from_inner_scope() | +| test.py:795:35:795:35 | ControlFlowNode for x | test.py:796:10:796:10 | ControlFlowNode for x | +| test.py:795:37:795:42 | ControlFlowNode for SOURCE | test.py:795:35:795:35 | ControlFlowNode for x | +| test.py:795:48:795:48 | ControlFlowNode for y | test.py:797:10:797:10 | ControlFlowNode for y | +| test.py:795:50:795:55 | ControlFlowNode for SOURCE | test.py:795:48:795:48 | ControlFlowNode for y | +| test.py:795:61:795:61 | ControlFlowNode for z | test.py:798:10:798:10 | ControlFlowNode for z | +| test.py:795:63:795:68 | ControlFlowNode for SOURCE | test.py:795:61:795:61 | ControlFlowNode for z | nodes +| datamodel.py:35:7:35:7 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | +| datamodel.py:36:10:36:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | | datamodel.py:38:6:38:17 | ControlFlowNode for f() | semmle.label | ControlFlowNode for f() | | datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| datamodel.py:44:22:44:22 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| datamodel.py:46:16:46:16 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| datamodel.py:49:26:49:26 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| datamodel.py:50:16:50:16 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | @@ -501,6 +545,8 @@ nodes | test.py:357:10:357:22 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] | | test.py:357:10:357:27 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | test.py:357:16:357:21 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| test.py:375:15:375:15 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | +| test.py:376:12:376:12 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | | test.py:380:10:380:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() | | test.py:380:28:380:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | | test.py:388:10:388:36 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() | @@ -509,9 +555,15 @@ nodes | test.py:396:10:396:43 | KwUnpacked b | semmle.label | KwUnpacked b | | test.py:396:30:396:42 | ControlFlowNode for Dict [Dictionary element at key b] | semmle.label | ControlFlowNode for Dict [Dictionary element at key b] | | test.py:396:36:396:41 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| test.py:399:21:399:21 | ControlFlowNode for b [Tuple element at index 0] | semmle.label | ControlFlowNode for b [Tuple element at index 0] | +| test.py:400:12:400:12 | ControlFlowNode for b [Tuple element at index 0] | semmle.label | ControlFlowNode for b [Tuple element at index 0] | +| test.py:400:12:400:15 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | test.py:404:10:404:39 | ControlFlowNode for f_extra_pos() | semmle.label | ControlFlowNode for f_extra_pos() | | test.py:404:10:404:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | semmle.label | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | | test.py:404:33:404:38 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| test.py:407:26:407:26 | ControlFlowNode for b [Dictionary element at key b] | semmle.label | ControlFlowNode for b [Dictionary element at key b] | +| test.py:408:12:408:12 | ControlFlowNode for b [Dictionary element at key b] | semmle.label | ControlFlowNode for b [Dictionary element at key b] | +| test.py:408:12:408:17 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | test.py:412:10:412:45 | ControlFlowNode for f_extra_keyword() | semmle.label | ControlFlowNode for f_extra_keyword() | | test.py:412:10:412:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | semmle.label | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | | test.py:412:39:412:44 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | @@ -519,19 +571,33 @@ nodes | test.py:433:10:433:38 | ControlFlowNode for IfExp | semmle.label | ControlFlowNode for IfExp | | test.py:441:10:441:39 | ControlFlowNode for IfExp | semmle.label | ControlFlowNode for IfExp | | test.py:441:34:441:39 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| test.py:462:11:462:11 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| test.py:463:16:463:16 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | | test.py:465:10:465:18 | ControlFlowNode for f() | semmle.label | ControlFlowNode for f() | | test.py:465:12:465:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| test.py:469:19:469:19 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | +| test.py:470:16:470:16 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | | test.py:472:10:472:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() | | test.py:472:28:472:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| test.py:483:19:483:19 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | +| test.py:484:16:484:16 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | | test.py:486:10:486:36 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() | | test.py:486:30:486:35 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| test.py:497:19:497:19 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | +| test.py:498:16:498:16 | ControlFlowNode for b | semmle.label | ControlFlowNode for b | | test.py:500:10:500:43 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() | | test.py:500:10:500:43 | KwUnpacked b | semmle.label | KwUnpacked b | | test.py:500:30:500:42 | ControlFlowNode for Dict [Dictionary element at key b] | semmle.label | ControlFlowNode for Dict [Dictionary element at key b] | | test.py:500:36:500:41 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| test.py:504:30:504:30 | ControlFlowNode for b [Tuple element at index 0] | semmle.label | ControlFlowNode for b [Tuple element at index 0] | +| test.py:504:33:504:33 | ControlFlowNode for b [Tuple element at index 0] | semmle.label | ControlFlowNode for b [Tuple element at index 0] | +| test.py:504:33:504:36 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | test.py:505:10:505:39 | ControlFlowNode for f_extra_pos() | semmle.label | ControlFlowNode for f_extra_pos() | | test.py:505:10:505:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | semmle.label | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | | test.py:505:33:505:38 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| test.py:509:35:509:35 | ControlFlowNode for b [Dictionary element at key b] | semmle.label | ControlFlowNode for b [Dictionary element at key b] | +| test.py:509:38:509:38 | ControlFlowNode for b [Dictionary element at key b] | semmle.label | ControlFlowNode for b [Dictionary element at key b] | +| test.py:509:38:509:43 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | test.py:510:10:510:45 | ControlFlowNode for f_extra_keyword() | semmle.label | ControlFlowNode for f_extra_keyword() | | test.py:510:10:510:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | semmle.label | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | | test.py:510:39:510:44 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | @@ -758,6 +824,32 @@ nodes | test.py:686:51:686:51 | ControlFlowNode for s | semmle.label | ControlFlowNode for s | | test.py:757:16:757:21 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | | test.py:760:10:760:36 | ControlFlowNode for return_from_inner_scope() | semmle.label | ControlFlowNode for return_from_inner_scope() | +| test.py:795:35:795:35 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| test.py:795:37:795:42 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| test.py:795:48:795:48 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | +| test.py:795:50:795:55 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| test.py:795:61:795:61 | ControlFlowNode for z | semmle.label | ControlFlowNode for z | +| test.py:795:63:795:68 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| test.py:796:10:796:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| test.py:797:10:797:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | +| test.py:798:10:798:10 | ControlFlowNode for z | semmle.label | ControlFlowNode for z | +subpaths +| datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:35:7:35:7 | ControlFlowNode for a | datamodel.py:36:10:36:10 | ControlFlowNode for a | datamodel.py:38:6:38:17 | ControlFlowNode for f() | +| datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:44:22:44:22 | ControlFlowNode for x | datamodel.py:46:16:46:16 | ControlFlowNode for x | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | +| datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:44:22:44:22 | ControlFlowNode for x | datamodel.py:46:16:46:16 | ControlFlowNode for x | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | +| datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:49:26:49:26 | ControlFlowNode for x | datamodel.py:50:16:50:16 | ControlFlowNode for x | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | +| datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:49:26:49:26 | ControlFlowNode for x | datamodel.py:50:16:50:16 | ControlFlowNode for x | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | +| test.py:380:28:380:33 | ControlFlowNode for SOURCE | test.py:375:15:375:15 | ControlFlowNode for b | test.py:376:12:376:12 | ControlFlowNode for b | test.py:380:10:380:34 | ControlFlowNode for second() | +| test.py:388:30:388:35 | ControlFlowNode for SOURCE | test.py:375:15:375:15 | ControlFlowNode for b | test.py:376:12:376:12 | ControlFlowNode for b | test.py:388:10:388:36 | ControlFlowNode for second() | +| test.py:396:10:396:43 | KwUnpacked b | test.py:375:15:375:15 | ControlFlowNode for b | test.py:376:12:376:12 | ControlFlowNode for b | test.py:396:10:396:43 | ControlFlowNode for second() | +| test.py:404:10:404:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:399:21:399:21 | ControlFlowNode for b [Tuple element at index 0] | test.py:400:12:400:15 | ControlFlowNode for Subscript | test.py:404:10:404:39 | ControlFlowNode for f_extra_pos() | +| test.py:412:10:412:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:407:26:407:26 | ControlFlowNode for b [Dictionary element at key b] | test.py:408:12:408:17 | ControlFlowNode for Subscript | test.py:412:10:412:45 | ControlFlowNode for f_extra_keyword() | +| test.py:465:12:465:17 | ControlFlowNode for SOURCE | test.py:462:11:462:11 | ControlFlowNode for x | test.py:463:16:463:16 | ControlFlowNode for x | test.py:465:10:465:18 | ControlFlowNode for f() | +| test.py:472:28:472:33 | ControlFlowNode for SOURCE | test.py:469:19:469:19 | ControlFlowNode for b | test.py:470:16:470:16 | ControlFlowNode for b | test.py:472:10:472:34 | ControlFlowNode for second() | +| test.py:486:30:486:35 | ControlFlowNode for SOURCE | test.py:483:19:483:19 | ControlFlowNode for b | test.py:484:16:484:16 | ControlFlowNode for b | test.py:486:10:486:36 | ControlFlowNode for second() | +| test.py:500:10:500:43 | KwUnpacked b | test.py:497:19:497:19 | ControlFlowNode for b | test.py:498:16:498:16 | ControlFlowNode for b | test.py:500:10:500:43 | ControlFlowNode for second() | +| test.py:505:10:505:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:504:30:504:30 | ControlFlowNode for b [Tuple element at index 0] | test.py:504:33:504:36 | ControlFlowNode for Subscript | test.py:505:10:505:39 | ControlFlowNode for f_extra_pos() | +| test.py:510:10:510:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:509:35:509:35 | ControlFlowNode for b [Dictionary element at key b] | test.py:509:38:509:43 | ControlFlowNode for Subscript | test.py:510:10:510:45 | ControlFlowNode for f_extra_keyword() | #select | datamodel.py:38:6:38:17 | ControlFlowNode for f() | datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:38:6:38:17 | ControlFlowNode for f() | Flow found | | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | Flow found | @@ -865,3 +957,6 @@ nodes | test.py:680:10:680:12 | ControlFlowNode for arg | test.py:685:7:685:12 | ControlFlowNode for SOURCE | test.py:680:10:680:12 | ControlFlowNode for arg | Flow found | | test.py:680:10:680:12 | ControlFlowNode for arg | test.py:686:43:686:48 | ControlFlowNode for SOURCE | test.py:680:10:680:12 | ControlFlowNode for arg | Flow found | | test.py:760:10:760:36 | ControlFlowNode for return_from_inner_scope() | test.py:757:16:757:21 | ControlFlowNode for SOURCE | test.py:760:10:760:36 | ControlFlowNode for return_from_inner_scope() | Flow found | +| test.py:796:10:796:10 | ControlFlowNode for x | test.py:795:37:795:42 | ControlFlowNode for SOURCE | test.py:796:10:796:10 | ControlFlowNode for x | Flow found | +| test.py:797:10:797:10 | ControlFlowNode for y | test.py:795:50:795:55 | ControlFlowNode for SOURCE | test.py:797:10:797:10 | ControlFlowNode for y | Flow found | +| test.py:798:10:798:10 | ControlFlowNode for z | test.py:795:63:795:68 | ControlFlowNode for SOURCE | test.py:798:10:798:10 | ControlFlowNode for z | Flow found | diff --git a/python/ql/test/experimental/dataflow/coverage/test.py b/python/ql/test/experimental/dataflow/coverage/test.py index c7d5f063eb9..906ece07952 100644 --- a/python/ql/test/experimental/dataflow/coverage/test.py +++ b/python/ql/test/experimental/dataflow/coverage/test.py @@ -793,6 +793,6 @@ def test_reverse_read_subscript_cls(): @expects(3) def test_with_default_param_value(x=SOURCE, /, y=SOURCE, *, z=SOURCE): - SINK(x) #$ MISSING:flow="SOURCE, l:-1 -> x" - SINK(y) #$ MISSING:flow="SOURCE, l:-2 -> y" - SINK(z) #$ MISSING:flow="SOURCE, l:-3 -> z" + SINK(x) #$ flow="SOURCE, l:-1 -> x" + SINK(y) #$ flow="SOURCE, l:-2 -> y" + SINK(z) #$ flow="SOURCE, l:-3 -> z" diff --git a/python/ql/test/experimental/dataflow/fieldflow/dataflow.expected b/python/ql/test/experimental/dataflow/fieldflow/dataflow.expected index 2301e52f08f..0d988d19909 100644 --- a/python/ql/test/experimental/dataflow/fieldflow/dataflow.expected +++ b/python/ql/test/experimental/dataflow/fieldflow/dataflow.expected @@ -1,5 +1,10 @@ edges +| examples.py:7:24:7:26 | ControlFlowNode for foo | examples.py:8:20:8:22 | ControlFlowNode for foo | +| examples.py:8:20:8:22 | ControlFlowNode for foo | examples.py:8:9:8:12 | [post store] ControlFlowNode for self [Attribute foo] | +| examples.py:20:17:20:17 | ControlFlowNode for x | examples.py:22:15:22:15 | ControlFlowNode for x | +| examples.py:22:15:22:15 | ControlFlowNode for x | examples.py:22:5:22:7 | [post store] ControlFlowNode for obj [Attribute foo] | | examples.py:27:8:27:12 | [post arg] ControlFlowNode for myobj [Attribute foo] | examples.py:28:6:28:10 | ControlFlowNode for myobj [Attribute foo] | +| examples.py:27:15:27:20 | ControlFlowNode for SOURCE | examples.py:20:17:20:17 | ControlFlowNode for x | | examples.py:27:15:27:20 | ControlFlowNode for SOURCE | examples.py:27:8:27:12 | [post arg] ControlFlowNode for myobj [Attribute foo] | | examples.py:28:6:28:10 | ControlFlowNode for myobj [Attribute foo] | examples.py:28:6:28:14 | ControlFlowNode for Attribute | | examples.py:31:5:31:10 | ControlFlowNode for SOURCE | examples.py:35:13:35:13 | ControlFlowNode for x | @@ -9,13 +14,29 @@ edges | examples.py:37:6:37:6 | ControlFlowNode for a [Attribute obj, Attribute foo] | examples.py:37:6:37:10 | ControlFlowNode for Attribute [Attribute foo] | | examples.py:37:6:37:10 | ControlFlowNode for Attribute [Attribute foo] | examples.py:37:6:37:14 | ControlFlowNode for Attribute | | examples.py:49:7:49:19 | ControlFlowNode for MyObj() [Attribute foo] | examples.py:50:6:50:8 | ControlFlowNode for obj [Attribute foo] | +| examples.py:49:13:49:18 | ControlFlowNode for SOURCE | examples.py:7:24:7:26 | ControlFlowNode for foo | | examples.py:49:13:49:18 | ControlFlowNode for SOURCE | examples.py:49:7:49:19 | ControlFlowNode for MyObj() [Attribute foo] | | examples.py:50:6:50:8 | ControlFlowNode for obj [Attribute foo] | examples.py:50:6:50:12 | ControlFlowNode for Attribute | +| examples.py:53:28:53:28 | ControlFlowNode for x | examples.py:54:17:54:17 | ControlFlowNode for x | +| examples.py:54:11:54:18 | ControlFlowNode for MyObj() [Attribute foo] | examples.py:55:9:55:11 | ControlFlowNode for obj [Attribute foo] | +| examples.py:54:17:54:17 | ControlFlowNode for x | examples.py:7:24:7:26 | ControlFlowNode for foo | +| examples.py:54:17:54:17 | ControlFlowNode for x | examples.py:54:11:54:18 | ControlFlowNode for MyObj() [Attribute foo] | +| examples.py:55:9:55:11 | ControlFlowNode for obj [Attribute foo] | examples.py:55:9:55:15 | ControlFlowNode for Attribute | +| examples.py:55:9:55:15 | ControlFlowNode for Attribute | examples.py:56:12:56:12 | ControlFlowNode for a | +| examples.py:59:29:59:34 | ControlFlowNode for SOURCE | examples.py:53:28:53:28 | ControlFlowNode for x | | examples.py:59:29:59:34 | ControlFlowNode for SOURCE | examples.py:59:6:59:35 | ControlFlowNode for fields_with_local_flow() | +| test.py:26:24:26:26 | ControlFlowNode for foo | test.py:27:20:27:22 | ControlFlowNode for foo | +| test.py:27:20:27:22 | ControlFlowNode for foo | test.py:27:9:27:12 | [post store] ControlFlowNode for self [Attribute foo] | +| test.py:29:22:29:24 | ControlFlowNode for foo | test.py:30:20:30:22 | ControlFlowNode for foo | +| test.py:30:20:30:22 | ControlFlowNode for foo | test.py:30:9:30:12 | [post store] ControlFlowNode for self [Attribute foo] | +| test.py:41:17:41:17 | ControlFlowNode for x | test.py:43:15:43:15 | ControlFlowNode for x | +| test.py:43:15:43:15 | ControlFlowNode for x | test.py:43:5:43:7 | [post store] ControlFlowNode for obj [Attribute foo] | | test.py:49:12:49:16 | [post arg] ControlFlowNode for myobj [Attribute foo] | test.py:50:10:50:14 | ControlFlowNode for myobj [Attribute foo] | +| test.py:49:19:49:24 | ControlFlowNode for SOURCE | test.py:41:17:41:17 | ControlFlowNode for x | | test.py:49:19:49:24 | ControlFlowNode for SOURCE | test.py:49:12:49:16 | [post arg] ControlFlowNode for myobj [Attribute foo] | | test.py:50:10:50:14 | ControlFlowNode for myobj [Attribute foo] | test.py:50:10:50:18 | ControlFlowNode for Attribute | | test.py:56:5:56:9 | [post read] ControlFlowNode for myobj [Attribute foo] | test.py:57:10:57:14 | ControlFlowNode for myobj [Attribute foo] | +| test.py:56:18:56:23 | ControlFlowNode for SOURCE | test.py:29:22:29:24 | ControlFlowNode for foo | | test.py:56:18:56:23 | ControlFlowNode for SOURCE | test.py:56:5:56:9 | [post read] ControlFlowNode for myobj [Attribute foo] | | test.py:57:10:57:14 | ControlFlowNode for myobj [Attribute foo] | test.py:57:10:57:18 | ControlFlowNode for Attribute | | test.py:61:9:61:14 | ControlFlowNode for SOURCE | test.py:65:17:65:17 | ControlFlowNode for x | @@ -31,13 +52,28 @@ edges | test.py:77:10:77:10 | ControlFlowNode for a [Attribute obj, Attribute foo] | test.py:77:10:77:14 | ControlFlowNode for Attribute [Attribute foo] | | test.py:77:10:77:14 | ControlFlowNode for Attribute [Attribute foo] | test.py:77:10:77:18 | ControlFlowNode for Attribute | | test.py:81:11:81:23 | ControlFlowNode for MyObj() [Attribute foo] | test.py:82:10:82:12 | ControlFlowNode for obj [Attribute foo] | +| test.py:81:17:81:22 | ControlFlowNode for SOURCE | test.py:26:24:26:26 | ControlFlowNode for foo | | test.py:81:17:81:22 | ControlFlowNode for SOURCE | test.py:81:11:81:23 | ControlFlowNode for MyObj() [Attribute foo] | | test.py:82:10:82:12 | ControlFlowNode for obj [Attribute foo] | test.py:82:10:82:16 | ControlFlowNode for Attribute | | test.py:86:11:86:27 | ControlFlowNode for MyObj() [Attribute foo] | test.py:87:10:87:12 | ControlFlowNode for obj [Attribute foo] | +| test.py:86:21:86:26 | ControlFlowNode for SOURCE | test.py:26:24:26:26 | ControlFlowNode for foo | | test.py:86:21:86:26 | ControlFlowNode for SOURCE | test.py:86:11:86:27 | ControlFlowNode for MyObj() [Attribute foo] | | test.py:87:10:87:12 | ControlFlowNode for obj [Attribute foo] | test.py:87:10:87:16 | ControlFlowNode for Attribute | +| test.py:90:28:90:28 | ControlFlowNode for x | test.py:91:17:91:17 | ControlFlowNode for x | +| test.py:91:11:91:18 | ControlFlowNode for MyObj() [Attribute foo] | test.py:92:9:92:11 | ControlFlowNode for obj [Attribute foo] | +| test.py:91:17:91:17 | ControlFlowNode for x | test.py:26:24:26:26 | ControlFlowNode for foo | +| test.py:91:17:91:17 | ControlFlowNode for x | test.py:91:11:91:18 | ControlFlowNode for MyObj() [Attribute foo] | +| test.py:92:9:92:11 | ControlFlowNode for obj [Attribute foo] | test.py:92:9:92:15 | ControlFlowNode for Attribute | +| test.py:92:9:92:15 | ControlFlowNode for Attribute | test.py:93:12:93:12 | ControlFlowNode for a | +| test.py:97:33:97:38 | ControlFlowNode for SOURCE | test.py:90:28:90:28 | ControlFlowNode for x | | test.py:97:33:97:38 | ControlFlowNode for SOURCE | test.py:97:10:97:39 | ControlFlowNode for fields_with_local_flow() | nodes +| examples.py:7:24:7:26 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo | +| examples.py:8:9:8:12 | [post store] ControlFlowNode for self [Attribute foo] | semmle.label | [post store] ControlFlowNode for self [Attribute foo] | +| examples.py:8:20:8:22 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo | +| examples.py:20:17:20:17 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| examples.py:22:5:22:7 | [post store] ControlFlowNode for obj [Attribute foo] | semmle.label | [post store] ControlFlowNode for obj [Attribute foo] | +| examples.py:22:15:22:15 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | | examples.py:27:8:27:12 | [post arg] ControlFlowNode for myobj [Attribute foo] | semmle.label | [post arg] ControlFlowNode for myobj [Attribute foo] | | examples.py:27:15:27:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | | examples.py:28:6:28:10 | ControlFlowNode for myobj [Attribute foo] | semmle.label | ControlFlowNode for myobj [Attribute foo] | @@ -53,8 +89,23 @@ nodes | examples.py:49:13:49:18 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | | examples.py:50:6:50:8 | ControlFlowNode for obj [Attribute foo] | semmle.label | ControlFlowNode for obj [Attribute foo] | | examples.py:50:6:50:12 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| examples.py:53:28:53:28 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| examples.py:54:11:54:18 | ControlFlowNode for MyObj() [Attribute foo] | semmle.label | ControlFlowNode for MyObj() [Attribute foo] | +| examples.py:54:17:54:17 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| examples.py:55:9:55:11 | ControlFlowNode for obj [Attribute foo] | semmle.label | ControlFlowNode for obj [Attribute foo] | +| examples.py:55:9:55:15 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| examples.py:56:12:56:12 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | | examples.py:59:6:59:35 | ControlFlowNode for fields_with_local_flow() | semmle.label | ControlFlowNode for fields_with_local_flow() | | examples.py:59:29:59:34 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +| test.py:26:24:26:26 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo | +| test.py:27:9:27:12 | [post store] ControlFlowNode for self [Attribute foo] | semmle.label | [post store] ControlFlowNode for self [Attribute foo] | +| test.py:27:20:27:22 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo | +| test.py:29:22:29:24 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo | +| test.py:30:9:30:12 | [post store] ControlFlowNode for self [Attribute foo] | semmle.label | [post store] ControlFlowNode for self [Attribute foo] | +| test.py:30:20:30:22 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo | +| test.py:41:17:41:17 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| test.py:43:5:43:7 | [post store] ControlFlowNode for obj [Attribute foo] | semmle.label | [post store] ControlFlowNode for obj [Attribute foo] | +| test.py:43:15:43:15 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | | test.py:49:12:49:16 | [post arg] ControlFlowNode for myobj [Attribute foo] | semmle.label | [post arg] ControlFlowNode for myobj [Attribute foo] | | test.py:49:19:49:24 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | | test.py:50:10:50:14 | ControlFlowNode for myobj [Attribute foo] | semmle.label | ControlFlowNode for myobj [Attribute foo] | @@ -85,8 +136,25 @@ nodes | test.py:86:21:86:26 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | | test.py:87:10:87:12 | ControlFlowNode for obj [Attribute foo] | semmle.label | ControlFlowNode for obj [Attribute foo] | | test.py:87:10:87:16 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:90:28:90:28 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| test.py:91:11:91:18 | ControlFlowNode for MyObj() [Attribute foo] | semmle.label | ControlFlowNode for MyObj() [Attribute foo] | +| test.py:91:17:91:17 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| test.py:92:9:92:11 | ControlFlowNode for obj [Attribute foo] | semmle.label | ControlFlowNode for obj [Attribute foo] | +| test.py:92:9:92:15 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| test.py:93:12:93:12 | ControlFlowNode for a | semmle.label | ControlFlowNode for a | | test.py:97:10:97:39 | ControlFlowNode for fields_with_local_flow() | semmle.label | ControlFlowNode for fields_with_local_flow() | | test.py:97:33:97:38 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE | +subpaths +| examples.py:27:15:27:20 | ControlFlowNode for SOURCE | examples.py:20:17:20:17 | ControlFlowNode for x | examples.py:22:5:22:7 | [post store] ControlFlowNode for obj [Attribute foo] | examples.py:27:8:27:12 | [post arg] ControlFlowNode for myobj [Attribute foo] | +| examples.py:49:13:49:18 | ControlFlowNode for SOURCE | examples.py:7:24:7:26 | ControlFlowNode for foo | examples.py:8:9:8:12 | [post store] ControlFlowNode for self [Attribute foo] | examples.py:49:7:49:19 | ControlFlowNode for MyObj() [Attribute foo] | +| examples.py:54:17:54:17 | ControlFlowNode for x | examples.py:7:24:7:26 | ControlFlowNode for foo | examples.py:8:9:8:12 | [post store] ControlFlowNode for self [Attribute foo] | examples.py:54:11:54:18 | ControlFlowNode for MyObj() [Attribute foo] | +| examples.py:59:29:59:34 | ControlFlowNode for SOURCE | examples.py:53:28:53:28 | ControlFlowNode for x | examples.py:56:12:56:12 | ControlFlowNode for a | examples.py:59:6:59:35 | ControlFlowNode for fields_with_local_flow() | +| test.py:49:19:49:24 | ControlFlowNode for SOURCE | test.py:41:17:41:17 | ControlFlowNode for x | test.py:43:5:43:7 | [post store] ControlFlowNode for obj [Attribute foo] | test.py:49:12:49:16 | [post arg] ControlFlowNode for myobj [Attribute foo] | +| test.py:56:18:56:23 | ControlFlowNode for SOURCE | test.py:29:22:29:24 | ControlFlowNode for foo | test.py:30:9:30:12 | [post store] ControlFlowNode for self [Attribute foo] | test.py:56:5:56:9 | [post read] ControlFlowNode for myobj [Attribute foo] | +| test.py:81:17:81:22 | ControlFlowNode for SOURCE | test.py:26:24:26:26 | ControlFlowNode for foo | test.py:27:9:27:12 | [post store] ControlFlowNode for self [Attribute foo] | test.py:81:11:81:23 | ControlFlowNode for MyObj() [Attribute foo] | +| test.py:86:21:86:26 | ControlFlowNode for SOURCE | test.py:26:24:26:26 | ControlFlowNode for foo | test.py:27:9:27:12 | [post store] ControlFlowNode for self [Attribute foo] | test.py:86:11:86:27 | ControlFlowNode for MyObj() [Attribute foo] | +| test.py:91:17:91:17 | ControlFlowNode for x | test.py:26:24:26:26 | ControlFlowNode for foo | test.py:27:9:27:12 | [post store] ControlFlowNode for self [Attribute foo] | test.py:91:11:91:18 | ControlFlowNode for MyObj() [Attribute foo] | +| test.py:97:33:97:38 | ControlFlowNode for SOURCE | test.py:90:28:90:28 | ControlFlowNode for x | test.py:93:12:93:12 | ControlFlowNode for a | test.py:97:10:97:39 | ControlFlowNode for fields_with_local_flow() | #select | examples.py:28:6:28:14 | ControlFlowNode for Attribute | examples.py:27:15:27:20 | ControlFlowNode for SOURCE | examples.py:28:6:28:14 | ControlFlowNode for Attribute | Flow found | | examples.py:37:6:37:14 | ControlFlowNode for Attribute | examples.py:31:5:31:10 | ControlFlowNode for SOURCE | examples.py:37:6:37:14 | ControlFlowNode for Attribute | Flow found | diff --git a/python/ql/test/experimental/dataflow/import-helper/ImportHelper.expected b/python/ql/test/experimental/dataflow/import-helper/ImportHelper.expected deleted file mode 100644 index 11608b04ab8..00000000000 --- a/python/ql/test/experimental/dataflow/import-helper/ImportHelper.expected +++ /dev/null @@ -1,23 +0,0 @@ -| test1.py:1:8:1:12 | ControlFlowNode for ImportExpr | mypkg | -| test2.py:1:6:1:10 | ControlFlowNode for ImportExpr | mypkg | -| test2.py:1:6:1:10 | ControlFlowNode for ImportExpr | mypkg | -| test2.py:1:19:1:21 | ControlFlowNode for ImportMember | mypkg.foo | -| test2.py:1:24:1:26 | ControlFlowNode for ImportMember | mypkg.bar | -| test3.py:1:8:1:16 | ControlFlowNode for ImportExpr | mypkg | -| test3.py:2:8:2:16 | ControlFlowNode for ImportExpr | mypkg | -| test4.py:1:8:1:16 | ControlFlowNode for ImportExpr | mypkg.foo | -| test4.py:2:8:2:16 | ControlFlowNode for ImportExpr | mypkg.bar | -| test5.py:1:8:1:12 | ControlFlowNode for ImportExpr | mypkg | -| test5.py:9:6:9:10 | ControlFlowNode for ImportExpr | mypkg | -| test5.py:9:19:9:29 | ControlFlowNode for ImportMember | mypkg.bar | -| test6.py:1:8:1:12 | ControlFlowNode for ImportExpr | mypkg | -| test6.py:5:8:5:16 | ControlFlowNode for ImportExpr | mypkg | -| test7.py:1:6:1:10 | ControlFlowNode for ImportExpr | mypkg | -| test7.py:1:19:1:21 | ControlFlowNode for ImportMember | mypkg.foo | -| test7.py:5:8:5:16 | ControlFlowNode for ImportExpr | mypkg | -| test7.py:9:6:9:10 | ControlFlowNode for ImportExpr | mypkg | -| test7.py:9:19:9:21 | ControlFlowNode for ImportMember | mypkg.foo | -| test_deep.py:1:6:1:21 | ControlFlowNode for ImportExpr | start.middle.end | -| test_deep.py:1:6:1:21 | ControlFlowNode for ImportExpr | start.middle.end | -| test_deep.py:1:30:1:32 | ControlFlowNode for ImportMember | start.middle.end.foo | -| test_deep.py:1:35:1:37 | ControlFlowNode for ImportMember | start.middle.end.bar | diff --git a/python/ql/test/experimental/dataflow/import-helper/ImportHelper.ql b/python/ql/test/experimental/dataflow/import-helper/ImportHelper.ql deleted file mode 100644 index 0af7d88d87d..00000000000 --- a/python/ql/test/experimental/dataflow/import-helper/ImportHelper.ql +++ /dev/null @@ -1,4 +0,0 @@ -import python -import semmle.python.dataflow.new.DataFlow - -query predicate importNode(DataFlow::Node res, string name) { res = DataFlow::importNode(name) } diff --git a/python/ql/test/experimental/dataflow/import-helper/README.md b/python/ql/test/experimental/dataflow/import-helper/README.md deleted file mode 100644 index bcee9b620db..00000000000 --- a/python/ql/test/experimental/dataflow/import-helper/README.md +++ /dev/null @@ -1 +0,0 @@ -Small tests that explore difference between `import mypkg.foo` and `from mypkg import foo`. diff --git a/python/ql/test/experimental/dataflow/import-helper/mypkg/__init__.py b/python/ql/test/experimental/dataflow/import-helper/mypkg/__init__.py deleted file mode 100644 index c84a9b135a3..00000000000 --- a/python/ql/test/experimental/dataflow/import-helper/mypkg/__init__.py +++ /dev/null @@ -1 +0,0 @@ -foo = 42 diff --git a/python/ql/test/experimental/dataflow/import-helper/mypkg/bar.py b/python/ql/test/experimental/dataflow/import-helper/mypkg/bar.py deleted file mode 100644 index 2ae28399f5f..00000000000 --- a/python/ql/test/experimental/dataflow/import-helper/mypkg/bar.py +++ /dev/null @@ -1 +0,0 @@ -pass diff --git a/python/ql/test/experimental/dataflow/import-helper/mypkg/foo.py b/python/ql/test/experimental/dataflow/import-helper/mypkg/foo.py deleted file mode 100644 index 2ae28399f5f..00000000000 --- a/python/ql/test/experimental/dataflow/import-helper/mypkg/foo.py +++ /dev/null @@ -1 +0,0 @@ -pass diff --git a/python/ql/test/experimental/dataflow/import-helper/test1.py b/python/ql/test/experimental/dataflow/import-helper/test1.py deleted file mode 100644 index fa4d1464942..00000000000 --- a/python/ql/test/experimental/dataflow/import-helper/test1.py +++ /dev/null @@ -1,6 +0,0 @@ -import mypkg -print(mypkg.foo) # 42 -try: - print(mypkg.bar) -except AttributeError as e: - print(e) # module 'mypkg' has no attribute 'bar' diff --git a/python/ql/test/experimental/dataflow/import-helper/test2.py b/python/ql/test/experimental/dataflow/import-helper/test2.py deleted file mode 100644 index a706d61fd0c..00000000000 --- a/python/ql/test/experimental/dataflow/import-helper/test2.py +++ /dev/null @@ -1,3 +0,0 @@ -from mypkg import foo, bar -print(foo) -print(bar) diff --git a/python/ql/test/experimental/dataflow/import-helper/test3.py b/python/ql/test/experimental/dataflow/import-helper/test3.py deleted file mode 100644 index 4fc602432c2..00000000000 --- a/python/ql/test/experimental/dataflow/import-helper/test3.py +++ /dev/null @@ -1,4 +0,0 @@ -import mypkg.foo -import mypkg.bar -print(mypkg.foo) # " + +# also has engine/session instantiated + +raw_sql = "SELECT 'Foo'" + +conn = db.engine.connect() +result = conn.execute(raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("Foo",)] + +conn = db.get_engine().connect() +result = conn.execute(raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("Foo",)] + +result = db.session.execute(raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("Foo",)] + +Session = db.create_session(options={}) +session = Session() +result = session.execute(raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("Foo",)] + +Session = db.create_session(options={}) +with Session.begin() as session: + result = session.execute(raw_sql) # $ getSql=raw_sql + assert result.fetchall() == [("Foo",)] + +result = db.create_scoped_session().execute(raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("Foo",)] + + +# text +t = db.text("foo") +assert isinstance(t, sqlalchemy.sql.expression.TextClause) + +t = db.text(text="foo") +assert isinstance(t, sqlalchemy.sql.expression.TextClause) diff --git a/python/ql/test/library-tests/frameworks/modeling-example/NaiveModel.expected b/python/ql/test/library-tests/frameworks/modeling-example/NaiveModel.expected index 159c2f3f256..4f88ba7b4e1 100644 --- a/python/ql/test/library-tests/frameworks/modeling-example/NaiveModel.expected +++ b/python/ql/test/library-tests/frameworks/modeling-example/NaiveModel.expected @@ -26,6 +26,7 @@ nodes | test.py:90:11:90:14 | ControlFlowNode for bm() | semmle.label | ControlFlowNode for bm() | | test.py:91:10:91:12 | ControlFlowNode for val | semmle.label | ControlFlowNode for val | | test.py:107:11:107:18 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() | +subpaths #select | test.py:22:10:22:24 | ControlFlowNode for Attribute() | test.py:21:11:21:18 | ControlFlowNode for source() | test.py:22:10:22:24 | ControlFlowNode for Attribute() | test flow (naive): test_simple | | test.py:33:10:33:12 | ControlFlowNode for val | test.py:29:11:29:18 | ControlFlowNode for source() | test.py:33:10:33:12 | ControlFlowNode for val | test flow (naive): test_alias | diff --git a/python/ql/test/library-tests/frameworks/modeling-example/ProperModel.expected b/python/ql/test/library-tests/frameworks/modeling-example/ProperModel.expected index c1f6f57ef04..9fee0cc2941 100644 --- a/python/ql/test/library-tests/frameworks/modeling-example/ProperModel.expected +++ b/python/ql/test/library-tests/frameworks/modeling-example/ProperModel.expected @@ -66,6 +66,7 @@ nodes | test.py:103:46:103:47 | ControlFlowNode for bm | semmle.label | ControlFlowNode for bm | | test.py:107:11:107:18 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() | | test.py:108:46:108:58 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +subpaths #select | test.py:22:10:22:24 | ControlFlowNode for Attribute() | test.py:21:11:21:18 | ControlFlowNode for source() | test.py:22:10:22:24 | ControlFlowNode for Attribute() | test flow (proper): test_simple | | test.py:33:10:33:12 | ControlFlowNode for val | test.py:29:11:29:18 | ControlFlowNode for source() | test.py:33:10:33:12 | ControlFlowNode for val | test flow (proper): test_alias | diff --git a/python/ql/test/library-tests/frameworks/sqlalchemy/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/sqlalchemy/ConceptsTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/library-tests/frameworks/sqlalchemy/ConceptsTest.ql b/python/ql/test/library-tests/frameworks/sqlalchemy/ConceptsTest.ql new file mode 100644 index 00000000000..b557a0bccb6 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/sqlalchemy/ConceptsTest.ql @@ -0,0 +1,2 @@ +import python +import experimental.meta.ConceptsTest diff --git a/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.expected new file mode 100644 index 00000000000..79d760d87f4 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.expected @@ -0,0 +1,3 @@ +argumentToEnsureNotTaintedNotMarkedAsSpurious +untaintedArgumentToEnsureTaintedNotMarkedAsMissing +failures diff --git a/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.ql b/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.ql new file mode 100644 index 00000000000..027ad8667be --- /dev/null +++ b/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.ql @@ -0,0 +1 @@ +import experimental.meta.InlineTaintTest diff --git a/python/ql/test/experimental/library-tests/frameworks/sqlalchemy/SqlExecution.py b/python/ql/test/library-tests/frameworks/sqlalchemy/SqlExecution.py similarity index 86% rename from python/ql/test/experimental/library-tests/frameworks/sqlalchemy/SqlExecution.py rename to python/ql/test/library-tests/frameworks/sqlalchemy/SqlExecution.py index 7731e80e534..a7c9af9da32 100644 --- a/python/ql/test/experimental/library-tests/frameworks/sqlalchemy/SqlExecution.py +++ b/python/ql/test/library-tests/frameworks/sqlalchemy/SqlExecution.py @@ -47,10 +47,10 @@ with engine.begin() as connection: # Injection requiring the text() taint-step t = text("some sql") -session.query(User).filter(t) # $ getSql=t -session.query(User).group_by(User.id).having(t) # $ getSql=User.id MISSING: getSql=t -session.query(User).group_by(t).first() # $ getSql=t -session.query(User).order_by(t).first() # $ getSql=t +session.query(User).filter(t) +session.query(User).group_by(User.id).having(t) +session.query(User).group_by(t).first() +session.query(User).order_by(t).first() query = select(User).where(User.name == t) # $ MISSING: getSql=t with engine.connect() as conn: diff --git a/python/ql/test/library-tests/frameworks/sqlalchemy/new_tests.py b/python/ql/test/library-tests/frameworks/sqlalchemy/new_tests.py new file mode 100644 index 00000000000..9726e08f6bc --- /dev/null +++ b/python/ql/test/library-tests/frameworks/sqlalchemy/new_tests.py @@ -0,0 +1,388 @@ +import sqlalchemy +import sqlalchemy.orm + +# SQLAlchemy is slowly migrating to a 2.0 version, and as part of 1.4 release have a 2.0 +# style (forwards compatible) API that _can_ be adopted. So these tests are marked with +# either v1.4 or v2.0, such that we cover both. + +raw_sql = "select 'FOO'" +text_sql = sqlalchemy.text(raw_sql) + +Base = sqlalchemy.orm.declarative_base() + +# ============================================================================== +# v1.4 +# ============================================================================== + +print("v1.4") + +# Engine see https://docs.sqlalchemy.org/en/14/core/connections.html#sqlalchemy.engine.Engine + +engine = sqlalchemy.create_engine("sqlite+pysqlite:///:memory:", echo=True) + +result = engine.execute(raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("FOO",)] +result = engine.execute(statement=raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("FOO",)] +result = engine.execute(text_sql) # $ getSql=text_sql +assert result.fetchall() == [("FOO",)] + +scalar_result = engine.scalar(raw_sql) # $ getSql=raw_sql +assert scalar_result == "FOO" +scalar_result = engine.scalar(statement=raw_sql) # $ getSql=raw_sql +assert scalar_result == "FOO" + +# engine with custom execution options +# see https://docs.sqlalchemy.org/en/14/core/connections.html#sqlalchemy.engine.Engine.execution_options +engine_with_custom_exe_opts = engine.execution_options(foo=42) +result = engine_with_custom_exe_opts.execute(raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("FOO",)] + +even_more_opts = engine_with_custom_exe_opts.execution_options(bar=43) +result = even_more_opts.execute(raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("FOO",)] + +# Connection see https://docs.sqlalchemy.org/en/14/core/connections.html#sqlalchemy.engine.Connection +conn = engine.connect() +conn: sqlalchemy.engine.base.Connection + +result = conn.execute(raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("FOO",)] +result = conn.execute(statement=raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("FOO",)] + +result = conn.execute(text_sql) # $ getSql=text_sql +assert result.fetchall() == [("FOO",)] +result = conn.execute(statement=text_sql) # $ getSql=text_sql +assert result.fetchall() == [("FOO",)] + +# scalar +scalar_result = conn.scalar(raw_sql) # $ getSql=raw_sql +assert scalar_result == "FOO" +scalar_result = conn.scalar(object_=raw_sql) # $ getSql=raw_sql +assert scalar_result == "FOO" + +scalar_result = conn.scalar(text_sql) # $ getSql=text_sql +assert scalar_result == "FOO" +scalar_result = conn.scalar(object_=text_sql) # $ getSql=text_sql +assert scalar_result == "FOO" + + +# exec_driver_sql +result = conn.exec_driver_sql(raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("FOO",)] + +# construction by object +conn = sqlalchemy.engine.base.Connection(engine) +result = conn.execute(raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("FOO",)] + +# branched connection +branched_conn = conn.connect() +result = branched_conn.execute(text_sql) # $ getSql=text_sql +assert result.fetchall() == [("FOO",)] + +# raw connection +raw_conn = conn.connection +result = raw_conn.execute(raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("FOO",)] + +cursor = raw_conn.cursor() +cursor.execute(raw_sql) # $ getSql=raw_sql +assert cursor.fetchall() == [("FOO",)] +cursor.close() + +raw_conn = engine.raw_connection() +result = raw_conn.execute(raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("FOO",)] + +# connection with custom execution options +conn_with_custom_exe_opts = conn.execution_options(bar=1337) +result = conn_with_custom_exe_opts.execute(text_sql) # $ getSql=text_sql +assert result.fetchall() == [("FOO",)] + +# Session -- is what you use to work with the ORM layer +# see https://docs.sqlalchemy.org/en/14/orm/session_basics.html +# and https://docs.sqlalchemy.org/en/14/orm/session_api.html#sqlalchemy.orm.Session + +session = sqlalchemy.orm.Session(engine) + +result = session.execute(raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("FOO",)] +result = session.execute(statement=raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("FOO",)] + +result = session.execute(text_sql) # $ getSql=text_sql +assert result.fetchall() == [("FOO",)] +result = session.execute(statement=text_sql) # $ getSql=text_sql +assert result.fetchall() == [("FOO",)] + +# scalar +scalar_result = session.scalar(raw_sql) # $ getSql=raw_sql +assert scalar_result == "FOO" +scalar_result = session.scalar(statement=raw_sql) # $ getSql=raw_sql +assert scalar_result == "FOO" + +scalar_result = session.scalar(text_sql) # $ getSql=text_sql +assert scalar_result == "FOO" +scalar_result = session.scalar(statement=text_sql) # $ getSql=text_sql +assert scalar_result == "FOO" + +# other ways to construct a session +with sqlalchemy.orm.Session(engine) as session: + result = session.execute(raw_sql) # $ getSql=raw_sql + assert result.fetchall() == [("FOO",)] + +Session = sqlalchemy.orm.sessionmaker(engine) +session = Session() + +result = session.execute(raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("FOO",)] + +with Session() as session: + result = session.execute(raw_sql) # $ getSql=raw_sql + assert result.fetchall() == [("FOO",)] + +with Session.begin() as session: + result = session.execute(raw_sql) # $ getSql=raw_sql + assert result.fetchall() == [("FOO",)] + +# Querying (1.4) +# see https://docs.sqlalchemy.org/en/14/orm/session_basics.html#querying-1-x-style + +# to do so we first need a model + +class For14(Base): + __tablename__ = "for14" + + id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True) + description = sqlalchemy.Column(sqlalchemy.String) + +Base.metadata.create_all(engine) + +# add a test-entry +test_entry = For14(id=14, description="test") +session = sqlalchemy.orm.Session(engine) +session.add(test_entry) +session.commit() +assert session.query(For14).all()[0].id == 14 + +# and now we can do the actual querying + +text_foo = sqlalchemy.text("'FOO'") + +# filter_by is only vulnerable to injection if sqlalchemy.text is used, which is evident +# from the logs produced if this file is run +# that is, first filter_by results in the SQL +# +# SELECT for14.id AS for14_id, for14.description AS for14_description +# FROM for14 +# WHERE for14.description = ? +# +# which is then called with the argument `'FOO'` +# +# and the second filter_by results in the SQL +# +# SELECT for14.id AS for14_id, for14.description AS for14_description +# FROM for14 +# WHERE for14.description = 'FOO' +# +# which is then called without any arguments +assert session.query(For14).filter_by(description="'FOO'").all() == [] +query = session.query(For14).filter_by(description=text_foo) +assert query.all() == [] + +# Initially I wanted to add lots of additional taint steps such that the normal SQL +# injection query would find these cases where an ORM query includes a TextClause that +# includes user-input directly... But that presented 2 problems: +# +# - which part of the query construction above should be marked as SQL to fit our +# `SqlExecution` concept. Nothing really fits this well, since all the SQL execution +# happens under the hood. +# - This would require a LOT of modeling for these additional taint steps, since there +# are many many constructs we would need to have models for. (see the 2 examples below) +# +# So instead we extended the SQL injection query to include TextClause construction as a +# sink directly. + +# `filter` provides more general filtering +# see https://docs.sqlalchemy.org/en/14/orm/tutorial.html#common-filter-operators +# and https://docs.sqlalchemy.org/en/14/orm/query.html#sqlalchemy.orm.Query.filter +assert session.query(For14).filter(For14.description == "'FOO'").all() == [] +query = session.query(For14).filter(For14.description == text_foo) +assert query.all() == [] + +assert session.query(For14).filter(For14.description.like("'FOO'")).all() == [] +query = session.query(For14).filter(For14.description.like(text_foo)) +assert query.all() == [] + +# There are many other possibilities for ending up with SQL injection, including the +# following (not an exhaustive list): +# - `where` (alias for `filter`) +# - `group_by` +# - `having` +# - `order_by` +# - `join` +# - `outerjoin` + +# ============================================================================== +# v2.0 +# ============================================================================== +import sqlalchemy.future + +print("-"*80) +print("v2.0 style") + +# For Engine, see https://docs.sqlalchemy.org/en/14/core/future.html#sqlalchemy.future.Engine +engine = sqlalchemy.create_engine("sqlite+pysqlite:///:memory:", echo=True, future=True) +future_engine = sqlalchemy.future.create_engine("sqlite+pysqlite:///:memory:", echo=True) + +# in 2.0 you are not allowed to execute things directly on the engine +try: + engine.execute(raw_sql) # $ SPURIOUS: getSql=raw_sql + raise Exception("above not allowed in 2.0") +except NotImplementedError: + pass +try: + engine.execute(text_sql) # $ SPURIOUS: getSql=text_sql + raise Exception("above not allowed in 2.0") +except NotImplementedError: + pass + + +# `connect` returns a new Connection object. +# see https://docs.sqlalchemy.org/en/14/core/future.html#sqlalchemy.future.Connection +print("v2.0 engine.connect") +with engine.connect() as conn: + conn: sqlalchemy.future.Connection + + # in 2.0 you are not allowed to use raw strings like this: + try: + conn.execute(raw_sql) # $ SPURIOUS: getSql=raw_sql + raise Exception("above not allowed in 2.0") + except sqlalchemy.exc.ObjectNotExecutableError: + pass + + result = conn.execute(text_sql) # $ getSql=text_sql + assert result.fetchall() == [("FOO",)] + result = conn.execute(statement=text_sql) # $ getSql=text_sql + assert result.fetchall() == [("FOO",)] + + result = conn.exec_driver_sql(raw_sql) # $ getSql=raw_sql + assert result.fetchall() == [("FOO",)] + + raw_conn = conn.connection + result = raw_conn.execute(raw_sql) # $ getSql=raw_sql + assert result.fetchall() == [("FOO",)] + + # branching not allowed in 2.0 + try: + branched_conn = conn.connect() + raise Exception("above not allowed in 2.0") + except NotImplementedError: + pass + + # connection with custom execution options + conn_with_custom_exe_opts = conn.execution_options(bar=1337) + result = conn_with_custom_exe_opts.execute(text_sql) # $ getSql=text_sql + assert result.fetchall() == [("FOO",)] + + # `scalar` is shorthand helper + try: + conn.scalar(raw_sql) # $ SPURIOUS: getSql=raw_sql + except sqlalchemy.exc.ObjectNotExecutableError: + pass + scalar_result = conn.scalar(text_sql) # $ getSql=text_sql + assert scalar_result == "FOO" + scalar_result = conn.scalar(statement=text_sql) # $ getSql=text_sql + assert scalar_result == "FOO" + + # This is a contrived example + select = sqlalchemy.select(sqlalchemy.text("'BAR'")) + result = conn.execute(select) # $ getSql=select + assert result.fetchall() == [("BAR",)] + + # This is a contrived example + select = sqlalchemy.select(sqlalchemy.literal_column("'BAZ'")) + result = conn.execute(select) # $ getSql=select + assert result.fetchall() == [("BAZ",)] + +with future_engine.connect() as conn: + result = conn.execute(text_sql) # $ getSql=text_sql + assert result.fetchall() == [("FOO",)] + +# `begin` returns a new Connection object with a transaction begun. +print("v2.0 engine.begin") +with engine.begin() as conn: + result = conn.execute(text_sql) # $ getSql=text_sql + assert result.fetchall() == [("FOO",)] + +# construction by object +conn = sqlalchemy.future.Connection(engine) +result = conn.execute(text_sql) # $ getSql=text_sql +assert result.fetchall() == [("FOO",)] + +# raw_connection + +raw_conn = engine.raw_connection() +result = raw_conn.execute(raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("FOO",)] + +cursor = raw_conn.cursor() +cursor.execute(raw_sql) # $ getSql=raw_sql +assert cursor.fetchall() == [("FOO",)] +cursor.close() + +# Session (2.0) +session = sqlalchemy.orm.Session(engine, future=True) + +result = session.execute(raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("FOO",)] +result = session.execute(statement=raw_sql) # $ getSql=raw_sql +assert result.fetchall() == [("FOO",)] + +result = session.execute(text_sql) # $ getSql=text_sql +assert result.fetchall() == [("FOO",)] +result = session.execute(statement=text_sql) # $ getSql=text_sql +assert result.fetchall() == [("FOO",)] + +# scalar +scalar_result = session.scalar(raw_sql) # $ getSql=raw_sql +assert scalar_result == "FOO" +scalar_result = session.scalar(statement=raw_sql) # $ getSql=raw_sql +assert scalar_result == "FOO" + +scalar_result = session.scalar(text_sql) # $ getSql=text_sql +assert scalar_result == "FOO" +scalar_result = session.scalar(statement=text_sql) # $ getSql=text_sql +assert scalar_result == "FOO" + +# Querying (2.0) +# uses a slightly different style than 1.4 -- see note about not modeling +# ORM query construction as SQL execution at the 1.4 query tests. + +class For20(Base): + __tablename__ = "for20" + + id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True) + description = sqlalchemy.Column(sqlalchemy.String) + +For20.metadata.create_all(engine) + +# add a test-entry +test_entry = For20(id=20, description="test") +session = sqlalchemy.orm.Session(engine, future=True) +session.add(test_entry) +session.commit() +assert session.query(For20).all()[0].id == 20 + +# and now we can do the actual querying +# see https://docs.sqlalchemy.org/en/14/orm/session_basics.html#querying-2-0-style + +statement = sqlalchemy.select(For20) +result = session.execute(statement) # $ getSql=statement +assert result.scalars().all()[0].id == 20 + +statement = sqlalchemy.select(For20).where(For20.description == text_foo) +result = session.execute(statement) # $ getSql=statement +assert result.scalars().all() == [] diff --git a/python/ql/test/library-tests/frameworks/sqlalchemy/taint_test.py b/python/ql/test/library-tests/frameworks/sqlalchemy/taint_test.py new file mode 100644 index 00000000000..9e9764a411f --- /dev/null +++ b/python/ql/test/library-tests/frameworks/sqlalchemy/taint_test.py @@ -0,0 +1,28 @@ +import sqlalchemy + +ensure_tainted = ensure_not_tainted = print +TAINTED_STRING = "TAINTED_STRING" + +def test_taint(): + ts = TAINTED_STRING + + ensure_tainted(ts) # $ tainted + + t1 = sqlalchemy.text(ts) + t2 = sqlalchemy.text(text=ts) + t3 = sqlalchemy.sql.text(ts) + t4 = sqlalchemy.sql.text(text=ts) + t5 = sqlalchemy.sql.expression.text(ts) + t6 = sqlalchemy.sql.expression.text(text=ts) + t7 = sqlalchemy.sql.expression.TextClause(ts) + t8 = sqlalchemy.sql.expression.TextClause(text=ts) + + # Since we flag user-input to a TextClause with its' own query, we don't want to + # have a taint-step for it as that would lead to us also giving an alert for normal + # SQL-injection... and double alerting like this does not seem desireable. + ensure_not_tainted(t1, t2, t3, t4, t5, t6, t7, t8) + + for text in [t1, t2, t3, t4, t5, t6, t7, t8]: + assert isinstance(text, sqlalchemy.sql.expression.TextClause) + +test_taint() diff --git a/python/ql/test/library-tests/regexparser/redos.py b/python/ql/test/library-tests/regexparser/redos.py index 1ddee257e18..c8379bfcc0f 100644 --- a/python/ql/test/library-tests/regexparser/redos.py +++ b/python/ql/test/library-tests/regexparser/redos.py @@ -266,11 +266,11 @@ bad61 = re.compile(r'''(thisisagoddamnlongstringforstresstestingthequery|this\w+ # GOOD good27 = re.compile(r'''(thisisagoddamnlongstringforstresstestingthequery|imanotherbutunrelatedstringcomparedtotheotherstring)*-''') -# GOOD -good28 = re.compile(r'''foo([\uDC66\uDC67]|[\uDC68\uDC69])*foo''') +# GOOD (but false positive caused by the extractor converting all four unpaired surrogates to \uFFFD) +good28 = re.compile('''foo([\uDC66\uDC67]|[\uDC68\uDC69])*foo''') -# GOOD -good29 = re.compile(r'''foo((\uDC66|\uDC67)|(\uDC68|\uDC69))*foo''') +# GOOD (but false positive caused by the extractor converting all four unpaired surrogates to \uFFFD) +good29 = re.compile('''foo((\uDC66|\uDC67)|(\uDC68|\uDC69))*foo''') # NOT GOOD (but cannot currently construct a prefix) bad62 = re.compile(r'''a{2,3}(b+)+X''') diff --git a/python/ql/test/query-tests/Exceptions/generators/test.py b/python/ql/test/query-tests/Exceptions/generators/test.py index 7b7ef8c7fe2..e8b3f0b2b34 100644 --- a/python/ql/test/query-tests/Exceptions/generators/test.py +++ b/python/ql/test/query-tests/Exceptions/generators/test.py @@ -53,3 +53,12 @@ def ok5(seq): def ok6(seq): yield next(iter([]), default='foo') + +# Handling for multiple exception types, one of which is `StopIteration` +# Reported as a false positive in github/codeql#6227 +def ok7(seq, ctx): + try: + with ctx: + yield next(iter) + except (StopIteration, MemoryError): + return diff --git a/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/ModificationOfParameterWithDefault.expected b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/ModificationOfParameterWithDefault.expected new file mode 100644 index 00000000000..86daf9cb09e --- /dev/null +++ b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/ModificationOfParameterWithDefault.expected @@ -0,0 +1,108 @@ +edges +| test.py:2:12:2:12 | ControlFlowNode for l | test.py:3:5:3:5 | ControlFlowNode for l | +| test.py:7:11:7:11 | ControlFlowNode for l | test.py:8:5:8:5 | ControlFlowNode for l | +| test.py:12:14:12:14 | ControlFlowNode for l | test.py:13:9:13:9 | ControlFlowNode for l | +| test.py:17:15:17:15 | ControlFlowNode for l | test.py:18:5:18:5 | ControlFlowNode for l | +| test.py:22:15:22:15 | ControlFlowNode for l | test.py:23:5:23:5 | ControlFlowNode for l | +| test.py:27:12:27:12 | ControlFlowNode for l | test.py:28:5:28:5 | ControlFlowNode for l | +| test.py:38:13:38:13 | ControlFlowNode for l | test.py:39:5:39:5 | ControlFlowNode for l | +| test.py:43:14:43:14 | ControlFlowNode for l | test.py:44:13:44:13 | ControlFlowNode for l | +| test.py:44:13:44:13 | ControlFlowNode for l | test.py:38:13:38:13 | ControlFlowNode for l | +| test.py:48:14:48:14 | ControlFlowNode for l | test.py:49:5:49:5 | ControlFlowNode for l | +| test.py:53:10:53:10 | ControlFlowNode for d | test.py:54:5:54:5 | ControlFlowNode for d | +| test.py:58:19:58:19 | ControlFlowNode for d | test.py:59:5:59:5 | ControlFlowNode for d | +| test.py:63:28:63:28 | ControlFlowNode for d | test.py:64:5:64:5 | ControlFlowNode for d | +| test.py:67:14:67:14 | ControlFlowNode for d | test.py:68:5:68:5 | ControlFlowNode for d | +| test.py:72:19:72:19 | ControlFlowNode for d | test.py:73:14:73:14 | ControlFlowNode for d | +| test.py:73:14:73:14 | ControlFlowNode for d | test.py:67:14:67:14 | ControlFlowNode for d | +| test.py:77:17:77:17 | ControlFlowNode for d | test.py:78:5:78:5 | ControlFlowNode for d | +| test.py:82:26:82:26 | ControlFlowNode for d | test.py:83:5:83:5 | ControlFlowNode for d | +| test.py:87:35:87:35 | ControlFlowNode for d | test.py:88:5:88:5 | ControlFlowNode for d | +| test.py:91:21:91:21 | ControlFlowNode for d | test.py:92:5:92:5 | ControlFlowNode for d | +| test.py:96:26:96:26 | ControlFlowNode for d | test.py:97:21:97:21 | ControlFlowNode for d | +| test.py:97:21:97:21 | ControlFlowNode for d | test.py:91:21:91:21 | ControlFlowNode for d | +| test.py:108:14:108:14 | ControlFlowNode for d | test.py:109:9:109:9 | ControlFlowNode for d | +| test.py:113:20:113:20 | ControlFlowNode for d | test.py:115:5:115:5 | ControlFlowNode for d | +| test.py:119:29:119:29 | ControlFlowNode for d | test.py:121:5:121:5 | ControlFlowNode for d | +| test.py:124:15:124:15 | ControlFlowNode for l | test.py:128:9:128:9 | ControlFlowNode for l | +| test.py:131:23:131:23 | ControlFlowNode for l | test.py:135:9:135:9 | ControlFlowNode for l | +| test.py:138:15:138:15 | ControlFlowNode for l | test.py:140:9:140:9 | ControlFlowNode for l | +| test.py:145:23:145:23 | ControlFlowNode for l | test.py:147:9:147:9 | ControlFlowNode for l | +nodes +| test.py:2:12:2:12 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:3:5:3:5 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:7:11:7:11 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:8:5:8:5 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:12:14:12:14 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:13:9:13:9 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:17:15:17:15 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:18:5:18:5 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:22:15:22:15 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:23:5:23:5 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:27:12:27:12 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:28:5:28:5 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:38:13:38:13 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:39:5:39:5 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:43:14:43:14 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:44:13:44:13 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:48:14:48:14 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:49:5:49:5 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:53:10:53:10 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:54:5:54:5 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:58:19:58:19 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:59:5:59:5 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:63:28:63:28 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:64:5:64:5 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:67:14:67:14 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:68:5:68:5 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:72:19:72:19 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:73:14:73:14 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:77:17:77:17 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:78:5:78:5 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:82:26:82:26 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:83:5:83:5 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:87:35:87:35 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:88:5:88:5 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:91:21:91:21 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:92:5:92:5 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:96:26:96:26 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:97:21:97:21 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:108:14:108:14 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:109:9:109:9 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:113:20:113:20 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:115:5:115:5 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:119:29:119:29 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:121:5:121:5 | ControlFlowNode for d | semmle.label | ControlFlowNode for d | +| test.py:124:15:124:15 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:128:9:128:9 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:131:23:131:23 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:135:9:135:9 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:138:15:138:15 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:140:9:140:9 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:145:23:145:23 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +| test.py:147:9:147:9 | ControlFlowNode for l | semmle.label | ControlFlowNode for l | +subpaths +#select +| test.py:3:5:3:5 | ControlFlowNode for l | test.py:2:12:2:12 | ControlFlowNode for l | test.py:3:5:3:5 | ControlFlowNode for l | $@ flows to here and is mutated. | test.py:2:12:2:12 | ControlFlowNode for l | Default value | +| test.py:8:5:8:5 | ControlFlowNode for l | test.py:7:11:7:11 | ControlFlowNode for l | test.py:8:5:8:5 | ControlFlowNode for l | $@ flows to here and is mutated. | test.py:7:11:7:11 | ControlFlowNode for l | Default value | +| test.py:13:9:13:9 | ControlFlowNode for l | test.py:12:14:12:14 | ControlFlowNode for l | test.py:13:9:13:9 | ControlFlowNode for l | $@ flows to here and is mutated. | test.py:12:14:12:14 | ControlFlowNode for l | Default value | +| test.py:18:5:18:5 | ControlFlowNode for l | test.py:17:15:17:15 | ControlFlowNode for l | test.py:18:5:18:5 | ControlFlowNode for l | $@ flows to here and is mutated. | test.py:17:15:17:15 | ControlFlowNode for l | Default value | +| test.py:23:5:23:5 | ControlFlowNode for l | test.py:22:15:22:15 | ControlFlowNode for l | test.py:23:5:23:5 | ControlFlowNode for l | $@ flows to here and is mutated. | test.py:22:15:22:15 | ControlFlowNode for l | Default value | +| test.py:28:5:28:5 | ControlFlowNode for l | test.py:27:12:27:12 | ControlFlowNode for l | test.py:28:5:28:5 | ControlFlowNode for l | $@ flows to here and is mutated. | test.py:27:12:27:12 | ControlFlowNode for l | Default value | +| test.py:39:5:39:5 | ControlFlowNode for l | test.py:43:14:43:14 | ControlFlowNode for l | test.py:39:5:39:5 | ControlFlowNode for l | $@ flows to here and is mutated. | test.py:43:14:43:14 | ControlFlowNode for l | Default value | +| test.py:49:5:49:5 | ControlFlowNode for l | test.py:48:14:48:14 | ControlFlowNode for l | test.py:49:5:49:5 | ControlFlowNode for l | $@ flows to here and is mutated. | test.py:48:14:48:14 | ControlFlowNode for l | Default value | +| test.py:54:5:54:5 | ControlFlowNode for d | test.py:53:10:53:10 | ControlFlowNode for d | test.py:54:5:54:5 | ControlFlowNode for d | $@ flows to here and is mutated. | test.py:53:10:53:10 | ControlFlowNode for d | Default value | +| test.py:59:5:59:5 | ControlFlowNode for d | test.py:58:19:58:19 | ControlFlowNode for d | test.py:59:5:59:5 | ControlFlowNode for d | $@ flows to here and is mutated. | test.py:58:19:58:19 | ControlFlowNode for d | Default value | +| test.py:64:5:64:5 | ControlFlowNode for d | test.py:63:28:63:28 | ControlFlowNode for d | test.py:64:5:64:5 | ControlFlowNode for d | $@ flows to here and is mutated. | test.py:63:28:63:28 | ControlFlowNode for d | Default value | +| test.py:68:5:68:5 | ControlFlowNode for d | test.py:72:19:72:19 | ControlFlowNode for d | test.py:68:5:68:5 | ControlFlowNode for d | $@ flows to here and is mutated. | test.py:72:19:72:19 | ControlFlowNode for d | Default value | +| test.py:78:5:78:5 | ControlFlowNode for d | test.py:77:17:77:17 | ControlFlowNode for d | test.py:78:5:78:5 | ControlFlowNode for d | $@ flows to here and is mutated. | test.py:77:17:77:17 | ControlFlowNode for d | Default value | +| test.py:83:5:83:5 | ControlFlowNode for d | test.py:82:26:82:26 | ControlFlowNode for d | test.py:83:5:83:5 | ControlFlowNode for d | $@ flows to here and is mutated. | test.py:82:26:82:26 | ControlFlowNode for d | Default value | +| test.py:88:5:88:5 | ControlFlowNode for d | test.py:87:35:87:35 | ControlFlowNode for d | test.py:88:5:88:5 | ControlFlowNode for d | $@ flows to here and is mutated. | test.py:87:35:87:35 | ControlFlowNode for d | Default value | +| test.py:92:5:92:5 | ControlFlowNode for d | test.py:96:26:96:26 | ControlFlowNode for d | test.py:92:5:92:5 | ControlFlowNode for d | $@ flows to here and is mutated. | test.py:96:26:96:26 | ControlFlowNode for d | Default value | +| test.py:109:9:109:9 | ControlFlowNode for d | test.py:108:14:108:14 | ControlFlowNode for d | test.py:109:9:109:9 | ControlFlowNode for d | $@ flows to here and is mutated. | test.py:108:14:108:14 | ControlFlowNode for d | Default value | +| test.py:115:5:115:5 | ControlFlowNode for d | test.py:113:20:113:20 | ControlFlowNode for d | test.py:115:5:115:5 | ControlFlowNode for d | $@ flows to here and is mutated. | test.py:113:20:113:20 | ControlFlowNode for d | Default value | +| test.py:121:5:121:5 | ControlFlowNode for d | test.py:119:29:119:29 | ControlFlowNode for d | test.py:121:5:121:5 | ControlFlowNode for d | $@ flows to here and is mutated. | test.py:119:29:119:29 | ControlFlowNode for d | Default value | +| test.py:128:9:128:9 | ControlFlowNode for l | test.py:124:15:124:15 | ControlFlowNode for l | test.py:128:9:128:9 | ControlFlowNode for l | $@ flows to here and is mutated. | test.py:124:15:124:15 | ControlFlowNode for l | Default value | +| test.py:135:9:135:9 | ControlFlowNode for l | test.py:131:23:131:23 | ControlFlowNode for l | test.py:135:9:135:9 | ControlFlowNode for l | $@ flows to here and is mutated. | test.py:131:23:131:23 | ControlFlowNode for l | Default value | +| test.py:140:9:140:9 | ControlFlowNode for l | test.py:138:15:138:15 | ControlFlowNode for l | test.py:140:9:140:9 | ControlFlowNode for l | $@ flows to here and is mutated. | test.py:138:15:138:15 | ControlFlowNode for l | Default value | +| test.py:147:9:147:9 | ControlFlowNode for l | test.py:145:23:145:23 | ControlFlowNode for l | test.py:147:9:147:9 | ControlFlowNode for l | $@ flows to here and is mutated. | test.py:145:23:145:23 | ControlFlowNode for l | Default value | diff --git a/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/ModificationOfParameterWithDefault.qlref b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/ModificationOfParameterWithDefault.qlref new file mode 100644 index 00000000000..8c4044e8fee --- /dev/null +++ b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/ModificationOfParameterWithDefault.qlref @@ -0,0 +1 @@ +Functions/ModificationOfParameterWithDefault.ql diff --git a/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.expected b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.py b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.py new file mode 100644 index 00000000000..f1377f36e56 --- /dev/null +++ b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.py @@ -0,0 +1,150 @@ +# Not OK +def simple(l = [0]): + l[0] = 1 #$ modification=l + return l + +# Not OK +def slice(l = [0]): + l[0:1] = 1 #$ modification=l + return l + +# Not OK +def list_del(l = [0]): + del l[0] #$ modification=l + return l + +# Not OK +def append_op(l = []): + l += [1, 2, 3] #$ modification=l + return l + +# Not OK +def repeat_op(l = [0]): + l *= 3 #$ modification=l + return l + +# Not OK +def append(l = []): + l.append(1) #$ modification=l + return l + +# OK +def includes(l = []): + x = [0] + x.extend(l) + x.extend([1]) + return x + +def extends(l): + l.extend([1]) #$ modification=l + return l + +# Not OK +def deferred(l = []): + extends(l) + return l + +# Not OK +def nonempty(l = [5]): + l.append(1) #$ modification=l + return l + +# Not OK +def dict(d = {}): + d['a'] = 1 #$ modification=d + return d + +# Not OK +def dict_nonempty(d = {'a': 1}): + d['a'] = 2 #$ modification=d + return d + +# OK +def dict_nonempty_nochange(d = {'a': 1}): + d['a'] = 1 #$ SPURIOUS: modification=d + return d + +def modifies(d): + d['a'] = 1 #$ modification=d + return d + +# Not OK +def dict_deferred(d = {}): + modifies(d) + return d + +# Not OK +def dict_method(d = {}): + d.update({'a': 1}) #$ modification=d + return d + +# Not OK +def dict_method_nonempty(d = {'a': 1}): + d.update({'a': 2}) #$ modification=d + return d + +# OK +def dict_method_nonempty_nochange(d = {'a': 1}): + d.update({'a': 1}) #$ SPURIOUS:modification=d + return d + +def modifies_method(d): + d.update({'a': 1}) #$ modification=d + return d + +# Not OK +def dict_deferred_method(d = {}): + modifies_method(d) + return d + +# OK +def dict_includes(d = {}): + x = {} + x.update(d) + x.update({'a': 1}) + return x + +# Not OK +def dict_del(d = {'a': 1}): + del d['a'] #$ modification=d + return d + +# Not OK +def dict_update_op(d = {}): + x = {'a': 1} + d |= x #$ modification=d + return d + +# OK +def dict_update_op_nochange(d = {}): + x = {} + d |= x #$ SPURIOUS: modification=d + return d + +def sanitizer(l = []): + if l: + l.append(1) + else: + l.append(1) #$ modification=l + return l + +def sanitizer_negated(l = [1]): + if not l: + l.append(1) + else: + l.append(1) #$ modification=l + return l + +def sanitizer(l = []): + if not l: + l.append(1) #$ modification=l + else: + l.append(1) + return l + +def sanitizer_negated(l = [1]): + if l: + l.append(1) #$ modification=l + else: + l.append(1) + return l diff --git a/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.ql b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.ql new file mode 100644 index 00000000000..de516c7ec9b --- /dev/null +++ b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.ql @@ -0,0 +1,24 @@ +import python +import semmle.python.dataflow.new.DataFlow +import TestUtilities.InlineExpectationsTest +import semmle.python.functions.ModificationOfParameterWithDefault +private import semmle.python.dataflow.new.internal.PrintNode + +class ModificationOfParameterWithDefaultTest extends InlineExpectationsTest { + ModificationOfParameterWithDefaultTest() { this = "ModificationOfParameterWithDefaultTest" } + + override string getARelevantTag() { result = "modification" } + + predicate relevant_node(DataFlow::Node sink) { + exists(ModificationOfParameterWithDefault::Configuration cfg | cfg.hasFlowTo(sink)) + } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + exists(DataFlow::Node n | relevant_node(n) | + n.getLocation() = location and + tag = "modification" and + value = prettyNode(n) and + element = n.toString() + ) + } +} diff --git a/python/ql/test/query-tests/Functions/general/ModificationOfParameterWithDefault.expected b/python/ql/test/query-tests/Functions/general/ModificationOfParameterWithDefault.expected index 08586d02c10..c32326d4942 100644 --- a/python/ql/test/query-tests/Functions/general/ModificationOfParameterWithDefault.expected +++ b/python/ql/test/query-tests/Functions/general/ModificationOfParameterWithDefault.expected @@ -1,24 +1,44 @@ edges -| functions_test.py:39:9:39:9 | empty mutable value | functions_test.py:40:5:40:5 | empty mutable value | -| functions_test.py:133:15:133:15 | empty mutable value | functions_test.py:134:5:134:5 | empty mutable value | -| functions_test.py:151:25:151:25 | empty mutable value | functions_test.py:152:5:152:5 | empty mutable value | -| functions_test.py:154:21:154:21 | empty mutable value | functions_test.py:155:5:155:5 | empty mutable value | -| functions_test.py:157:27:157:27 | empty mutable value | functions_test.py:158:25:158:25 | empty mutable value | -| functions_test.py:157:27:157:27 | empty mutable value | functions_test.py:159:21:159:21 | empty mutable value | -| functions_test.py:158:25:158:25 | empty mutable value | functions_test.py:151:25:151:25 | empty mutable value | -| functions_test.py:159:21:159:21 | empty mutable value | functions_test.py:154:21:154:21 | empty mutable value | -| functions_test.py:175:28:175:28 | non-empty mutable value | functions_test.py:179:9:179:9 | non-empty mutable value | -| functions_test.py:175:28:175:28 | non-empty mutable value | functions_test.py:181:9:181:9 | non-empty mutable value | -| functions_test.py:188:18:188:18 | non-empty mutable value | functions_test.py:189:28:189:28 | non-empty mutable value | -| functions_test.py:189:28:189:28 | non-empty mutable value | functions_test.py:175:28:175:28 | non-empty mutable value | -| functions_test.py:191:18:191:18 | non-empty mutable value | functions_test.py:192:28:192:28 | non-empty mutable value | -| functions_test.py:192:28:192:28 | non-empty mutable value | functions_test.py:175:28:175:28 | non-empty mutable value | +| functions_test.py:39:9:39:9 | ControlFlowNode for x | functions_test.py:40:5:40:5 | ControlFlowNode for x | +| functions_test.py:133:15:133:15 | ControlFlowNode for x | functions_test.py:134:5:134:5 | ControlFlowNode for x | +| functions_test.py:151:25:151:25 | ControlFlowNode for x | functions_test.py:152:5:152:5 | ControlFlowNode for x | +| functions_test.py:154:21:154:21 | ControlFlowNode for x | functions_test.py:155:5:155:5 | ControlFlowNode for x | +| functions_test.py:157:27:157:27 | ControlFlowNode for y | functions_test.py:158:25:158:25 | ControlFlowNode for y | +| functions_test.py:157:27:157:27 | ControlFlowNode for y | functions_test.py:159:21:159:21 | ControlFlowNode for y | +| functions_test.py:158:25:158:25 | ControlFlowNode for y | functions_test.py:151:25:151:25 | ControlFlowNode for x | +| functions_test.py:159:21:159:21 | ControlFlowNode for y | functions_test.py:154:21:154:21 | ControlFlowNode for x | +| functions_test.py:179:28:179:28 | ControlFlowNode for x | functions_test.py:183:9:183:9 | ControlFlowNode for x | +| functions_test.py:179:28:179:28 | ControlFlowNode for x | functions_test.py:185:9:185:9 | ControlFlowNode for x | +| functions_test.py:192:18:192:18 | ControlFlowNode for x | functions_test.py:193:28:193:28 | ControlFlowNode for x | +| functions_test.py:193:28:193:28 | ControlFlowNode for x | functions_test.py:179:28:179:28 | ControlFlowNode for x | +| functions_test.py:195:18:195:18 | ControlFlowNode for x | functions_test.py:196:28:196:28 | ControlFlowNode for x | +| functions_test.py:196:28:196:28 | ControlFlowNode for x | functions_test.py:179:28:179:28 | ControlFlowNode for x | +nodes +| functions_test.py:39:9:39:9 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| functions_test.py:40:5:40:5 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| functions_test.py:133:15:133:15 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| functions_test.py:134:5:134:5 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| functions_test.py:151:25:151:25 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| functions_test.py:152:5:152:5 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| functions_test.py:154:21:154:21 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| functions_test.py:155:5:155:5 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| functions_test.py:157:27:157:27 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | +| functions_test.py:158:25:158:25 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | +| functions_test.py:159:21:159:21 | ControlFlowNode for y | semmle.label | ControlFlowNode for y | +| functions_test.py:179:28:179:28 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| functions_test.py:183:9:183:9 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| functions_test.py:185:9:185:9 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| functions_test.py:192:18:192:18 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| functions_test.py:193:28:193:28 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| functions_test.py:195:18:195:18 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +| functions_test.py:196:28:196:28 | ControlFlowNode for x | semmle.label | ControlFlowNode for x | +subpaths #select -| functions_test.py:40:5:40:5 | x | functions_test.py:39:9:39:9 | empty mutable value | functions_test.py:40:5:40:5 | empty mutable value | $@ flows to here and is mutated. | functions_test.py:39:9:39:9 | x | Default value | -| functions_test.py:134:5:134:5 | x | functions_test.py:133:15:133:15 | empty mutable value | functions_test.py:134:5:134:5 | empty mutable value | $@ flows to here and is mutated. | functions_test.py:133:15:133:15 | x | Default value | -| functions_test.py:152:5:152:5 | x | functions_test.py:157:27:157:27 | empty mutable value | functions_test.py:152:5:152:5 | empty mutable value | $@ flows to here and is mutated. | functions_test.py:157:27:157:27 | y | Default value | -| functions_test.py:155:5:155:5 | x | functions_test.py:157:27:157:27 | empty mutable value | functions_test.py:155:5:155:5 | empty mutable value | $@ flows to here and is mutated. | functions_test.py:157:27:157:27 | y | Default value | -| functions_test.py:179:9:179:9 | x | functions_test.py:188:18:188:18 | non-empty mutable value | functions_test.py:179:9:179:9 | non-empty mutable value | $@ flows to here and is mutated. | functions_test.py:188:18:188:18 | x | Default value | -| functions_test.py:179:9:179:9 | x | functions_test.py:191:18:191:18 | non-empty mutable value | functions_test.py:179:9:179:9 | non-empty mutable value | $@ flows to here and is mutated. | functions_test.py:191:18:191:18 | x | Default value | -| functions_test.py:181:9:181:9 | x | functions_test.py:188:18:188:18 | non-empty mutable value | functions_test.py:181:9:181:9 | non-empty mutable value | $@ flows to here and is mutated. | functions_test.py:188:18:188:18 | x | Default value | -| functions_test.py:181:9:181:9 | x | functions_test.py:191:18:191:18 | non-empty mutable value | functions_test.py:181:9:181:9 | non-empty mutable value | $@ flows to here and is mutated. | functions_test.py:191:18:191:18 | x | Default value | +| functions_test.py:40:5:40:5 | ControlFlowNode for x | functions_test.py:39:9:39:9 | ControlFlowNode for x | functions_test.py:40:5:40:5 | ControlFlowNode for x | $@ flows to here and is mutated. | functions_test.py:39:9:39:9 | ControlFlowNode for x | Default value | +| functions_test.py:134:5:134:5 | ControlFlowNode for x | functions_test.py:133:15:133:15 | ControlFlowNode for x | functions_test.py:134:5:134:5 | ControlFlowNode for x | $@ flows to here and is mutated. | functions_test.py:133:15:133:15 | ControlFlowNode for x | Default value | +| functions_test.py:152:5:152:5 | ControlFlowNode for x | functions_test.py:157:27:157:27 | ControlFlowNode for y | functions_test.py:152:5:152:5 | ControlFlowNode for x | $@ flows to here and is mutated. | functions_test.py:157:27:157:27 | ControlFlowNode for y | Default value | +| functions_test.py:155:5:155:5 | ControlFlowNode for x | functions_test.py:157:27:157:27 | ControlFlowNode for y | functions_test.py:155:5:155:5 | ControlFlowNode for x | $@ flows to here and is mutated. | functions_test.py:157:27:157:27 | ControlFlowNode for y | Default value | +| functions_test.py:183:9:183:9 | ControlFlowNode for x | functions_test.py:192:18:192:18 | ControlFlowNode for x | functions_test.py:183:9:183:9 | ControlFlowNode for x | $@ flows to here and is mutated. | functions_test.py:192:18:192:18 | ControlFlowNode for x | Default value | +| functions_test.py:183:9:183:9 | ControlFlowNode for x | functions_test.py:195:18:195:18 | ControlFlowNode for x | functions_test.py:183:9:183:9 | ControlFlowNode for x | $@ flows to here and is mutated. | functions_test.py:195:18:195:18 | ControlFlowNode for x | Default value | +| functions_test.py:185:9:185:9 | ControlFlowNode for x | functions_test.py:192:18:192:18 | ControlFlowNode for x | functions_test.py:185:9:185:9 | ControlFlowNode for x | $@ flows to here and is mutated. | functions_test.py:192:18:192:18 | ControlFlowNode for x | Default value | +| functions_test.py:185:9:185:9 | ControlFlowNode for x | functions_test.py:195:18:195:18 | ControlFlowNode for x | functions_test.py:185:9:185:9 | ControlFlowNode for x | $@ flows to here and is mutated. | functions_test.py:195:18:195:18 | ControlFlowNode for x | Default value | diff --git a/python/ql/test/query-tests/Functions/general/functions_test.py b/python/ql/test/query-tests/Functions/general/functions_test.py index 95e0923ea21..c47794fef28 100644 --- a/python/ql/test/query-tests/Functions/general/functions_test.py +++ b/python/ql/test/query-tests/Functions/general/functions_test.py @@ -163,11 +163,15 @@ def guarded_modification(z=[]): z.append(0) return z -def issue1143(expr, param=[]): - if not param: - return result - for i in param: - param.remove(i) # Mutation here +# This function causes a discrepancy between the +# Python 2 and 3 versions of the analysis. +# We comment it out until we have resoved the issue. +# +# def issue1143(expr, param=[]): +# if not param: +# return result +# for i in param: +# param.remove(i) # Mutation here # Type guarding of modification of parameter with default: diff --git a/python/ql/test/query-tests/Functions/general/options b/python/ql/test/query-tests/Functions/general/options new file mode 100644 index 00000000000..2032dd9e54c --- /dev/null +++ b/python/ql/test/query-tests/Functions/general/options @@ -0,0 +1 @@ +semmle-extractor-options: --max-import-depth=1 --dont-split-graph diff --git a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected index 859f23a50c2..fcb2d3103eb 100644 --- a/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected +++ b/python/ql/test/query-tests/Security/CWE-020-ExternalAPIs/UntrustedDataToExternalAPI.expected @@ -5,5 +5,6 @@ nodes | test.py:13:16:13:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test.py:13:16:13:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:15:36:15:39 | ControlFlowNode for data | semmle.label | ControlFlowNode for data | +subpaths #select | test.py:15:36:15:39 | ControlFlowNode for data | test.py:13:16:13:22 | ControlFlowNode for request | test.py:15:36:15:39 | ControlFlowNode for data | Call to hmac.new [param 1] with untrusted data from $@. | test.py:13:16:13:22 | ControlFlowNode for request | ControlFlowNode for request | diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.expected b/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.expected index a461c41e031..3c000eb1070 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection-py2/CommandInjection.expected @@ -21,6 +21,7 @@ nodes | command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +subpaths #select | command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | | command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected index df3afdaf150..449bc4d0efb 100644 --- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/CommandInjection.expected @@ -50,6 +50,7 @@ nodes | command_injection.py:78:12:78:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | command_injection.py:78:12:78:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | command_injection.py:80:19:80:30 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +subpaths #select | command_injection.py:13:15:13:27 | ControlFlowNode for BinaryExpr | command_injection.py:11:13:11:19 | ControlFlowNode for request | command_injection.py:13:15:13:27 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:11:13:11:19 | ControlFlowNode for request | a user-provided value | | command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected b/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected index d40279e8fcc..39c2bb3778f 100644 --- a/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected +++ b/python/ql/test/query-tests/Security/CWE-079-ReflectedXss/ReflectedXss.expected @@ -15,6 +15,7 @@ nodes | reflected_xss.py:27:23:27:29 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | reflected_xss.py:27:23:27:34 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +subpaths #select | reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | reflected_xss.py:9:18:9:24 | ControlFlowNode for request | reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | Cross-site scripting vulnerability due to $@. | reflected_xss.py:9:18:9:24 | ControlFlowNode for request | a user-provided value | | reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | reflected_xss.py:21:23:21:29 | ControlFlowNode for request | reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | reflected_xss.py:21:23:21:29 | ControlFlowNode for request | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-089-SqlInjection/SqlInjection.expected b/python/ql/test/query-tests/Security/CWE-089-SqlInjection/SqlInjection.expected index a133d4039fe..ed4c3e3d313 100644 --- a/python/ql/test/query-tests/Security/CWE-089-SqlInjection/SqlInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-089-SqlInjection/SqlInjection.expected @@ -3,14 +3,52 @@ edges | sql_injection.py:14:15:14:22 | ControlFlowNode for username | sql_injection.py:24:38:24:95 | ControlFlowNode for BinaryExpr | | sql_injection.py:14:15:14:22 | ControlFlowNode for username | sql_injection.py:25:26:25:83 | ControlFlowNode for BinaryExpr | | sql_injection.py:14:15:14:22 | ControlFlowNode for username | sql_injection.py:26:28:26:85 | ControlFlowNode for BinaryExpr | +| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:27:28:27:87 | ControlFlowNode for Attribute() | +| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:31:50:31:72 | ControlFlowNode for Attribute() | +| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:41:26:41:33 | ControlFlowNode for username | +| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:42:31:42:38 | ControlFlowNode for username | +| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:43:30:43:37 | ControlFlowNode for username | +| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:44:35:44:42 | ControlFlowNode for username | +| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:45:41:45:48 | ControlFlowNode for username | +| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:46:46:46:53 | ControlFlowNode for username | +| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:47:47:47:54 | ControlFlowNode for username | +| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:48:52:48:59 | ControlFlowNode for username | +| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:50:18:50:25 | ControlFlowNode for username | +| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:51:24:51:31 | ControlFlowNode for username | nodes | sql_injection.py:14:15:14:22 | ControlFlowNode for username | semmle.label | ControlFlowNode for username | | sql_injection.py:21:24:21:77 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | sql_injection.py:24:38:24:95 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | sql_injection.py:25:26:25:83 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | sql_injection.py:26:28:26:85 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | semmle.label | ControlFlowNode for username | +| sqlalchemy_textclause.py:27:28:27:87 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| sqlalchemy_textclause.py:31:50:31:72 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| sqlalchemy_textclause.py:41:26:41:33 | ControlFlowNode for username | semmle.label | ControlFlowNode for username | +| sqlalchemy_textclause.py:42:31:42:38 | ControlFlowNode for username | semmle.label | ControlFlowNode for username | +| sqlalchemy_textclause.py:43:30:43:37 | ControlFlowNode for username | semmle.label | ControlFlowNode for username | +| sqlalchemy_textclause.py:44:35:44:42 | ControlFlowNode for username | semmle.label | ControlFlowNode for username | +| sqlalchemy_textclause.py:45:41:45:48 | ControlFlowNode for username | semmle.label | ControlFlowNode for username | +| sqlalchemy_textclause.py:46:46:46:53 | ControlFlowNode for username | semmle.label | ControlFlowNode for username | +| sqlalchemy_textclause.py:47:47:47:54 | ControlFlowNode for username | semmle.label | ControlFlowNode for username | +| sqlalchemy_textclause.py:48:52:48:59 | ControlFlowNode for username | semmle.label | ControlFlowNode for username | +| sqlalchemy_textclause.py:50:18:50:25 | ControlFlowNode for username | semmle.label | ControlFlowNode for username | +| sqlalchemy_textclause.py:51:24:51:31 | ControlFlowNode for username | semmle.label | ControlFlowNode for username | +subpaths #select | sql_injection.py:21:24:21:77 | ControlFlowNode for BinaryExpr | sql_injection.py:14:15:14:22 | ControlFlowNode for username | sql_injection.py:21:24:21:77 | ControlFlowNode for BinaryExpr | This SQL query depends on $@. | sql_injection.py:14:15:14:22 | ControlFlowNode for username | a user-provided value | | sql_injection.py:24:38:24:95 | ControlFlowNode for BinaryExpr | sql_injection.py:14:15:14:22 | ControlFlowNode for username | sql_injection.py:24:38:24:95 | ControlFlowNode for BinaryExpr | This SQL query depends on $@. | sql_injection.py:14:15:14:22 | ControlFlowNode for username | a user-provided value | | sql_injection.py:25:26:25:83 | ControlFlowNode for BinaryExpr | sql_injection.py:14:15:14:22 | ControlFlowNode for username | sql_injection.py:25:26:25:83 | ControlFlowNode for BinaryExpr | This SQL query depends on $@. | sql_injection.py:14:15:14:22 | ControlFlowNode for username | a user-provided value | | sql_injection.py:26:28:26:85 | ControlFlowNode for BinaryExpr | sql_injection.py:14:15:14:22 | ControlFlowNode for username | sql_injection.py:26:28:26:85 | ControlFlowNode for BinaryExpr | This SQL query depends on $@. | sql_injection.py:14:15:14:22 | ControlFlowNode for username | a user-provided value | +| sqlalchemy_textclause.py:27:28:27:87 | ControlFlowNode for Attribute() | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:27:28:27:87 | ControlFlowNode for Attribute() | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value | +| sqlalchemy_textclause.py:31:50:31:72 | ControlFlowNode for Attribute() | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:31:50:31:72 | ControlFlowNode for Attribute() | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value | +| sqlalchemy_textclause.py:41:26:41:33 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:41:26:41:33 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value | +| sqlalchemy_textclause.py:42:31:42:38 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:42:31:42:38 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value | +| sqlalchemy_textclause.py:43:30:43:37 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:43:30:43:37 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value | +| sqlalchemy_textclause.py:44:35:44:42 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:44:35:44:42 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value | +| sqlalchemy_textclause.py:45:41:45:48 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:45:41:45:48 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value | +| sqlalchemy_textclause.py:46:46:46:53 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:46:46:46:53 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value | +| sqlalchemy_textclause.py:47:47:47:54 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:47:47:47:54 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value | +| sqlalchemy_textclause.py:48:52:48:59 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:48:52:48:59 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value | +| sqlalchemy_textclause.py:50:18:50:25 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:50:18:50:25 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value | +| sqlalchemy_textclause.py:51:24:51:31 | ControlFlowNode for username | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | sqlalchemy_textclause.py:51:24:51:31 | ControlFlowNode for username | This SQL query depends on $@. | sqlalchemy_textclause.py:23:15:23:22 | ControlFlowNode for username | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-089-SqlInjection/sqlalchemy_textclause.py b/python/ql/test/query-tests/Security/CWE-089-SqlInjection/sqlalchemy_textclause.py new file mode 100644 index 00000000000..a54d64517d4 --- /dev/null +++ b/python/ql/test/query-tests/Security/CWE-089-SqlInjection/sqlalchemy_textclause.py @@ -0,0 +1,51 @@ +from flask import Flask, request +import sqlalchemy +import sqlalchemy.orm +from flask_sqlalchemy import SQLAlchemy + +app = Flask(__name__) +engine = sqlalchemy.create_engine(...) +Base = sqlalchemy.orm.declarative_base() + +app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite+pysqlite:///:memory:" +db = SQLAlchemy(app) + + + +class User(Base): + __tablename__ = "users" + + id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True) + username = sqlalchemy.Column(sqlalchemy.String) + + +@app.route("/users/") +def show_user(username): + session = sqlalchemy.orm.Session(engine) + + # BAD, normal SQL injection + stmt = sqlalchemy.text("SELECT * FROM users WHERE username = '{}'".format(username)) + results = session.execute(stmt).fetchall() + + # BAD, allows SQL injection + username_formatted_for_sql = sqlalchemy.text("'{}'".format(username)) + stmt = sqlalchemy.select(User).where(User.username == username_formatted_for_sql) + results = session.execute(stmt).scalars().all() + + # GOOD, does not allow for SQL injection + stmt = sqlalchemy.select(User).where(User.username == username) + results = session.execute(stmt).scalars().all() + + + # All of these should be flagged by query + t1 = sqlalchemy.text(username) + t2 = sqlalchemy.text(text=username) + t3 = sqlalchemy.sql.text(username) + t4 = sqlalchemy.sql.text(text=username) + t5 = sqlalchemy.sql.expression.text(username) + t6 = sqlalchemy.sql.expression.text(text=username) + t7 = sqlalchemy.sql.expression.TextClause(username) + t8 = sqlalchemy.sql.expression.TextClause(text=username) + + t9 = db.text(username) + t10 = db.text(text=username) diff --git a/python/ql/test/query-tests/Security/CWE-094-CodeInjection/CodeInjection.expected b/python/ql/test/query-tests/Security/CWE-094-CodeInjection/CodeInjection.expected index de484611e03..c0bff3e7d11 100644 --- a/python/ql/test/query-tests/Security/CWE-094-CodeInjection/CodeInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-094-CodeInjection/CodeInjection.expected @@ -14,6 +14,7 @@ nodes | code_injection.py:18:16:18:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | code_injection.py:18:16:18:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | code_injection.py:21:20:21:27 | ControlFlowNode for obj_name | semmle.label | ControlFlowNode for obj_name | +subpaths #select | code_injection.py:7:10:7:13 | ControlFlowNode for code | code_injection.py:6:12:6:18 | ControlFlowNode for request | code_injection.py:7:10:7:13 | ControlFlowNode for code | $@ flows to here and is interpreted as code. | code_injection.py:6:12:6:18 | ControlFlowNode for request | A user-provided value | | code_injection.py:8:10:8:13 | ControlFlowNode for code | code_injection.py:6:12:6:18 | ControlFlowNode for request | code_injection.py:8:10:8:13 | ControlFlowNode for code | $@ flows to here and is interpreted as code. | code_injection.py:6:12:6:18 | ControlFlowNode for request | A user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.expected b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.expected index 610695f1923..cf73f12b9a4 100644 --- a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.expected +++ b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/StackTraceExposure.expected @@ -3,6 +3,8 @@ edges | test.py:31:25:31:25 | SSA variable e | test.py:32:16:32:30 | ControlFlowNode for Attribute | | test.py:49:15:49:36 | ControlFlowNode for Attribute() | test.py:50:29:50:31 | ControlFlowNode for err | | test.py:50:29:50:31 | ControlFlowNode for err | test.py:50:16:50:32 | ControlFlowNode for format_error() | +| test.py:50:29:50:31 | ControlFlowNode for err | test.py:52:18:52:20 | ControlFlowNode for msg | +| test.py:52:18:52:20 | ControlFlowNode for msg | test.py:53:12:53:27 | ControlFlowNode for BinaryExpr | nodes | test.py:16:16:16:37 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:23:25:23:25 | SSA variable e | semmle.label | SSA variable e | @@ -12,6 +14,10 @@ nodes | test.py:49:15:49:36 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:50:16:50:32 | ControlFlowNode for format_error() | semmle.label | ControlFlowNode for format_error() | | test.py:50:29:50:31 | ControlFlowNode for err | semmle.label | ControlFlowNode for err | +| test.py:52:18:52:20 | ControlFlowNode for msg | semmle.label | ControlFlowNode for msg | +| test.py:53:12:53:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +subpaths +| test.py:50:29:50:31 | ControlFlowNode for err | test.py:52:18:52:20 | ControlFlowNode for msg | test.py:53:12:53:27 | ControlFlowNode for BinaryExpr | test.py:50:16:50:32 | ControlFlowNode for format_error() | #select | test.py:16:16:16:37 | ControlFlowNode for Attribute() | test.py:16:16:16:37 | ControlFlowNode for Attribute() | test.py:16:16:16:37 | ControlFlowNode for Attribute() | $@ may be exposed to an external user | test.py:16:16:16:37 | ControlFlowNode for Attribute() | Error information | | test.py:24:16:24:16 | ControlFlowNode for e | test.py:23:25:23:25 | SSA variable e | test.py:24:16:24:16 | ControlFlowNode for e | $@ may be exposed to an external user | test.py:23:25:23:25 | SSA variable e | Error information | diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected index 92f8e072b8c..3aacfa32aa5 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected @@ -15,6 +15,7 @@ nodes | test.py:37:11:37:24 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test.py:39:22:39:35 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test.py:40:22:40:35 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | +subpaths #select | test.py:20:48:20:55 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:20:48:20:55 | ControlFlowNode for password | $@ is logged here. | test.py:19:16:19:29 | ControlFlowNode for get_password() | Sensitive data (password) | | test.py:22:58:22:65 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:22:58:22:65 | ControlFlowNode for password | $@ is logged here. | test.py:19:16:19:29 | ControlFlowNode for get_password() | Sensitive data (password) | diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/CleartextStorage.expected b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/CleartextStorage.expected index fe2ea368817..ea3b3cb4c2a 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/CleartextStorage.expected +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/CleartextStorage.expected @@ -7,6 +7,7 @@ nodes | test.py:12:21:12:24 | ControlFlowNode for cert | semmle.label | ControlFlowNode for cert | | test.py:13:22:13:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:15:26:15:29 | ControlFlowNode for cert | semmle.label | ControlFlowNode for cert | +subpaths #select | test.py:12:21:12:24 | ControlFlowNode for cert | test.py:9:12:9:21 | ControlFlowNode for get_cert() | test.py:12:21:12:24 | ControlFlowNode for cert | $@ is stored here. | test.py:9:12:9:21 | ControlFlowNode for get_cert() | Sensitive data (certificate) | | test.py:13:22:13:41 | ControlFlowNode for Attribute() | test.py:9:12:9:21 | ControlFlowNode for get_cert() | test.py:13:22:13:41 | ControlFlowNode for Attribute() | $@ is stored here. | test.py:9:12:9:21 | ControlFlowNode for get_cert() | Sensitive data (certificate) | diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.expected b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.expected index bad4be5313e..518935eb677 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.expected +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.expected @@ -13,6 +13,7 @@ nodes | test.py:8:20:8:23 | ControlFlowNode for cert | semmle.label | ControlFlowNode for cert | | test.py:9:17:9:29 | ControlFlowNode for List | semmle.label | ControlFlowNode for List | | test.py:10:25:10:29 | ControlFlowNode for lines | semmle.label | ControlFlowNode for lines | +subpaths #select | password_in_cookie.py:9:33:9:40 | ControlFlowNode for password | password_in_cookie.py:7:16:7:43 | ControlFlowNode for Attribute() | password_in_cookie.py:9:33:9:40 | ControlFlowNode for password | $@ is stored here. | password_in_cookie.py:7:16:7:43 | ControlFlowNode for Attribute() | Sensitive data (password) | | password_in_cookie.py:16:33:16:40 | ControlFlowNode for password | password_in_cookie.py:14:16:14:43 | ControlFlowNode for Attribute() | password_in_cookie.py:16:33:16:40 | ControlFlowNode for password | $@ is stored here. | password_in_cookie.py:14:16:14:43 | ControlFlowNode for Attribute() | Sensitive data (password) | diff --git a/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/WeakSensitiveDataHashing.expected b/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/WeakSensitiveDataHashing.expected index 50d4cfcc62d..afd49cad997 100644 --- a/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/WeakSensitiveDataHashing.expected +++ b/python/ql/test/query-tests/Security/CWE-327-WeakSensitiveDataHashing/WeakSensitiveDataHashing.expected @@ -56,6 +56,7 @@ nodes | test_cryptography.py:23:17:23:28 | ControlFlowNode for get_password | semmle.label | ControlFlowNode for get_password | | test_cryptography.py:23:17:23:30 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test_cryptography.py:27:19:27:27 | ControlFlowNode for dangerous | semmle.label | ControlFlowNode for dangerous | +subpaths #select | test_cryptodome.py:8:19:8:27 | ControlFlowNode for dangerous | test_cryptodome.py:2:37:2:51 | ControlFlowNode for ImportMember | test_cryptodome.py:8:19:8:27 | ControlFlowNode for dangerous | $@ is used in a hashing algorithm (MD5) that is insecure. | test_cryptodome.py:2:37:2:51 | ControlFlowNode for ImportMember | Sensitive data (certificate) | | test_cryptodome.py:8:19:8:27 | ControlFlowNode for dangerous | test_cryptodome.py:6:17:6:33 | ControlFlowNode for get_certificate() | test_cryptodome.py:8:19:8:27 | ControlFlowNode for dangerous | $@ is used in a hashing algorithm (MD5) that is insecure. | test_cryptodome.py:6:17:6:33 | ControlFlowNode for get_certificate() | Sensitive data (certificate) | diff --git a/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected b/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected index b854cbd39e2..cee0bf3ad7c 100644 --- a/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected +++ b/python/ql/test/query-tests/Security/CWE-502-UnsafeDeserialization/UnsafeDeserialization.expected @@ -11,6 +11,7 @@ nodes | unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload | | unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload | | unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | semmle.label | ControlFlowNode for payload | +subpaths #select | unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | Deserializing of $@. | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | untrusted input | | unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | Deserializing of $@. | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | untrusted input | diff --git a/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected b/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected index 8acf4426978..0be499849ff 100644 --- a/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected +++ b/python/ql/test/query-tests/Security/CWE-601-UrlRedirect/UrlRedirect.expected @@ -40,6 +40,7 @@ nodes | test.py:81:17:81:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test.py:81:17:81:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:83:21:83:26 | ControlFlowNode for unsafe | semmle.label | ControlFlowNode for unsafe | +subpaths #select | test.py:8:21:8:26 | ControlFlowNode for target | test.py:7:14:7:20 | ControlFlowNode for request | test.py:8:21:8:26 | ControlFlowNode for target | Untrusted URL redirection due to $@. | test.py:7:14:7:20 | ControlFlowNode for request | A user-provided value | | test.py:32:21:32:24 | ControlFlowNode for safe | test.py:30:17:30:23 | ControlFlowNode for request | test.py:32:21:32:24 | ControlFlowNode for safe | Untrusted URL redirection due to $@. | test.py:30:17:30:23 | ControlFlowNode for request | A user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected index 64d3daf7161..7f5cf5926c0 100644 --- a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected +++ b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected @@ -7,6 +7,7 @@ nodes | test.py:7:12:7:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:8:30:8:33 | ControlFlowNode for text | semmle.label | ControlFlowNode for text | | test.py:9:32:9:35 | ControlFlowNode for text | semmle.label | ControlFlowNode for text | +subpaths #select | test.py:8:30:8:33 | ControlFlowNode for text | test.py:7:12:7:18 | ControlFlowNode for request | test.py:8:30:8:33 | ControlFlowNode for text | This $@ that depends on $@ may run slow on strings with many repetitions of ' '. | test.py:8:21:8:23 | \\s+ | regular expression | test.py:7:12:7:18 | ControlFlowNode for request | a user-provided value | | test.py:9:32:9:35 | ControlFlowNode for text | test.py:7:12:7:18 | ControlFlowNode for request | test.py:9:32:9:35 | ControlFlowNode for text | This $@ that depends on $@ may run slow on strings with many repetitions of '99'. | test.py:9:27:9:29 | \\d+ | regular expression | test.py:7:12:7:18 | ControlFlowNode for request | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-730-ReDoS/ReDoS.expected b/python/ql/test/query-tests/Security/CWE-730-ReDoS/ReDoS.expected index 21db78dd092..4356f13755d 100644 --- a/python/ql/test/query-tests/Security/CWE-730-ReDoS/ReDoS.expected +++ b/python/ql/test/query-tests/Security/CWE-730-ReDoS/ReDoS.expected @@ -65,6 +65,8 @@ | redos.py:259:24:259:126 | (.thisisagoddamnlongstringforstresstestingthequery\|\\sthisisagoddamnlongstringforstresstestingthequery)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of ' thisisagoddamnlongstringforstresstestingthequery'. | | redos.py:262:24:262:87 | (thisisagoddamnlongstringforstresstestingthequery\|this\\w+query)* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'thisisagoddamnlongstringforstresstestingthequery'. | | redos.py:262:78:262:80 | \\w+ | This part of the regular expression may cause exponential backtracking on strings starting with 'this' and containing many repetitions of 'aquerythis'. | +| redos.py:268:28:268:39 | ([\ufffd\ufffd]\|[\ufffd\ufffd])* | This part of the regular expression may cause exponential backtracking on strings starting with 'foo' and containing many repetitions of '\ufffd'. | +| redos.py:271:28:271:41 | ((\ufffd\|\ufffd)\|(\ufffd\|\ufffd))* | This part of the regular expression may cause exponential backtracking on strings starting with 'foo' and containing many repetitions of '\ufffd'. | | redos.py:274:31:274:32 | b+ | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'b'. | | redos.py:277:48:277:50 | \\s* | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '"" a='. | | redos.py:283:26:283:27 | a+ | This part of the regular expression may cause exponential backtracking on strings containing many repetitions of 'a'. | diff --git a/python/ql/test/query-tests/Security/CWE-730-ReDoS/redos.py b/python/ql/test/query-tests/Security/CWE-730-ReDoS/redos.py index 733c594a53a..99befe42f36 100644 --- a/python/ql/test/query-tests/Security/CWE-730-ReDoS/redos.py +++ b/python/ql/test/query-tests/Security/CWE-730-ReDoS/redos.py @@ -264,11 +264,11 @@ bad61 = re.compile(r'''(thisisagoddamnlongstringforstresstestingthequery|this\w+ # GOOD good27 = re.compile(r'''(thisisagoddamnlongstringforstresstestingthequery|imanotherbutunrelatedstringcomparedtotheotherstring)*-''') -# GOOD -good28 = re.compile(r'''foo([\uDC66\uDC67]|[\uDC68\uDC69])*foo''') +# GOOD (but false positive caused by the extractor converting all four unpaired surrogates to \uFFFD) +good28 = re.compile('''foo([\uDC66\uDC67]|[\uDC68\uDC69])*foo''') -# GOOD -good29 = re.compile(r'''foo((\uDC66|\uDC67)|(\uDC68|\uDC69))*foo''') +# GOOD (but false positive caused by the extractor converting all four unpaired surrogates to \uFFFD) +good29 = re.compile('''foo((\uDC66|\uDC67)|(\uDC68|\uDC69))*foo''') # NOT GOOD (but cannot currently construct a prefix) bad62 = re.compile(r'''a{2,3}(b+)+X''') diff --git a/python/ql/test/query-tests/Statements/general/C_StyleParentheses.expected b/python/ql/test/query-tests/Statements/general/C_StyleParentheses.expected index a7fa79d219a..44ae1710468 100644 --- a/python/ql/test/query-tests/Statements/general/C_StyleParentheses.expected +++ b/python/ql/test/query-tests/Statements/general/C_StyleParentheses.expected @@ -1,4 +1,4 @@ -| test.py:109:5:109:8 | cond | Parenthesized condition in 'if' statement. | -| test.py:112:8:112:11 | cond | Parenthesized condition in 'while' statement. | -| test.py:115:9:115:12 | test | Parenthesized test in 'assert' statement. | -| test.py:118:13:118:13 | x | Parenthesized value in 'return' statement. | +| test.py:115:5:115:8 | cond | Parenthesized condition in 'if' statement. | +| test.py:118:8:118:11 | cond | Parenthesized condition in 'while' statement. | +| test.py:121:9:121:12 | test | Parenthesized test in 'assert' statement. | +| test.py:124:13:124:13 | x | Parenthesized value in 'return' statement. | diff --git a/python/ql/test/query-tests/Statements/general/ShouldUseWithStatement.expected b/python/ql/test/query-tests/Statements/general/ShouldUseWithStatement.expected index 41a8723db03..d062717bbf2 100644 --- a/python/ql/test/query-tests/Statements/general/ShouldUseWithStatement.expected +++ b/python/ql/test/query-tests/Statements/general/ShouldUseWithStatement.expected @@ -1 +1 @@ -| test.py:162:9:162:17 | Attribute() | Instance of context-manager class $@ is closed in a finally block. Consider using 'with' statement. | test.py:145:1:145:17 | class CM | CM | +| test.py:168:9:168:17 | Attribute() | Instance of context-manager class $@ is closed in a finally block. Consider using 'with' statement. | test.py:151:1:151:17 | class CM | CM | diff --git a/python/ql/test/query-tests/Statements/general/test.py b/python/ql/test/query-tests/Statements/general/test.py index 0f23a0b1681..eee63fa89e8 100644 --- a/python/ql/test/query-tests/Statements/general/test.py +++ b/python/ql/test/query-tests/Statements/general/test.py @@ -18,7 +18,7 @@ def return_in_finally(seq, x): finally: return 1 return 0 - + #Break in loop in finally #This is OK def return_in_loop_in_finally(f, seq): @@ -27,7 +27,7 @@ def return_in_loop_in_finally(f, seq): finally: for i in seq: break - + #But this is not def return_in_loop_in_finally(f, seq): try: @@ -49,7 +49,7 @@ class NonIterator(object): for x in NonIterator(): do_something(x) - + #None in for loop def dodgy_iter(x): @@ -91,8 +91,8 @@ for z in D(): - - + + def modification_of_locals(): x = 0 locals()['x'] = 1 @@ -104,6 +104,12 @@ def modification_of_locals(): return x +globals()['foo'] = 42 # OK +# in module-level scope `locals() == globals()` +# FP report from https://github.com/github/codeql/issues/6674 +locals()['foo'] = 43 # technically OK + + #C-style things if (cond): @@ -128,7 +134,7 @@ class classproperty(object): return self.getter(instance_type) class WithClassProperty(object): - + @classproperty def x(self): return [0] @@ -143,13 +149,13 @@ for i in WithClassProperty.x: #Should use context mamager class CM(object): - + def __enter__(self): pass - + def __exit__(self, ex, cls, tb): pass - + def write(self, data): pass @@ -168,4 +174,3 @@ def assert_ok(seq): # False positive. ODASA-8042. Fixed in PR #2401. class false_positive: e = (x for x in []) - diff --git a/python/ql/test/query-tests/Variables/undefined/UninitializedLocal.py b/python/ql/test/query-tests/Variables/undefined/UninitializedLocal.py index f8a8d76ad15..26e109af5a2 100644 --- a/python/ql/test/query-tests/Variables/undefined/UninitializedLocal.py +++ b/python/ql/test/query-tests/Variables/undefined/UninitializedLocal.py @@ -288,3 +288,8 @@ def avoid_redundant_split(a): var = False if var: foo.bar() #foo is defined here. + +def type_annotation_fp(): + annotated : annotation = [1,2,3] + for x in annotated: + print(x) diff --git a/python/ql/test/query-tests/Variables/unused/UnusedLocalVariable.expected b/python/ql/test/query-tests/Variables/unused/UnusedLocalVariable.expected index 339a74432bc..a902cad04cb 100644 --- a/python/ql/test/query-tests/Variables/unused/UnusedLocalVariable.expected +++ b/python/ql/test/query-tests/Variables/unused/UnusedLocalVariable.expected @@ -1,4 +1,3 @@ -| type_annotation_fp.py:5:5:5:7 | foo | The value assigned to local variable 'foo' is never used. | | variables_test.py:29:5:29:5 | x | The value assigned to local variable 'x' is never used. | | variables_test.py:89:5:89:5 | a | The value assigned to local variable 'a' is never used. | | variables_test.py:89:7:89:7 | b | The value assigned to local variable 'b' is never used. | diff --git a/python/ql/test/query-tests/Variables/unused/type_annotation_fp.py b/python/ql/test/query-tests/Variables/unused/type_annotation_fp.py index 72293f232e5..4f10f6e333e 100644 --- a/python/ql/test/query-tests/Variables/unused/type_annotation_fp.py +++ b/python/ql/test/query-tests/Variables/unused/type_annotation_fp.py @@ -9,3 +9,8 @@ def type_annotation(x): else: foo : float do_other_stuff_with(foo) + +def type_annotation_fn(): + # False negative: the value of `bar` is never used, but this is masked by the presence of the type annotation. + bar = 5 + bar : int diff --git a/python/upgrades/4f1806347d7fafe2f78508da01c01e5aff5f7cbb/old.dbscheme b/python/upgrades/4f1806347d7fafe2f78508da01c01e5aff5f7cbb/old.dbscheme new file mode 100644 index 00000000000..4f1806347d7 --- /dev/null +++ b/python/upgrades/4f1806347d7fafe2f78508da01c01e5aff5f7cbb/old.dbscheme @@ -0,0 +1,999 @@ +/* + * This dbscheme is auto-generated by 'semmle/dbscheme_gen.py'. + * WARNING: Any modifications to this file will be lost. + * Relations can be changed by modifying master.py or + * by adding rules to dbscheme.template + */ + +/* This is a dummy line to alter the dbscheme, so we can make a database upgrade + * without actually changing any of the dbscheme predicates. It contains a date + * to allow for such updates in the future as well. + * + * 2020-07-02 + * + * DO NOT remove this comment carelessly, since it can revert the dbscheme back to a + * previously seen state (matching a previously seen SHA), which would make the upgrade + * mechanism not work properly. + */ + + /* + * External artifacts + */ + +externalDefects( + unique int id : @externalDefect, + varchar(900) queryPath : string ref, + int location : @location ref, + varchar(900) message : string ref, + float severity : float ref +); + +externalMetrics( + unique int id : @externalMetric, + varchar(900) queryPath : string ref, + int location : @location ref, + float value : float ref +); + +externalData( + int id : @externalDataElement, + varchar(900) queryPath : string ref, + int column: int ref, + varchar(900) data : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/* + * Line metrics + */ +py_codelines(int id : @py_scope ref, + int count : int ref); + +py_commentlines(int id : @py_scope ref, + int count : int ref); + +py_docstringlines(int id : @py_scope ref, + int count : int ref); + +py_alllines(int id : @py_scope ref, + int count : int ref); + +/* + * Version history + */ + +svnentries( + int id : @svnentry, + varchar(500) revision : string ref, + varchar(500) author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + varchar(500) action : string ref +) + +svnentrymsg( + int id : @svnentry ref, + varchar(500) message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/**************************** + Python dbscheme +****************************/ + +/* fromSource is ignored */ +files(unique int id: @file, + varchar(900) name: string ref, + varchar(900) simple: string ref, + varchar(900) ext: string ref, + int fromSource: int ref); + +folders(unique int id: @folder, + varchar(900) name: string ref, + varchar(900) simple: string ref); + +@container = @folder | @file; + +containerparent(int parent: @container ref, + unique int child: @container ref); + +@sourceline = @file | @py_Module | @xmllocatable; + +numlines(int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref + ); + +@location = @location_ast | @location_default ; + +locations_default(unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +locations_ast(unique int id: @location_ast, + int module: @py_Module ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +file_contents(unique int file: @file ref, string contents: string ref); + +py_module_path(int module: @py_Module ref, int file: @container ref); + +variable(unique int id : @py_variable, + int scope : @py_scope ref, + varchar(1) name : string ref); + +py_line_lengths(unique int id : @py_line, + int file: @py_Module ref, + int line : int ref, + int length : int ref); + +py_extracted_version(int module : @py_Module ref, + varchar(1) version : string ref); + +/* AUTO GENERATED PART STARTS HERE */ + + +/* AnnAssign.location = 0, location */ +/* AnnAssign.value = 1, expr */ +/* AnnAssign.annotation = 2, expr */ +/* AnnAssign.target = 3, expr */ + +/* Assert.location = 0, location */ +/* Assert.test = 1, expr */ +/* Assert.msg = 2, expr */ + +/* Assign.location = 0, location */ +/* Assign.value = 1, expr */ +/* Assign.targets = 2, expr_list */ + +/* AssignExpr.location = 0, location */ +/* AssignExpr.parenthesised = 1, bool */ +/* AssignExpr.value = 2, expr */ +/* AssignExpr.target = 3, expr */ + +/* Attribute.location = 0, location */ +/* Attribute.parenthesised = 1, bool */ +/* Attribute.value = 2, expr */ +/* Attribute.attr = 3, str */ +/* Attribute.ctx = 4, expr_context */ + +/* AugAssign.location = 0, location */ +/* AugAssign.operation = 1, BinOp */ + +/* Await.location = 0, location */ +/* Await.parenthesised = 1, bool */ +/* Await.value = 2, expr */ + +/* BinaryExpr.location = 0, location */ +/* BinaryExpr.parenthesised = 1, bool */ +/* BinaryExpr.left = 2, expr */ +/* BinaryExpr.op = 3, operator */ +/* BinaryExpr.right = 4, expr */ +/* BinaryExpr = AugAssign */ + +/* BoolExpr.location = 0, location */ +/* BoolExpr.parenthesised = 1, bool */ +/* BoolExpr.op = 2, boolop */ +/* BoolExpr.values = 3, expr_list */ + +/* Break.location = 0, location */ + +/* Bytes.location = 0, location */ +/* Bytes.parenthesised = 1, bool */ +/* Bytes.s = 2, bytes */ +/* Bytes.prefix = 3, bytes */ +/* Bytes.implicitly_concatenated_parts = 4, StringPart_list */ + +/* Call.location = 0, location */ +/* Call.parenthesised = 1, bool */ +/* Call.func = 2, expr */ +/* Call.positional_args = 3, expr_list */ +/* Call.named_args = 4, dict_item_list */ + +/* Class.name = 0, str */ +/* Class.body = 1, stmt_list */ +/* Class = ClassExpr */ + +/* ClassExpr.location = 0, location */ +/* ClassExpr.parenthesised = 1, bool */ +/* ClassExpr.name = 2, str */ +/* ClassExpr.bases = 3, expr_list */ +/* ClassExpr.keywords = 4, dict_item_list */ +/* ClassExpr.inner_scope = 5, Class */ + +/* Compare.location = 0, location */ +/* Compare.parenthesised = 1, bool */ +/* Compare.left = 2, expr */ +/* Compare.ops = 3, cmpop_list */ +/* Compare.comparators = 4, expr_list */ + +/* Continue.location = 0, location */ + +/* Delete.location = 0, location */ +/* Delete.targets = 1, expr_list */ + +/* Dict.location = 0, location */ +/* Dict.parenthesised = 1, bool */ +/* Dict.items = 2, dict_item_list */ + +/* DictComp.location = 0, location */ +/* DictComp.parenthesised = 1, bool */ +/* DictComp.function = 2, Function */ +/* DictComp.iterable = 3, expr */ + +/* DictUnpacking.location = 0, location */ +/* DictUnpacking.value = 1, expr */ + +/* Ellipsis.location = 0, location */ +/* Ellipsis.parenthesised = 1, bool */ + +/* ExceptStmt.location = 0, location */ +/* ExceptStmt.type = 1, expr */ +/* ExceptStmt.name = 2, expr */ +/* ExceptStmt.body = 3, stmt_list */ + +/* Exec.location = 0, location */ +/* Exec.body = 1, expr */ +/* Exec.globals = 2, expr */ +/* Exec.locals = 3, expr */ + +/* ExprStmt.location = 0, location */ +/* ExprStmt.value = 1, expr */ + +/* Filter.location = 0, location */ +/* Filter.parenthesised = 1, bool */ +/* Filter.value = 2, expr */ +/* Filter.filter = 3, expr */ + +/* For.location = 0, location */ +/* For.target = 1, expr */ +/* For.iter = 2, expr */ +/* For.body = 3, stmt_list */ +/* For.orelse = 4, stmt_list */ +/* For.is_async = 5, bool */ + +/* FormattedValue.location = 0, location */ +/* FormattedValue.parenthesised = 1, bool */ +/* FormattedValue.value = 2, expr */ +/* FormattedValue.conversion = 3, str */ +/* FormattedValue.format_spec = 4, JoinedStr */ + +/* Function.name = 0, str */ +/* Function.args = 1, parameter_list */ +/* Function.vararg = 2, expr */ +/* Function.kwonlyargs = 3, expr_list */ +/* Function.kwarg = 4, expr */ +/* Function.body = 5, stmt_list */ +/* Function.is_async = 6, bool */ +/* Function = FunctionParent */ + +/* FunctionExpr.location = 0, location */ +/* FunctionExpr.parenthesised = 1, bool */ +/* FunctionExpr.name = 2, str */ +/* FunctionExpr.args = 3, arguments */ +/* FunctionExpr.returns = 4, expr */ +/* FunctionExpr.inner_scope = 5, Function */ + +/* GeneratorExp.location = 0, location */ +/* GeneratorExp.parenthesised = 1, bool */ +/* GeneratorExp.function = 2, Function */ +/* GeneratorExp.iterable = 3, expr */ + +/* Global.location = 0, location */ +/* Global.names = 1, str_list */ + +/* If.location = 0, location */ +/* If.test = 1, expr */ +/* If.body = 2, stmt_list */ +/* If.orelse = 3, stmt_list */ + +/* IfExp.location = 0, location */ +/* IfExp.parenthesised = 1, bool */ +/* IfExp.test = 2, expr */ +/* IfExp.body = 3, expr */ +/* IfExp.orelse = 4, expr */ + +/* Import.location = 0, location */ +/* Import.names = 1, alias_list */ + +/* ImportExpr.location = 0, location */ +/* ImportExpr.parenthesised = 1, bool */ +/* ImportExpr.level = 2, int */ +/* ImportExpr.name = 3, str */ +/* ImportExpr.top = 4, bool */ + +/* ImportStar.location = 0, location */ +/* ImportStar.module = 1, expr */ + +/* ImportMember.location = 0, location */ +/* ImportMember.parenthesised = 1, bool */ +/* ImportMember.module = 2, expr */ +/* ImportMember.name = 3, str */ + +/* Fstring.location = 0, location */ +/* Fstring.parenthesised = 1, bool */ +/* Fstring.values = 2, expr_list */ +/* Fstring = FormattedValue */ + +/* KeyValuePair.location = 0, location */ +/* KeyValuePair.value = 1, expr */ +/* KeyValuePair.key = 2, expr */ + +/* Lambda.location = 0, location */ +/* Lambda.parenthesised = 1, bool */ +/* Lambda.args = 2, arguments */ +/* Lambda.inner_scope = 3, Function */ + +/* List.location = 0, location */ +/* List.parenthesised = 1, bool */ +/* List.elts = 2, expr_list */ +/* List.ctx = 3, expr_context */ + +/* ListComp.location = 0, location */ +/* ListComp.parenthesised = 1, bool */ +/* ListComp.function = 2, Function */ +/* ListComp.iterable = 3, expr */ +/* ListComp.generators = 4, comprehension_list */ +/* ListComp.elt = 5, expr */ + +/* Module.name = 0, str */ +/* Module.hash = 1, str */ +/* Module.body = 2, stmt_list */ +/* Module.kind = 3, str */ + +/* Name.location = 0, location */ +/* Name.parenthesised = 1, bool */ +/* Name.variable = 2, variable */ +/* Name.ctx = 3, expr_context */ +/* Name = ParameterList */ + +/* Nonlocal.location = 0, location */ +/* Nonlocal.names = 1, str_list */ + +/* Num.location = 0, location */ +/* Num.parenthesised = 1, bool */ +/* Num.n = 2, number */ +/* Num.text = 3, number */ + +/* Pass.location = 0, location */ + +/* PlaceHolder.location = 0, location */ +/* PlaceHolder.parenthesised = 1, bool */ +/* PlaceHolder.variable = 2, variable */ +/* PlaceHolder.ctx = 3, expr_context */ + +/* Print.location = 0, location */ +/* Print.dest = 1, expr */ +/* Print.values = 2, expr_list */ +/* Print.nl = 3, bool */ + +/* Raise.location = 0, location */ +/* Raise.exc = 1, expr */ +/* Raise.cause = 2, expr */ +/* Raise.type = 3, expr */ +/* Raise.inst = 4, expr */ +/* Raise.tback = 5, expr */ + +/* Repr.location = 0, location */ +/* Repr.parenthesised = 1, bool */ +/* Repr.value = 2, expr */ + +/* Return.location = 0, location */ +/* Return.value = 1, expr */ + +/* Set.location = 0, location */ +/* Set.parenthesised = 1, bool */ +/* Set.elts = 2, expr_list */ + +/* SetComp.location = 0, location */ +/* SetComp.parenthesised = 1, bool */ +/* SetComp.function = 2, Function */ +/* SetComp.iterable = 3, expr */ + +/* Slice.location = 0, location */ +/* Slice.parenthesised = 1, bool */ +/* Slice.start = 2, expr */ +/* Slice.stop = 3, expr */ +/* Slice.step = 4, expr */ + +/* SpecialOperation.location = 0, location */ +/* SpecialOperation.parenthesised = 1, bool */ +/* SpecialOperation.name = 2, str */ +/* SpecialOperation.arguments = 3, expr_list */ + +/* Starred.location = 0, location */ +/* Starred.parenthesised = 1, bool */ +/* Starred.value = 2, expr */ +/* Starred.ctx = 3, expr_context */ + +/* Str.location = 0, location */ +/* Str.parenthesised = 1, bool */ +/* Str.s = 2, str */ +/* Str.prefix = 3, str */ +/* Str.implicitly_concatenated_parts = 4, StringPart_list */ + +/* StringPart.text = 0, str */ +/* StringPart.location = 1, location */ +/* StringPart = StringPartList */ +/* StringPartList = BytesOrStr */ + +/* Subscript.location = 0, location */ +/* Subscript.parenthesised = 1, bool */ +/* Subscript.value = 2, expr */ +/* Subscript.index = 3, expr */ +/* Subscript.ctx = 4, expr_context */ + +/* TemplateDottedNotation.location = 0, location */ +/* TemplateDottedNotation.parenthesised = 1, bool */ +/* TemplateDottedNotation.value = 2, expr */ +/* TemplateDottedNotation.attr = 3, str */ +/* TemplateDottedNotation.ctx = 4, expr_context */ + +/* TemplateWrite.location = 0, location */ +/* TemplateWrite.value = 1, expr */ + +/* Try.location = 0, location */ +/* Try.body = 1, stmt_list */ +/* Try.orelse = 2, stmt_list */ +/* Try.handlers = 3, stmt_list */ +/* Try.finalbody = 4, stmt_list */ + +/* Tuple.location = 0, location */ +/* Tuple.parenthesised = 1, bool */ +/* Tuple.elts = 2, expr_list */ +/* Tuple.ctx = 3, expr_context */ +/* Tuple = ParameterList */ + +/* UnaryExpr.location = 0, location */ +/* UnaryExpr.parenthesised = 1, bool */ +/* UnaryExpr.op = 2, unaryop */ +/* UnaryExpr.operand = 3, expr */ + +/* While.location = 0, location */ +/* While.test = 1, expr */ +/* While.body = 2, stmt_list */ +/* While.orelse = 3, stmt_list */ + +/* With.location = 0, location */ +/* With.context_expr = 1, expr */ +/* With.optional_vars = 2, expr */ +/* With.body = 3, stmt_list */ +/* With.is_async = 4, bool */ + +/* Yield.location = 0, location */ +/* Yield.parenthesised = 1, bool */ +/* Yield.value = 2, expr */ + +/* YieldFrom.location = 0, location */ +/* YieldFrom.parenthesised = 1, bool */ +/* YieldFrom.value = 2, expr */ + +/* Alias.value = 0, expr */ +/* Alias.asname = 1, expr */ +/* Alias = AliasList */ +/* AliasList = Import */ + +/* Arguments.kw_defaults = 0, expr_list */ +/* Arguments.defaults = 1, expr_list */ +/* Arguments.annotations = 2, expr_list */ +/* Arguments.varargannotation = 3, expr */ +/* Arguments.kwargannotation = 4, expr */ +/* Arguments.kw_annotations = 5, expr_list */ +/* Arguments = ArgumentsParent */ +/* boolean = BoolParent */ +/* Boolop = BoolExpr */ +/* string = Bytes */ +/* Cmpop = CmpopList */ +/* CmpopList = Compare */ + +/* Comprehension.location = 0, location */ +/* Comprehension.iter = 1, expr */ +/* Comprehension.target = 2, expr */ +/* Comprehension.ifs = 3, expr_list */ +/* Comprehension = ComprehensionList */ +/* ComprehensionList = ListComp */ +/* DictItem = DictItemList */ +/* DictItemList = DictItemListParent */ + +/* Expr.location = 0, location */ +/* Expr.parenthesised = 1, bool */ +/* Expr = ExprParent */ +/* ExprContext = ExprContextParent */ +/* ExprList = ExprListParent */ +/* int = ImportExpr */ + +/* Keyword.location = 0, location */ +/* Keyword.value = 1, expr */ +/* Keyword.arg = 2, str */ +/* Location = LocationParent */ +/* string = Num */ +/* Operator = BinaryExpr */ +/* ParameterList = Function */ + +/* Stmt.location = 0, location */ +/* Stmt = StmtList */ +/* StmtList = StmtListParent */ +/* string = StrParent */ +/* StringList = StrListParent */ +/* Unaryop = UnaryExpr */ +/* Variable = VariableParent */ +py_Classes(unique int id : @py_Class, + unique int parent : @py_ClassExpr ref); + +py_Functions(unique int id : @py_Function, + unique int parent : @py_Function_parent ref); + +py_Modules(unique int id : @py_Module); + +py_StringParts(unique int id : @py_StringPart, + int parent : @py_StringPart_list ref, + int idx : int ref); + +py_StringPart_lists(unique int id : @py_StringPart_list, + unique int parent : @py_Bytes_or_Str ref); + +py_aliases(unique int id : @py_alias, + int parent : @py_alias_list ref, + int idx : int ref); + +py_alias_lists(unique int id : @py_alias_list, + unique int parent : @py_Import ref); + +py_arguments(unique int id : @py_arguments, + unique int parent : @py_arguments_parent ref); + +py_bools(int parent : @py_bool_parent ref, + int idx : int ref); + +py_boolops(unique int id : @py_boolop, + int kind: int ref, + unique int parent : @py_BoolExpr ref); + +py_bytes(varchar(1) id : string ref, + int parent : @py_Bytes ref, + int idx : int ref); + +py_cmpops(unique int id : @py_cmpop, + int kind: int ref, + int parent : @py_cmpop_list ref, + int idx : int ref); + +py_cmpop_lists(unique int id : @py_cmpop_list, + unique int parent : @py_Compare ref); + +py_comprehensions(unique int id : @py_comprehension, + int parent : @py_comprehension_list ref, + int idx : int ref); + +py_comprehension_lists(unique int id : @py_comprehension_list, + unique int parent : @py_ListComp ref); + +py_dict_items(unique int id : @py_dict_item, + int kind: int ref, + int parent : @py_dict_item_list ref, + int idx : int ref); + +py_dict_item_lists(unique int id : @py_dict_item_list, + unique int parent : @py_dict_item_list_parent ref); + +py_exprs(unique int id : @py_expr, + int kind: int ref, + int parent : @py_expr_parent ref, + int idx : int ref); + +py_expr_contexts(unique int id : @py_expr_context, + int kind: int ref, + unique int parent : @py_expr_context_parent ref); + +py_expr_lists(unique int id : @py_expr_list, + int parent : @py_expr_list_parent ref, + int idx : int ref); + +py_ints(int id : int ref, + unique int parent : @py_ImportExpr ref); + +py_locations(unique int id : @location ref, + unique int parent : @py_location_parent ref); + +py_numbers(varchar(1) id : string ref, + int parent : @py_Num ref, + int idx : int ref); + +py_operators(unique int id : @py_operator, + int kind: int ref, + unique int parent : @py_BinaryExpr ref); + +py_parameter_lists(unique int id : @py_parameter_list, + unique int parent : @py_Function ref); + +py_stmts(unique int id : @py_stmt, + int kind: int ref, + int parent : @py_stmt_list ref, + int idx : int ref); + +py_stmt_lists(unique int id : @py_stmt_list, + int parent : @py_stmt_list_parent ref, + int idx : int ref); + +py_strs(varchar(1) id : string ref, + int parent : @py_str_parent ref, + int idx : int ref); + +py_str_lists(unique int id : @py_str_list, + unique int parent : @py_str_list_parent ref); + +py_unaryops(unique int id : @py_unaryop, + int kind: int ref, + unique int parent : @py_UnaryExpr ref); + +py_variables(int id : @py_variable ref, + unique int parent : @py_variable_parent ref); + +case @py_boolop.kind of + 0 = @py_And +| 1 = @py_Or; + +case @py_cmpop.kind of + 0 = @py_Eq +| 1 = @py_Gt +| 2 = @py_GtE +| 3 = @py_In +| 4 = @py_Is +| 5 = @py_IsNot +| 6 = @py_Lt +| 7 = @py_LtE +| 8 = @py_NotEq +| 9 = @py_NotIn; + +case @py_dict_item.kind of + 0 = @py_DictUnpacking +| 1 = @py_KeyValuePair +| 2 = @py_keyword; + +case @py_expr.kind of + 0 = @py_Attribute +| 1 = @py_BinaryExpr +| 2 = @py_BoolExpr +| 3 = @py_Bytes +| 4 = @py_Call +| 5 = @py_ClassExpr +| 6 = @py_Compare +| 7 = @py_Dict +| 8 = @py_DictComp +| 9 = @py_Ellipsis +| 10 = @py_FunctionExpr +| 11 = @py_GeneratorExp +| 12 = @py_IfExp +| 13 = @py_ImportExpr +| 14 = @py_ImportMember +| 15 = @py_Lambda +| 16 = @py_List +| 17 = @py_ListComp +| 18 = @py_Name +| 19 = @py_Num +| 20 = @py_Repr +| 21 = @py_Set +| 22 = @py_SetComp +| 23 = @py_Slice +| 24 = @py_Starred +| 25 = @py_Str +| 26 = @py_Subscript +| 27 = @py_Tuple +| 28 = @py_UnaryExpr +| 29 = @py_Yield +| 30 = @py_YieldFrom +| 31 = @py_TemplateDottedNotation +| 32 = @py_Filter +| 33 = @py_PlaceHolder +| 34 = @py_Await +| 35 = @py_Fstring +| 36 = @py_FormattedValue +| 37 = @py_AssignExpr +| 38 = @py_SpecialOperation; + +case @py_expr_context.kind of + 0 = @py_AugLoad +| 1 = @py_AugStore +| 2 = @py_Del +| 3 = @py_Load +| 4 = @py_Param +| 5 = @py_Store; + +case @py_operator.kind of + 0 = @py_Add +| 1 = @py_BitAnd +| 2 = @py_BitOr +| 3 = @py_BitXor +| 4 = @py_Div +| 5 = @py_FloorDiv +| 6 = @py_LShift +| 7 = @py_Mod +| 8 = @py_Mult +| 9 = @py_Pow +| 10 = @py_RShift +| 11 = @py_Sub +| 12 = @py_MatMult; + +case @py_stmt.kind of + 0 = @py_Assert +| 1 = @py_Assign +| 2 = @py_AugAssign +| 3 = @py_Break +| 4 = @py_Continue +| 5 = @py_Delete +| 6 = @py_ExceptStmt +| 7 = @py_Exec +| 8 = @py_Expr_stmt +| 9 = @py_For +| 10 = @py_Global +| 11 = @py_If +| 12 = @py_Import +| 13 = @py_ImportStar +| 14 = @py_Nonlocal +| 15 = @py_Pass +| 16 = @py_Print +| 17 = @py_Raise +| 18 = @py_Return +| 19 = @py_Try +| 20 = @py_While +| 21 = @py_With +| 22 = @py_TemplateWrite +| 23 = @py_AnnAssign; + +case @py_unaryop.kind of + 0 = @py_Invert +| 1 = @py_Not +| 2 = @py_UAdd +| 3 = @py_USub; + +@py_Bytes_or_Str = @py_Bytes | @py_Str; + +@py_Function_parent = @py_DictComp | @py_FunctionExpr | @py_GeneratorExp | @py_Lambda | @py_ListComp | @py_SetComp; + +@py_arguments_parent = @py_FunctionExpr | @py_Lambda; + +@py_ast_node = @py_Class | @py_Function | @py_Module | @py_StringPart | @py_comprehension | @py_dict_item | @py_expr | @py_stmt; + +@py_bool_parent = @py_For | @py_Function | @py_Print | @py_With | @py_expr; + +@py_dict_item_list_parent = @py_Call | @py_ClassExpr | @py_Dict; + +@py_expr_context_parent = @py_Attribute | @py_List | @py_Name | @py_PlaceHolder | @py_Starred | @py_Subscript | @py_TemplateDottedNotation | @py_Tuple; + +@py_expr_list_parent = @py_Assign | @py_BoolExpr | @py_Call | @py_ClassExpr | @py_Compare | @py_Delete | @py_Fstring | @py_Function | @py_List | @py_Print | @py_Set | @py_SpecialOperation | @py_Tuple | @py_arguments | @py_comprehension; + +@py_expr_or_stmt = @py_expr | @py_stmt; + +@py_expr_parent = @py_AnnAssign | @py_Assert | @py_Assign | @py_AssignExpr | @py_Attribute | @py_AugAssign | @py_Await | @py_BinaryExpr | @py_Call | @py_Compare | @py_DictComp | @py_DictUnpacking | @py_ExceptStmt | @py_Exec | @py_Expr_stmt | @py_Filter | @py_For | @py_FormattedValue | @py_Function | @py_FunctionExpr | @py_GeneratorExp | @py_If | @py_IfExp | @py_ImportMember | @py_ImportStar | @py_KeyValuePair | @py_ListComp | @py_Print | @py_Raise | @py_Repr | @py_Return | @py_SetComp | @py_Slice | @py_Starred | @py_Subscript | @py_TemplateDottedNotation | @py_TemplateWrite | @py_UnaryExpr | @py_While | @py_With | @py_Yield | @py_YieldFrom | @py_alias | @py_arguments | @py_comprehension | @py_expr_list | @py_keyword | @py_parameter_list; + +@py_location_parent = @py_DictUnpacking | @py_KeyValuePair | @py_StringPart | @py_comprehension | @py_expr | @py_keyword | @py_stmt; + +@py_parameter = @py_Name | @py_Tuple; + +@py_scope = @py_Class | @py_Function | @py_Module; + +@py_stmt_list_parent = @py_Class | @py_ExceptStmt | @py_For | @py_Function | @py_If | @py_Module | @py_Try | @py_While | @py_With; + +@py_str_list_parent = @py_Global | @py_Nonlocal; + +@py_str_parent = @py_Attribute | @py_Class | @py_ClassExpr | @py_FormattedValue | @py_Function | @py_FunctionExpr | @py_ImportExpr | @py_ImportMember | @py_Module | @py_SpecialOperation | @py_Str | @py_StringPart | @py_TemplateDottedNotation | @py_keyword | @py_str_list; + +@py_variable_parent = @py_Name | @py_PlaceHolder; + + +/* + * End of auto-generated part + */ + + + +/* Map relative names to absolute names for imports */ +py_absolute_names(int module : @py_Module ref, + varchar(1) relname : string ref, + varchar(1) absname : string ref); + +py_exports(int id : @py_Module ref, + varchar(1) name : string ref); + +/* Successor information */ +py_successors(int predecessor : @py_flow_node ref, + int successor : @py_flow_node ref); + +py_true_successors(int predecessor : @py_flow_node ref, + int successor : @py_flow_node ref); + +py_exception_successors(int predecessor : @py_flow_node ref, + int successor : @py_flow_node ref); + +py_false_successors(int predecessor : @py_flow_node ref, + int successor : @py_flow_node ref); + +py_flow_bb_node(unique int flownode : @py_flow_node, + int realnode : @py_ast_node ref, + int basicblock : @py_flow_node ref, + int index : int ref); + +py_scope_flow(int flow : @py_flow_node ref, + int scope : @py_scope ref, + int kind : int ref); + +py_idoms(unique int node : @py_flow_node ref, + int immediate_dominator : @py_flow_node ref); + +py_ssa_phi(int phi : @py_ssa_var ref, + int arg: @py_ssa_var ref); + +py_ssa_var(unique int id : @py_ssa_var, + int var : @py_variable ref); + +py_ssa_use(int node: @py_flow_node ref, + int var : @py_ssa_var ref); + +py_ssa_defn(unique int id : @py_ssa_var ref, + int node: @py_flow_node ref); + +@py_base_var = @py_variable | @py_ssa_var; + +py_scopes(unique int node : @py_expr_or_stmt ref, + int scope : @py_scope ref); + +py_scope_location(unique int id : @location ref, + unique int scope : @py_scope ref); + +py_flags_versioned(varchar(1) name : string ref, + varchar(1) value : string ref, + varchar(1) version : string ref); + +py_syntax_error_versioned(unique int id : @location ref, + varchar(1) message : string ref, + varchar(1) version : string ref); + +py_comments(unique int id : @py_comment, + varchar(1) text : string ref, + unique int location : @location ref); + +/* Type information support */ + +py_cobjects(unique int obj : @py_cobject); + +py_cobjecttypes(unique int obj : @py_cobject ref, + int typeof : @py_cobject ref); + +py_cobjectnames(unique int obj : @py_cobject ref, + varchar(1) name : string ref); + +/* Kind should be 0 for introspection, > 0 from source, as follows: + 1 from C extension source + */ +py_cobject_sources(int obj : @py_cobject ref, + int kind : int ref); + +py_cmembers_versioned(int object : @py_cobject ref, + varchar(1) name : string ref, + int member : @py_cobject ref, + varchar(1) version : string ref); + +py_citems(int object : @py_cobject ref, + int index : int ref, + int member : @py_cobject ref); + +ext_argtype(int funcid : @py_object ref, + int arg : int ref, + int typeid : @py_object ref); + +ext_rettype(int funcid : @py_object ref, + int typeid : @py_object ref); + +ext_proptype(int propid : @py_object ref, + int typeid : @py_object ref); + +ext_argreturn(int funcid : @py_object ref, + int arg : int ref); + +py_special_objects(unique int obj : @py_cobject ref, + unique varchar(1) name : string ref); + +py_decorated_object(int object : @py_object ref, + int level: int ref); + +@py_object = @py_cobject | @py_flow_node; + +@py_source_element = @py_ast_node | @container; + +/* XML Files */ + +xmlEncoding (unique int id: @file ref, varchar(900) encoding: string ref); + +xmlDTDs (unique int id: @xmldtd, + varchar(900) root: string ref, + varchar(900) publicId: string ref, + varchar(900) systemId: string ref, + int fileid: @file ref); + +xmlElements (unique int id: @xmlelement, + varchar(900) name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs (unique int id: @xmlattribute, + int elementid: @xmlelement ref, + varchar(900) name: string ref, + varchar(3600) value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs (int id: @xmlnamespace, + varchar(900) prefixName: string ref, + varchar(900) URI: string ref, + int fileid: @file ref); + +xmlHasNs (int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments (unique int id: @xmlcomment, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars (unique int id: @xmlcharacters, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations(int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; diff --git a/python/upgrades/4f1806347d7fafe2f78508da01c01e5aff5f7cbb/semmlecode.python.dbscheme b/python/upgrades/4f1806347d7fafe2f78508da01c01e5aff5f7cbb/semmlecode.python.dbscheme new file mode 100644 index 00000000000..ff5327c074c --- /dev/null +++ b/python/upgrades/4f1806347d7fafe2f78508da01c01e5aff5f7cbb/semmlecode.python.dbscheme @@ -0,0 +1,994 @@ +/* + * This dbscheme is auto-generated by 'semmle/dbscheme_gen.py'. + * WARNING: Any modifications to this file will be lost. + * Relations can be changed by modifying master.py or + * by adding rules to dbscheme.template + */ + +/* This is a dummy line to alter the dbscheme, so we can make a database upgrade + * without actually changing any of the dbscheme predicates. It contains a date + * to allow for such updates in the future as well. + * + * 2020-07-02 + * + * DO NOT remove this comment carelessly, since it can revert the dbscheme back to a + * previously seen state (matching a previously seen SHA), which would make the upgrade + * mechanism not work properly. + */ + + /* + * External artifacts + */ + +externalDefects( + unique int id : @externalDefect, + varchar(900) queryPath : string ref, + int location : @location ref, + varchar(900) message : string ref, + float severity : float ref +); + +externalMetrics( + unique int id : @externalMetric, + varchar(900) queryPath : string ref, + int location : @location ref, + float value : float ref +); + +externalData( + int id : @externalDataElement, + varchar(900) queryPath : string ref, + int column: int ref, + varchar(900) data : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/* + * Line metrics + */ +py_codelines(int id : @py_scope ref, + int count : int ref); + +py_commentlines(int id : @py_scope ref, + int count : int ref); + +py_docstringlines(int id : @py_scope ref, + int count : int ref); + +py_alllines(int id : @py_scope ref, + int count : int ref); + +/* + * Version history + */ + +svnentries( + int id : @svnentry, + varchar(500) revision : string ref, + varchar(500) author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + varchar(500) action : string ref +) + +svnentrymsg( + int id : @svnentry ref, + varchar(500) message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/**************************** + Python dbscheme +****************************/ + +files(unique int id: @file, + varchar(900) name: string ref); + +folders(unique int id: @folder, + varchar(900) name: string ref); + +@container = @folder | @file; + +containerparent(int parent: @container ref, + unique int child: @container ref); + +@sourceline = @file | @py_Module | @xmllocatable; + +numlines(int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref + ); + +@location = @location_ast | @location_default ; + +locations_default(unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +locations_ast(unique int id: @location_ast, + int module: @py_Module ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +file_contents(unique int file: @file ref, string contents: string ref); + +py_module_path(int module: @py_Module ref, int file: @container ref); + +variable(unique int id : @py_variable, + int scope : @py_scope ref, + varchar(1) name : string ref); + +py_line_lengths(unique int id : @py_line, + int file: @py_Module ref, + int line : int ref, + int length : int ref); + +py_extracted_version(int module : @py_Module ref, + varchar(1) version : string ref); + +/* AUTO GENERATED PART STARTS HERE */ + + +/* AnnAssign.location = 0, location */ +/* AnnAssign.value = 1, expr */ +/* AnnAssign.annotation = 2, expr */ +/* AnnAssign.target = 3, expr */ + +/* Assert.location = 0, location */ +/* Assert.test = 1, expr */ +/* Assert.msg = 2, expr */ + +/* Assign.location = 0, location */ +/* Assign.value = 1, expr */ +/* Assign.targets = 2, expr_list */ + +/* AssignExpr.location = 0, location */ +/* AssignExpr.parenthesised = 1, bool */ +/* AssignExpr.value = 2, expr */ +/* AssignExpr.target = 3, expr */ + +/* Attribute.location = 0, location */ +/* Attribute.parenthesised = 1, bool */ +/* Attribute.value = 2, expr */ +/* Attribute.attr = 3, str */ +/* Attribute.ctx = 4, expr_context */ + +/* AugAssign.location = 0, location */ +/* AugAssign.operation = 1, BinOp */ + +/* Await.location = 0, location */ +/* Await.parenthesised = 1, bool */ +/* Await.value = 2, expr */ + +/* BinaryExpr.location = 0, location */ +/* BinaryExpr.parenthesised = 1, bool */ +/* BinaryExpr.left = 2, expr */ +/* BinaryExpr.op = 3, operator */ +/* BinaryExpr.right = 4, expr */ +/* BinaryExpr = AugAssign */ + +/* BoolExpr.location = 0, location */ +/* BoolExpr.parenthesised = 1, bool */ +/* BoolExpr.op = 2, boolop */ +/* BoolExpr.values = 3, expr_list */ + +/* Break.location = 0, location */ + +/* Bytes.location = 0, location */ +/* Bytes.parenthesised = 1, bool */ +/* Bytes.s = 2, bytes */ +/* Bytes.prefix = 3, bytes */ +/* Bytes.implicitly_concatenated_parts = 4, StringPart_list */ + +/* Call.location = 0, location */ +/* Call.parenthesised = 1, bool */ +/* Call.func = 2, expr */ +/* Call.positional_args = 3, expr_list */ +/* Call.named_args = 4, dict_item_list */ + +/* Class.name = 0, str */ +/* Class.body = 1, stmt_list */ +/* Class = ClassExpr */ + +/* ClassExpr.location = 0, location */ +/* ClassExpr.parenthesised = 1, bool */ +/* ClassExpr.name = 2, str */ +/* ClassExpr.bases = 3, expr_list */ +/* ClassExpr.keywords = 4, dict_item_list */ +/* ClassExpr.inner_scope = 5, Class */ + +/* Compare.location = 0, location */ +/* Compare.parenthesised = 1, bool */ +/* Compare.left = 2, expr */ +/* Compare.ops = 3, cmpop_list */ +/* Compare.comparators = 4, expr_list */ + +/* Continue.location = 0, location */ + +/* Delete.location = 0, location */ +/* Delete.targets = 1, expr_list */ + +/* Dict.location = 0, location */ +/* Dict.parenthesised = 1, bool */ +/* Dict.items = 2, dict_item_list */ + +/* DictComp.location = 0, location */ +/* DictComp.parenthesised = 1, bool */ +/* DictComp.function = 2, Function */ +/* DictComp.iterable = 3, expr */ + +/* DictUnpacking.location = 0, location */ +/* DictUnpacking.value = 1, expr */ + +/* Ellipsis.location = 0, location */ +/* Ellipsis.parenthesised = 1, bool */ + +/* ExceptStmt.location = 0, location */ +/* ExceptStmt.type = 1, expr */ +/* ExceptStmt.name = 2, expr */ +/* ExceptStmt.body = 3, stmt_list */ + +/* Exec.location = 0, location */ +/* Exec.body = 1, expr */ +/* Exec.globals = 2, expr */ +/* Exec.locals = 3, expr */ + +/* ExprStmt.location = 0, location */ +/* ExprStmt.value = 1, expr */ + +/* Filter.location = 0, location */ +/* Filter.parenthesised = 1, bool */ +/* Filter.value = 2, expr */ +/* Filter.filter = 3, expr */ + +/* For.location = 0, location */ +/* For.target = 1, expr */ +/* For.iter = 2, expr */ +/* For.body = 3, stmt_list */ +/* For.orelse = 4, stmt_list */ +/* For.is_async = 5, bool */ + +/* FormattedValue.location = 0, location */ +/* FormattedValue.parenthesised = 1, bool */ +/* FormattedValue.value = 2, expr */ +/* FormattedValue.conversion = 3, str */ +/* FormattedValue.format_spec = 4, JoinedStr */ + +/* Function.name = 0, str */ +/* Function.args = 1, parameter_list */ +/* Function.vararg = 2, expr */ +/* Function.kwonlyargs = 3, expr_list */ +/* Function.kwarg = 4, expr */ +/* Function.body = 5, stmt_list */ +/* Function.is_async = 6, bool */ +/* Function = FunctionParent */ + +/* FunctionExpr.location = 0, location */ +/* FunctionExpr.parenthesised = 1, bool */ +/* FunctionExpr.name = 2, str */ +/* FunctionExpr.args = 3, arguments */ +/* FunctionExpr.returns = 4, expr */ +/* FunctionExpr.inner_scope = 5, Function */ + +/* GeneratorExp.location = 0, location */ +/* GeneratorExp.parenthesised = 1, bool */ +/* GeneratorExp.function = 2, Function */ +/* GeneratorExp.iterable = 3, expr */ + +/* Global.location = 0, location */ +/* Global.names = 1, str_list */ + +/* If.location = 0, location */ +/* If.test = 1, expr */ +/* If.body = 2, stmt_list */ +/* If.orelse = 3, stmt_list */ + +/* IfExp.location = 0, location */ +/* IfExp.parenthesised = 1, bool */ +/* IfExp.test = 2, expr */ +/* IfExp.body = 3, expr */ +/* IfExp.orelse = 4, expr */ + +/* Import.location = 0, location */ +/* Import.names = 1, alias_list */ + +/* ImportExpr.location = 0, location */ +/* ImportExpr.parenthesised = 1, bool */ +/* ImportExpr.level = 2, int */ +/* ImportExpr.name = 3, str */ +/* ImportExpr.top = 4, bool */ + +/* ImportStar.location = 0, location */ +/* ImportStar.module = 1, expr */ + +/* ImportMember.location = 0, location */ +/* ImportMember.parenthesised = 1, bool */ +/* ImportMember.module = 2, expr */ +/* ImportMember.name = 3, str */ + +/* Fstring.location = 0, location */ +/* Fstring.parenthesised = 1, bool */ +/* Fstring.values = 2, expr_list */ +/* Fstring = FormattedValue */ + +/* KeyValuePair.location = 0, location */ +/* KeyValuePair.value = 1, expr */ +/* KeyValuePair.key = 2, expr */ + +/* Lambda.location = 0, location */ +/* Lambda.parenthesised = 1, bool */ +/* Lambda.args = 2, arguments */ +/* Lambda.inner_scope = 3, Function */ + +/* List.location = 0, location */ +/* List.parenthesised = 1, bool */ +/* List.elts = 2, expr_list */ +/* List.ctx = 3, expr_context */ + +/* ListComp.location = 0, location */ +/* ListComp.parenthesised = 1, bool */ +/* ListComp.function = 2, Function */ +/* ListComp.iterable = 3, expr */ +/* ListComp.generators = 4, comprehension_list */ +/* ListComp.elt = 5, expr */ + +/* Module.name = 0, str */ +/* Module.hash = 1, str */ +/* Module.body = 2, stmt_list */ +/* Module.kind = 3, str */ + +/* Name.location = 0, location */ +/* Name.parenthesised = 1, bool */ +/* Name.variable = 2, variable */ +/* Name.ctx = 3, expr_context */ +/* Name = ParameterList */ + +/* Nonlocal.location = 0, location */ +/* Nonlocal.names = 1, str_list */ + +/* Num.location = 0, location */ +/* Num.parenthesised = 1, bool */ +/* Num.n = 2, number */ +/* Num.text = 3, number */ + +/* Pass.location = 0, location */ + +/* PlaceHolder.location = 0, location */ +/* PlaceHolder.parenthesised = 1, bool */ +/* PlaceHolder.variable = 2, variable */ +/* PlaceHolder.ctx = 3, expr_context */ + +/* Print.location = 0, location */ +/* Print.dest = 1, expr */ +/* Print.values = 2, expr_list */ +/* Print.nl = 3, bool */ + +/* Raise.location = 0, location */ +/* Raise.exc = 1, expr */ +/* Raise.cause = 2, expr */ +/* Raise.type = 3, expr */ +/* Raise.inst = 4, expr */ +/* Raise.tback = 5, expr */ + +/* Repr.location = 0, location */ +/* Repr.parenthesised = 1, bool */ +/* Repr.value = 2, expr */ + +/* Return.location = 0, location */ +/* Return.value = 1, expr */ + +/* Set.location = 0, location */ +/* Set.parenthesised = 1, bool */ +/* Set.elts = 2, expr_list */ + +/* SetComp.location = 0, location */ +/* SetComp.parenthesised = 1, bool */ +/* SetComp.function = 2, Function */ +/* SetComp.iterable = 3, expr */ + +/* Slice.location = 0, location */ +/* Slice.parenthesised = 1, bool */ +/* Slice.start = 2, expr */ +/* Slice.stop = 3, expr */ +/* Slice.step = 4, expr */ + +/* SpecialOperation.location = 0, location */ +/* SpecialOperation.parenthesised = 1, bool */ +/* SpecialOperation.name = 2, str */ +/* SpecialOperation.arguments = 3, expr_list */ + +/* Starred.location = 0, location */ +/* Starred.parenthesised = 1, bool */ +/* Starred.value = 2, expr */ +/* Starred.ctx = 3, expr_context */ + +/* Str.location = 0, location */ +/* Str.parenthesised = 1, bool */ +/* Str.s = 2, str */ +/* Str.prefix = 3, str */ +/* Str.implicitly_concatenated_parts = 4, StringPart_list */ + +/* StringPart.text = 0, str */ +/* StringPart.location = 1, location */ +/* StringPart = StringPartList */ +/* StringPartList = BytesOrStr */ + +/* Subscript.location = 0, location */ +/* Subscript.parenthesised = 1, bool */ +/* Subscript.value = 2, expr */ +/* Subscript.index = 3, expr */ +/* Subscript.ctx = 4, expr_context */ + +/* TemplateDottedNotation.location = 0, location */ +/* TemplateDottedNotation.parenthesised = 1, bool */ +/* TemplateDottedNotation.value = 2, expr */ +/* TemplateDottedNotation.attr = 3, str */ +/* TemplateDottedNotation.ctx = 4, expr_context */ + +/* TemplateWrite.location = 0, location */ +/* TemplateWrite.value = 1, expr */ + +/* Try.location = 0, location */ +/* Try.body = 1, stmt_list */ +/* Try.orelse = 2, stmt_list */ +/* Try.handlers = 3, stmt_list */ +/* Try.finalbody = 4, stmt_list */ + +/* Tuple.location = 0, location */ +/* Tuple.parenthesised = 1, bool */ +/* Tuple.elts = 2, expr_list */ +/* Tuple.ctx = 3, expr_context */ +/* Tuple = ParameterList */ + +/* UnaryExpr.location = 0, location */ +/* UnaryExpr.parenthesised = 1, bool */ +/* UnaryExpr.op = 2, unaryop */ +/* UnaryExpr.operand = 3, expr */ + +/* While.location = 0, location */ +/* While.test = 1, expr */ +/* While.body = 2, stmt_list */ +/* While.orelse = 3, stmt_list */ + +/* With.location = 0, location */ +/* With.context_expr = 1, expr */ +/* With.optional_vars = 2, expr */ +/* With.body = 3, stmt_list */ +/* With.is_async = 4, bool */ + +/* Yield.location = 0, location */ +/* Yield.parenthesised = 1, bool */ +/* Yield.value = 2, expr */ + +/* YieldFrom.location = 0, location */ +/* YieldFrom.parenthesised = 1, bool */ +/* YieldFrom.value = 2, expr */ + +/* Alias.value = 0, expr */ +/* Alias.asname = 1, expr */ +/* Alias = AliasList */ +/* AliasList = Import */ + +/* Arguments.kw_defaults = 0, expr_list */ +/* Arguments.defaults = 1, expr_list */ +/* Arguments.annotations = 2, expr_list */ +/* Arguments.varargannotation = 3, expr */ +/* Arguments.kwargannotation = 4, expr */ +/* Arguments.kw_annotations = 5, expr_list */ +/* Arguments = ArgumentsParent */ +/* boolean = BoolParent */ +/* Boolop = BoolExpr */ +/* string = Bytes */ +/* Cmpop = CmpopList */ +/* CmpopList = Compare */ + +/* Comprehension.location = 0, location */ +/* Comprehension.iter = 1, expr */ +/* Comprehension.target = 2, expr */ +/* Comprehension.ifs = 3, expr_list */ +/* Comprehension = ComprehensionList */ +/* ComprehensionList = ListComp */ +/* DictItem = DictItemList */ +/* DictItemList = DictItemListParent */ + +/* Expr.location = 0, location */ +/* Expr.parenthesised = 1, bool */ +/* Expr = ExprParent */ +/* ExprContext = ExprContextParent */ +/* ExprList = ExprListParent */ +/* int = ImportExpr */ + +/* Keyword.location = 0, location */ +/* Keyword.value = 1, expr */ +/* Keyword.arg = 2, str */ +/* Location = LocationParent */ +/* string = Num */ +/* Operator = BinaryExpr */ +/* ParameterList = Function */ + +/* Stmt.location = 0, location */ +/* Stmt = StmtList */ +/* StmtList = StmtListParent */ +/* string = StrParent */ +/* StringList = StrListParent */ +/* Unaryop = UnaryExpr */ +/* Variable = VariableParent */ +py_Classes(unique int id : @py_Class, + unique int parent : @py_ClassExpr ref); + +py_Functions(unique int id : @py_Function, + unique int parent : @py_Function_parent ref); + +py_Modules(unique int id : @py_Module); + +py_StringParts(unique int id : @py_StringPart, + int parent : @py_StringPart_list ref, + int idx : int ref); + +py_StringPart_lists(unique int id : @py_StringPart_list, + unique int parent : @py_Bytes_or_Str ref); + +py_aliases(unique int id : @py_alias, + int parent : @py_alias_list ref, + int idx : int ref); + +py_alias_lists(unique int id : @py_alias_list, + unique int parent : @py_Import ref); + +py_arguments(unique int id : @py_arguments, + unique int parent : @py_arguments_parent ref); + +py_bools(int parent : @py_bool_parent ref, + int idx : int ref); + +py_boolops(unique int id : @py_boolop, + int kind: int ref, + unique int parent : @py_BoolExpr ref); + +py_bytes(varchar(1) id : string ref, + int parent : @py_Bytes ref, + int idx : int ref); + +py_cmpops(unique int id : @py_cmpop, + int kind: int ref, + int parent : @py_cmpop_list ref, + int idx : int ref); + +py_cmpop_lists(unique int id : @py_cmpop_list, + unique int parent : @py_Compare ref); + +py_comprehensions(unique int id : @py_comprehension, + int parent : @py_comprehension_list ref, + int idx : int ref); + +py_comprehension_lists(unique int id : @py_comprehension_list, + unique int parent : @py_ListComp ref); + +py_dict_items(unique int id : @py_dict_item, + int kind: int ref, + int parent : @py_dict_item_list ref, + int idx : int ref); + +py_dict_item_lists(unique int id : @py_dict_item_list, + unique int parent : @py_dict_item_list_parent ref); + +py_exprs(unique int id : @py_expr, + int kind: int ref, + int parent : @py_expr_parent ref, + int idx : int ref); + +py_expr_contexts(unique int id : @py_expr_context, + int kind: int ref, + unique int parent : @py_expr_context_parent ref); + +py_expr_lists(unique int id : @py_expr_list, + int parent : @py_expr_list_parent ref, + int idx : int ref); + +py_ints(int id : int ref, + unique int parent : @py_ImportExpr ref); + +py_locations(unique int id : @location ref, + unique int parent : @py_location_parent ref); + +py_numbers(varchar(1) id : string ref, + int parent : @py_Num ref, + int idx : int ref); + +py_operators(unique int id : @py_operator, + int kind: int ref, + unique int parent : @py_BinaryExpr ref); + +py_parameter_lists(unique int id : @py_parameter_list, + unique int parent : @py_Function ref); + +py_stmts(unique int id : @py_stmt, + int kind: int ref, + int parent : @py_stmt_list ref, + int idx : int ref); + +py_stmt_lists(unique int id : @py_stmt_list, + int parent : @py_stmt_list_parent ref, + int idx : int ref); + +py_strs(varchar(1) id : string ref, + int parent : @py_str_parent ref, + int idx : int ref); + +py_str_lists(unique int id : @py_str_list, + unique int parent : @py_str_list_parent ref); + +py_unaryops(unique int id : @py_unaryop, + int kind: int ref, + unique int parent : @py_UnaryExpr ref); + +py_variables(int id : @py_variable ref, + unique int parent : @py_variable_parent ref); + +case @py_boolop.kind of + 0 = @py_And +| 1 = @py_Or; + +case @py_cmpop.kind of + 0 = @py_Eq +| 1 = @py_Gt +| 2 = @py_GtE +| 3 = @py_In +| 4 = @py_Is +| 5 = @py_IsNot +| 6 = @py_Lt +| 7 = @py_LtE +| 8 = @py_NotEq +| 9 = @py_NotIn; + +case @py_dict_item.kind of + 0 = @py_DictUnpacking +| 1 = @py_KeyValuePair +| 2 = @py_keyword; + +case @py_expr.kind of + 0 = @py_Attribute +| 1 = @py_BinaryExpr +| 2 = @py_BoolExpr +| 3 = @py_Bytes +| 4 = @py_Call +| 5 = @py_ClassExpr +| 6 = @py_Compare +| 7 = @py_Dict +| 8 = @py_DictComp +| 9 = @py_Ellipsis +| 10 = @py_FunctionExpr +| 11 = @py_GeneratorExp +| 12 = @py_IfExp +| 13 = @py_ImportExpr +| 14 = @py_ImportMember +| 15 = @py_Lambda +| 16 = @py_List +| 17 = @py_ListComp +| 18 = @py_Name +| 19 = @py_Num +| 20 = @py_Repr +| 21 = @py_Set +| 22 = @py_SetComp +| 23 = @py_Slice +| 24 = @py_Starred +| 25 = @py_Str +| 26 = @py_Subscript +| 27 = @py_Tuple +| 28 = @py_UnaryExpr +| 29 = @py_Yield +| 30 = @py_YieldFrom +| 31 = @py_TemplateDottedNotation +| 32 = @py_Filter +| 33 = @py_PlaceHolder +| 34 = @py_Await +| 35 = @py_Fstring +| 36 = @py_FormattedValue +| 37 = @py_AssignExpr +| 38 = @py_SpecialOperation; + +case @py_expr_context.kind of + 0 = @py_AugLoad +| 1 = @py_AugStore +| 2 = @py_Del +| 3 = @py_Load +| 4 = @py_Param +| 5 = @py_Store; + +case @py_operator.kind of + 0 = @py_Add +| 1 = @py_BitAnd +| 2 = @py_BitOr +| 3 = @py_BitXor +| 4 = @py_Div +| 5 = @py_FloorDiv +| 6 = @py_LShift +| 7 = @py_Mod +| 8 = @py_Mult +| 9 = @py_Pow +| 10 = @py_RShift +| 11 = @py_Sub +| 12 = @py_MatMult; + +case @py_stmt.kind of + 0 = @py_Assert +| 1 = @py_Assign +| 2 = @py_AugAssign +| 3 = @py_Break +| 4 = @py_Continue +| 5 = @py_Delete +| 6 = @py_ExceptStmt +| 7 = @py_Exec +| 8 = @py_Expr_stmt +| 9 = @py_For +| 10 = @py_Global +| 11 = @py_If +| 12 = @py_Import +| 13 = @py_ImportStar +| 14 = @py_Nonlocal +| 15 = @py_Pass +| 16 = @py_Print +| 17 = @py_Raise +| 18 = @py_Return +| 19 = @py_Try +| 20 = @py_While +| 21 = @py_With +| 22 = @py_TemplateWrite +| 23 = @py_AnnAssign; + +case @py_unaryop.kind of + 0 = @py_Invert +| 1 = @py_Not +| 2 = @py_UAdd +| 3 = @py_USub; + +@py_Bytes_or_Str = @py_Bytes | @py_Str; + +@py_Function_parent = @py_DictComp | @py_FunctionExpr | @py_GeneratorExp | @py_Lambda | @py_ListComp | @py_SetComp; + +@py_arguments_parent = @py_FunctionExpr | @py_Lambda; + +@py_ast_node = @py_Class | @py_Function | @py_Module | @py_StringPart | @py_comprehension | @py_dict_item | @py_expr | @py_stmt; + +@py_bool_parent = @py_For | @py_Function | @py_Print | @py_With | @py_expr; + +@py_dict_item_list_parent = @py_Call | @py_ClassExpr | @py_Dict; + +@py_expr_context_parent = @py_Attribute | @py_List | @py_Name | @py_PlaceHolder | @py_Starred | @py_Subscript | @py_TemplateDottedNotation | @py_Tuple; + +@py_expr_list_parent = @py_Assign | @py_BoolExpr | @py_Call | @py_ClassExpr | @py_Compare | @py_Delete | @py_Fstring | @py_Function | @py_List | @py_Print | @py_Set | @py_SpecialOperation | @py_Tuple | @py_arguments | @py_comprehension; + +@py_expr_or_stmt = @py_expr | @py_stmt; + +@py_expr_parent = @py_AnnAssign | @py_Assert | @py_Assign | @py_AssignExpr | @py_Attribute | @py_AugAssign | @py_Await | @py_BinaryExpr | @py_Call | @py_Compare | @py_DictComp | @py_DictUnpacking | @py_ExceptStmt | @py_Exec | @py_Expr_stmt | @py_Filter | @py_For | @py_FormattedValue | @py_Function | @py_FunctionExpr | @py_GeneratorExp | @py_If | @py_IfExp | @py_ImportMember | @py_ImportStar | @py_KeyValuePair | @py_ListComp | @py_Print | @py_Raise | @py_Repr | @py_Return | @py_SetComp | @py_Slice | @py_Starred | @py_Subscript | @py_TemplateDottedNotation | @py_TemplateWrite | @py_UnaryExpr | @py_While | @py_With | @py_Yield | @py_YieldFrom | @py_alias | @py_arguments | @py_comprehension | @py_expr_list | @py_keyword | @py_parameter_list; + +@py_location_parent = @py_DictUnpacking | @py_KeyValuePair | @py_StringPart | @py_comprehension | @py_expr | @py_keyword | @py_stmt; + +@py_parameter = @py_Name | @py_Tuple; + +@py_scope = @py_Class | @py_Function | @py_Module; + +@py_stmt_list_parent = @py_Class | @py_ExceptStmt | @py_For | @py_Function | @py_If | @py_Module | @py_Try | @py_While | @py_With; + +@py_str_list_parent = @py_Global | @py_Nonlocal; + +@py_str_parent = @py_Attribute | @py_Class | @py_ClassExpr | @py_FormattedValue | @py_Function | @py_FunctionExpr | @py_ImportExpr | @py_ImportMember | @py_Module | @py_SpecialOperation | @py_Str | @py_StringPart | @py_TemplateDottedNotation | @py_keyword | @py_str_list; + +@py_variable_parent = @py_Name | @py_PlaceHolder; + + +/* + * End of auto-generated part + */ + + + +/* Map relative names to absolute names for imports */ +py_absolute_names(int module : @py_Module ref, + varchar(1) relname : string ref, + varchar(1) absname : string ref); + +py_exports(int id : @py_Module ref, + varchar(1) name : string ref); + +/* Successor information */ +py_successors(int predecessor : @py_flow_node ref, + int successor : @py_flow_node ref); + +py_true_successors(int predecessor : @py_flow_node ref, + int successor : @py_flow_node ref); + +py_exception_successors(int predecessor : @py_flow_node ref, + int successor : @py_flow_node ref); + +py_false_successors(int predecessor : @py_flow_node ref, + int successor : @py_flow_node ref); + +py_flow_bb_node(unique int flownode : @py_flow_node, + int realnode : @py_ast_node ref, + int basicblock : @py_flow_node ref, + int index : int ref); + +py_scope_flow(int flow : @py_flow_node ref, + int scope : @py_scope ref, + int kind : int ref); + +py_idoms(unique int node : @py_flow_node ref, + int immediate_dominator : @py_flow_node ref); + +py_ssa_phi(int phi : @py_ssa_var ref, + int arg: @py_ssa_var ref); + +py_ssa_var(unique int id : @py_ssa_var, + int var : @py_variable ref); + +py_ssa_use(int node: @py_flow_node ref, + int var : @py_ssa_var ref); + +py_ssa_defn(unique int id : @py_ssa_var ref, + int node: @py_flow_node ref); + +@py_base_var = @py_variable | @py_ssa_var; + +py_scopes(unique int node : @py_expr_or_stmt ref, + int scope : @py_scope ref); + +py_scope_location(unique int id : @location ref, + unique int scope : @py_scope ref); + +py_flags_versioned(varchar(1) name : string ref, + varchar(1) value : string ref, + varchar(1) version : string ref); + +py_syntax_error_versioned(unique int id : @location ref, + varchar(1) message : string ref, + varchar(1) version : string ref); + +py_comments(unique int id : @py_comment, + varchar(1) text : string ref, + unique int location : @location ref); + +/* Type information support */ + +py_cobjects(unique int obj : @py_cobject); + +py_cobjecttypes(unique int obj : @py_cobject ref, + int typeof : @py_cobject ref); + +py_cobjectnames(unique int obj : @py_cobject ref, + varchar(1) name : string ref); + +/* Kind should be 0 for introspection, > 0 from source, as follows: + 1 from C extension source + */ +py_cobject_sources(int obj : @py_cobject ref, + int kind : int ref); + +py_cmembers_versioned(int object : @py_cobject ref, + varchar(1) name : string ref, + int member : @py_cobject ref, + varchar(1) version : string ref); + +py_citems(int object : @py_cobject ref, + int index : int ref, + int member : @py_cobject ref); + +ext_argtype(int funcid : @py_object ref, + int arg : int ref, + int typeid : @py_object ref); + +ext_rettype(int funcid : @py_object ref, + int typeid : @py_object ref); + +ext_proptype(int propid : @py_object ref, + int typeid : @py_object ref); + +ext_argreturn(int funcid : @py_object ref, + int arg : int ref); + +py_special_objects(unique int obj : @py_cobject ref, + unique varchar(1) name : string ref); + +py_decorated_object(int object : @py_object ref, + int level: int ref); + +@py_object = @py_cobject | @py_flow_node; + +@py_source_element = @py_ast_node | @container; + +/* XML Files */ + +xmlEncoding (unique int id: @file ref, varchar(900) encoding: string ref); + +xmlDTDs (unique int id: @xmldtd, + varchar(900) root: string ref, + varchar(900) publicId: string ref, + varchar(900) systemId: string ref, + int fileid: @file ref); + +xmlElements (unique int id: @xmlelement, + varchar(900) name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs (unique int id: @xmlattribute, + int elementid: @xmlelement ref, + varchar(900) name: string ref, + varchar(3600) value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs (int id: @xmlnamespace, + varchar(900) prefixName: string ref, + varchar(900) URI: string ref, + int fileid: @file ref); + +xmlHasNs (int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments (unique int id: @xmlcomment, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars (unique int id: @xmlcharacters, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations(int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; diff --git a/python/upgrades/4f1806347d7fafe2f78508da01c01e5aff5f7cbb/upgrade.properties b/python/upgrades/4f1806347d7fafe2f78508da01c01e5aff5f7cbb/upgrade.properties new file mode 100644 index 00000000000..a0c4ba602a1 --- /dev/null +++ b/python/upgrades/4f1806347d7fafe2f78508da01c01e5aff5f7cbb/upgrade.properties @@ -0,0 +1,4 @@ +description: Removed unused column from the `folders` and `files` relations +compatibility: full +files.rel: reorder files.rel (int id, string name, string simple, string ext, int fromSource) id name +folders.rel: reorder folders.rel (int id, string name, string simple) id name \ No newline at end of file