diff --git a/.github/workflows/check-change-note.yml b/.github/workflows/check-change-note.yml index 51dd61a3f73..3967c0ec921 100644 --- a/.github/workflows/check-change-note.yml +++ b/.github/workflows/check-change-note.yml @@ -11,7 +11,6 @@ on: - "*/ql/lib/**/*.yml" - "!**/experimental/**" - "!ql/**" - - "!swift/**" - ".github/workflows/check-change-note.yml" jobs: @@ -32,4 +31,4 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | gh api 'repos/${{github.repository}}/pulls/${{github.event.number}}/files' --paginate --jq '[.[].filename | select(test("/change-notes/.*[.]md$"))] | all(test("/change-notes/[0-9]{4}-[0-9]{2}-[0-9]{2}.*[.]md$") or test("/change-notes/released/[0-9]*[.][0-9]*[.][0-9]*[.]md$"))' | - grep true -c + grep true -c diff --git a/.github/workflows/ql-for-ql-build.yml b/.github/workflows/ql-for-ql-build.yml index 49d73d60fc5..10086d78d78 100644 --- a/.github/workflows/ql-for-ql-build.yml +++ b/.github/workflows/ql-for-ql-build.yml @@ -32,7 +32,7 @@ jobs: path: | ql/extractor-pack/ ql/target/release/buramu - key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-extractor-${{ hashFiles('ql/**/Cargo.lock') }}-${{ hashFiles('ql/**/*.rs') }} + key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-extractor-${{ hashFiles('ql/**/Cargo.lock') }}-${{ hashFiles('shared/tree-sitter-extractor') }}-${{ hashFiles('ql/**/*.rs') }} - name: Cache cargo if: steps.cache-extractor.outputs.cache-hit != 'true' uses: actions/cache@v3 diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index 51d1fea9697..935d9da642b 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -61,7 +61,7 @@ jobs: ruby/extractor/target/release/codeql-extractor-ruby ruby/extractor/target/release/codeql-extractor-ruby.exe ruby/extractor/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll - key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-extractor-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/Cargo.lock') }}--${{ hashFiles('ruby/extractor/**/*.rs') }} + key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-extractor-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/Cargo.lock') }}-${{ hashFiles('shared/tree-sitter-extractor') }}-${{ hashFiles('ruby/extractor/**/*.rs') }} - uses: actions/cache@v3 if: steps.cache-extractor.outputs.cache-hit != 'true' with: diff --git a/.github/workflows/sync-files.yml b/.github/workflows/sync-files.yml index afa1e78edfa..8f4678f1788 100644 --- a/.github/workflows/sync-files.yml +++ b/.github/workflows/sync-files.yml @@ -17,4 +17,6 @@ jobs: - uses: actions/checkout@v3 - name: Check synchronized files run: python config/sync-files.py + - name: Check dbscheme fragments + run: python config/sync-dbscheme-fragments.py diff --git a/config/dbscheme-fragments.json b/config/dbscheme-fragments.json new file mode 100644 index 00000000000..2a56ed57bae --- /dev/null +++ b/config/dbscheme-fragments.json @@ -0,0 +1,33 @@ +{ + "files": [ + "javascript/ql/lib/semmlecode.javascript.dbscheme", + "python/ql/lib/semmlecode.python.dbscheme", + "ruby/ql/lib/ruby.dbscheme", + "ql/ql/src/ql.dbscheme" + ], + "fragments": [ + "/*- External data -*/", + "/*- Files and folders -*/", + "/*- Diagnostic messages -*/", + "/*- Diagnostic messages: severity -*/", + "/*- Source location prefix -*/", + "/*- Lines of code -*/", + "/*- Configuration files with key value pairs -*/", + "/*- YAML -*/", + "/*- XML Files -*/", + "/*- XML: sourceline -*/", + "/*- DEPRECATED: External defects and metrics -*/", + "/*- DEPRECATED: Snapshot date -*/", + "/*- DEPRECATED: Duplicate code -*/", + "/*- DEPRECATED: Version control data -*/", + "/*- JavaScript-specific part -*/", + "/*- Ruby dbscheme -*/", + "/*- Erb dbscheme -*/", + "/*- QL dbscheme -*/", + "/*- Dbscheme dbscheme -*/", + "/*- Yaml dbscheme -*/", + "/*- Blame dbscheme -*/", + "/*- JSON dbscheme -*/", + "/*- Python dbscheme -*/" + ] +} \ No newline at end of file diff --git a/config/sync-dbscheme-fragments.py b/config/sync-dbscheme-fragments.py new file mode 100755 index 00000000000..266a504691e --- /dev/null +++ b/config/sync-dbscheme-fragments.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 + +import argparse +import json +import os +import pathlib +import re + + +def make_groups(blocks): + groups = {} + for block in blocks: + groups.setdefault("".join(block["lines"]), []).append(block) + return list(groups.values()) + + +def validate_fragments(fragments): + ok = True + for header, blocks in fragments.items(): + groups = make_groups(blocks) + if len(groups) > 1: + ok = False + print("Warning: dbscheme fragments with header '{}' are different for {}".format(header, ["{}:{}:{}".format( + group[0]["file"], group[0]["start"], group[0]["end"]) for group in groups])) + return ok + + +def main(): + script_path = os.path.realpath(__file__) + script_dir = os.path.dirname(script_path) + parser = argparse.ArgumentParser( + prog=os.path.basename(script_path), + description='Sync dbscheme fragments across files.' + ) + parser.add_argument('files', metavar='dbscheme_file', type=pathlib.Path, nargs='*', default=[], + help='dbscheme files to check') + args = parser.parse_args() + + with open(os.path.join(script_dir, "dbscheme-fragments.json"), "r") as f: + config = json.load(f) + + fragment_headers = set(config["fragments"]) + fragments = {} + ok = True + for file in args.files + config["files"]: + with open(os.path.join(os.path.dirname(script_dir), file), "r") as dbscheme: + header = None + line_number = 1 + block = {"file": file, "start": line_number, + "end": None, "lines": []} + + def end_block(): + block["end"] = line_number - 1 + if len(block["lines"]) > 0: + if header is None: + if re.match(r'(?m)\A(\s|//.*$|/\*(\**[^\*])*\*+/)*\Z', "".join(block["lines"])): + # Ignore comments at the beginning of the file + pass + else: + ok = False + print("Warning: dbscheme fragment without header: {}:{}:{}".format( + block["file"], block["start"], block["end"])) + else: + fragments.setdefault(header, []).append(block) + for line in dbscheme: + m = re.match(r"^\/\*-.*-\*\/$", line) + if m: + end_block() + header = line.strip() + if header not in fragment_headers: + ok = False + print("Warning: unknown header for dbscheme fragment: '{}': {}:{}".format( + header, file, line_number)) + block = {"file": file, "start": line_number, + "end": None, "lines": []} + block["lines"].append(line) + line_number += 1 + block["lines"].append('\n') + line_number += 1 + end_block() + if not ok or not validate_fragments(fragments): + exit(1) + + +if __name__ == "__main__": + main() 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 efd33b82a89..cc8d0cdbe94 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 @@ -210,8 +210,8 @@ class IndirectOperand extends Node { this.(RawIndirectOperand).getOperand() = operand and this.(RawIndirectOperand).getIndirectionIndex() = indirectionIndex or - this.(OperandNode).getOperand() = - Ssa::getIRRepresentationOfIndirectOperand(operand, indirectionIndex) + nodeHasOperand(this, Ssa::getIRRepresentationOfIndirectOperand(operand, indirectionIndex), + indirectionIndex - 1) } /** Gets the underlying operand. */ @@ -250,8 +250,8 @@ class IndirectInstruction extends Node { this.(RawIndirectInstruction).getInstruction() = instr and this.(RawIndirectInstruction).getIndirectionIndex() = indirectionIndex or - this.(InstructionNode).getInstruction() = - Ssa::getIRRepresentationOfIndirectInstruction(instr, indirectionIndex) + nodeHasInstruction(this, Ssa::getIRRepresentationOfIndirectInstruction(instr, indirectionIndex), + indirectionIndex - 1) } /** Gets the underlying instruction. */ 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 7f32a27287b..9a3fd679f23 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 @@ -1640,8 +1640,15 @@ predicate localInstructionFlow(Instruction e1, Instruction e2) { localFlow(instructionNode(e1), instructionNode(e2)) } +/** + * INTERNAL: Do not use. + * + * Ideally this module would be private, but the `asExprInternal` predicate is + * needed in `DefaultTaintTrackingImpl`. Once `DefaultTaintTrackingImpl` is gone + * we can make this module private. + */ cached -private module ExprFlowCached { +module ExprFlowCached { /** * Holds if `n` is an indirect operand of a `PointerArithmeticInstruction`, and * `e` is the result of loading from the `PointerArithmeticInstruction`. @@ -1692,7 +1699,8 @@ private module ExprFlowCached { * `x[i]` steps to the expression `x[i - 1]` without traversing the * entire chain. */ - private Expr asExpr(Node n) { + cached + Expr asExprInternal(Node n) { isIndirectBaseOfArrayAccess(n, result) or not isIndirectBaseOfArrayAccess(n, _) and @@ -1704,7 +1712,7 @@ private module ExprFlowCached { * dataflow step. */ private predicate localStepFromNonExpr(Node n1, Node n2) { - not exists(asExpr(n1)) and + not exists(asExprInternal(n1)) and localFlowStep(n1, n2) } @@ -1715,7 +1723,7 @@ private module ExprFlowCached { pragma[nomagic] private predicate localStepsToExpr(Node n1, Node n2, Expr e2) { localStepFromNonExpr*(n1, n2) and - e2 = asExpr(n2) + e2 = asExprInternal(n2) } /** @@ -1726,7 +1734,7 @@ private module ExprFlowCached { exists(Node mid | localFlowStep(n1, mid) and localStepsToExpr(mid, n2, e2) and - e1 = asExpr(n1) + e1 = asExprInternal(n1) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DefaultTaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DefaultTaintTrackingImpl.qll index e21a83fcb54..960b373b4fa 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DefaultTaintTrackingImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DefaultTaintTrackingImpl.qll @@ -60,7 +60,7 @@ private DataFlow::Node getNodeForSource(Expr source) { } private DataFlow::Node getNodeForExpr(Expr node) { - result = DataFlow::exprNode(node) + node = DataFlow::ExprFlowCached::asExprInternal(result) or // Some of the sources in `isUserInput` are intended to match the value of // an expression, while others (those modeled below) are intended to match @@ -221,7 +221,7 @@ private module Cached { predicate nodeIsBarrierIn(DataFlow::Node node) { // don't use dataflow into taint sources, as this leads to duplicate results. exists(Expr source | isUserInput(source, _) | - node = DataFlow::exprNode(source) + source = DataFlow::ExprFlowCached::asExprInternal(node) or // This case goes together with the similar (but not identical) rule in // `getNodeForSource`. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRFieldFlowSteps.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRFieldFlowSteps.qll new file mode 100644 index 00000000000..f0286c00cbc --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRFieldFlowSteps.qll @@ -0,0 +1,38 @@ +/** + * Print the dataflow local store steps in IR dumps. + */ + +private import cpp +private import semmle.code.cpp.ir.IR +private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil +private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate +private import PrintIRUtilities + +/** A property provider for local IR dataflow store steps. */ +class FieldFlowPropertyProvider extends IRPropertyProvider { + override string getOperandProperty(Operand operand, string key) { + exists(PostFieldUpdateNode pfun, Content content | + key = "store " + content.toString() and + operand = pfun.getPreUpdateNode().(IndirectOperand).getOperand() and + result = + strictconcat(string element, Node node | + storeStep(node, content, pfun) and + element = nodeId(node, _, _) + | + element, ", " + ) + ) + or + exists(Node node2, Content content | + key = "read " + content.toString() and + operand = node2.(IndirectOperand).getOperand() and + result = + strictconcat(string element, Node node1 | + readStep(node1, content, node2) and + element = nodeId(node1, _, _) + | + element, ", " + ) + ) + } +} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRLocalFlow.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRLocalFlow.qll index bbe236311fb..e92a4a8933e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRLocalFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRLocalFlow.qll @@ -1,119 +1,44 @@ private import cpp -// The `ValueNumbering` library has to be imported right after `cpp` to ensure -// that the cached IR gets the same checksum here as it does in queries that use -// `ValueNumbering` without `DataFlow`. -private import semmle.code.cpp.ir.ValueNumbering private import semmle.code.cpp.ir.IR -private import semmle.code.cpp.ir.dataflow.DataFlow private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil +private import SsaInternals as Ssa private import PrintIRUtilities /** * Gets the local dataflow from other nodes in the same function to this node. */ -private string getFromFlow(DataFlow::Node useNode, int order1, int order2) { - exists(DataFlow::Node defNode, string prefix | - ( - simpleLocalFlowStep(defNode, useNode) and prefix = "" - or - any(DataFlow::Configuration cfg).isAdditionalFlowStep(defNode, useNode) and - defNode.getEnclosingCallable() = useNode.getEnclosingCallable() and - prefix = "+" - ) and - if defNode.asInstruction() = useNode.asOperand().getAnyDef() - then - // Shorthand for flow from the def of this operand. - result = prefix + "def" and - order1 = -1 and - order2 = 0 - else - if defNode.asOperand().getUse() = useNode.asInstruction() - then - // Shorthand for flow from an operand of this instruction - result = prefix + defNode.asOperand().getDumpId() and - order1 = -1 and - order2 = defNode.asOperand().getDumpSortOrder() - else result = prefix + nodeId(defNode, order1, order2) +private string getFromFlow(Node node2, int order1, int order2) { + exists(Node node1 | + simpleLocalFlowStep(node1, node2) and + result = nodeId(node1, order1, order2) ) } /** * Gets the local dataflow from this node to other nodes in the same function. */ -private string getToFlow(DataFlow::Node defNode, int order1, int order2) { - exists(DataFlow::Node useNode, string prefix | - ( - simpleLocalFlowStep(defNode, useNode) and prefix = "" - or - any(DataFlow::Configuration cfg).isAdditionalFlowStep(defNode, useNode) and - defNode.getEnclosingCallable() = useNode.getEnclosingCallable() and - prefix = "+" - ) and - if useNode.asInstruction() = defNode.asOperand().getUse() - then - // Shorthand for flow to this operand's instruction. - result = prefix + "result" and - order1 = -1 and - order2 = 0 - else result = prefix + nodeId(useNode, order1, order2) +private string getToFlow(Node node1, int order1, int order2) { + exists(Node node2 | + simpleLocalFlowStep(node1, node2) and + result = nodeId(node2, order1, order2) ) } /** * Gets the properties of the dataflow node `node`. */ -private string getNodeProperty(DataFlow::Node node, string key) { +private string getNodeProperty(Node node, string key) { // List dataflow into and out of this node. Flow into this node is printed as `src->@`, and flow // out of this node is printed as `@->dest`. key = "flow" and result = strictconcat(string flow, boolean to, int order1, int order2 | - flow = getFromFlow(node, order1, order2) + "->@" and to = false + flow = getFromFlow(node, order1, order2) + "->" + starsForNode(node) + "@" and to = false or - flow = "@->" + getToFlow(node, order1, order2) and to = true + flow = starsForNode(node) + "@->" + getToFlow(node, order1, order2) and to = true | flow, ", " order by to, order1, order2, flow ) - or - // Is this node a dataflow sink? - key = "sink" and - any(DataFlow::Configuration cfg).isSink(node) and - result = "true" - or - // Is this node a dataflow source? - key = "source" and - any(DataFlow::Configuration cfg).isSource(node) and - result = "true" - or - // Is this node a dataflow barrier, and if so, what kind? - key = "barrier" and - result = - strictconcat(string kind | - any(DataFlow::Configuration cfg).isBarrier(node) and kind = "full" - or - any(DataFlow::Configuration cfg).isBarrierIn(node) and kind = "in" - or - any(DataFlow::Configuration cfg).isBarrierOut(node) and kind = "out" - | - kind, ", " - ) - // or - // // Is there partial flow from a source to this node? - // // This property will only be emitted if partial flow is enabled by overriding - // // `DataFlow::Configuration::explorationLimit()`. - // key = "pflow" and - // result = - // strictconcat(DataFlow::PartialPathNode sourceNode, DataFlow::PartialPathNode destNode, int dist, - // int order1, int order2 | - // any(DataFlow::Configuration cfg).hasPartialFlow(sourceNode, destNode, dist) and - // destNode.getNode() = node and - // // Only print flow from a source in the same function. - // sourceNode.getNode().getEnclosingCallable() = node.getEnclosingCallable() - // | - // nodeId(sourceNode.getNode(), order1, order2) + "+" + dist.toString(), ", " - // order by - // order1, order2, dist desc - // ) } /** @@ -121,16 +46,21 @@ private string getNodeProperty(DataFlow::Node node, string key) { */ class LocalFlowPropertyProvider extends IRPropertyProvider { override string getOperandProperty(Operand operand, string key) { - exists(DataFlow::Node node | - operand = node.asOperand() and + exists(Node node | + operand = [node.asOperand(), node.(RawIndirectOperand).getOperand()] and result = getNodeProperty(node, key) ) } override string getInstructionProperty(Instruction instruction, string key) { - exists(DataFlow::Node node | - instruction = node.asInstruction() and + exists(Node node | + instruction = [node.asInstruction(), node.(RawIndirectInstruction).getInstruction()] + | result = getNodeProperty(node, key) ) } + + override predicate shouldPrintOperand(Operand operand) { not Ssa::ignoreOperand(operand) } + + override predicate shouldPrintInstruction(Instruction instr) { not Ssa::ignoreInstruction(instr) } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRStoreSteps.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRStoreSteps.qll deleted file mode 100644 index 8c318216217..00000000000 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRStoreSteps.qll +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Print the dataflow local store steps in IR dumps. - */ - -private import cpp -// The `ValueNumbering` library has to be imported right after `cpp` to ensure -// that the cached IR gets the same checksum here as it does in queries that use -// `ValueNumbering` without `DataFlow`. -private import semmle.code.cpp.ir.ValueNumbering -private import semmle.code.cpp.ir.IR -private import semmle.code.cpp.ir.dataflow.DataFlow -private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil -private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate -private import PrintIRUtilities - -/** - * Property provider for local IR dataflow store steps. - */ -class LocalFlowPropertyProvider extends IRPropertyProvider { - override string getInstructionProperty(Instruction instruction, string key) { - exists(DataFlow::Node objectNode, Content content | - key = "content[" + content.toString() + "]" and - instruction = objectNode.asInstruction() and - result = - strictconcat(string element, DataFlow::Node fieldNode | - storeStep(fieldNode, content, objectNode) and - element = nodeId(fieldNode, _, _) - | - element, ", " - ) - ) - } -} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRUtilities.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRUtilities.qll index 5fc15cf986c..5c6cdebf800 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRUtilities.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/PrintIRUtilities.qll @@ -3,37 +3,59 @@ */ private import cpp -// The `ValueNumbering` library has to be imported right after `cpp` to ensure -// that the cached IR gets the same checksum here as it does in queries that use -// `ValueNumbering` without `DataFlow`. -private import semmle.code.cpp.ir.ValueNumbering private import semmle.code.cpp.ir.IR -private import semmle.code.cpp.ir.dataflow.DataFlow +private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil +private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate + +private string stars(int k) { + k = + [0 .. max([ + any(RawIndirectInstruction n).getIndirectionIndex(), + any(RawIndirectOperand n).getIndirectionIndex() + ] + )] and + (if k = 0 then result = "" else result = "*" + stars(k - 1)) +} + +string starsForNode(Node node) { + result = stars(node.(IndirectInstruction).getIndirectionIndex()) + or + result = stars(node.(IndirectOperand).getIndirectionIndex()) + or + not node instanceof IndirectInstruction and + not node instanceof IndirectOperand and + result = "" +} + +private Instruction getInstruction(Node n, string stars) { + result = [n.asInstruction(), n.(RawIndirectInstruction).getInstruction()] and + stars = starsForNode(n) +} + +private Operand getOperand(Node n, string stars) { + result = [n.asOperand(), n.(RawIndirectOperand).getOperand()] and + stars = starsForNode(n) +} /** * Gets a short ID for an IR dataflow node. * - For `Instruction`s, this is just the result ID of the instruction (e.g. `m128`). * - For `Operand`s, this is the label of the operand, prefixed with the result ID of the * instruction and a dot (e.g. `m128.left`). - * - For `Variable`s, this is the qualified name of the variable. */ -string nodeId(DataFlow::Node node, int order1, int order2) { - exists(Instruction instruction | instruction = node.asInstruction() | - result = instruction.getResultId() and +string nodeId(Node node, int order1, int order2) { + exists(Instruction instruction, string stars | instruction = getInstruction(node, stars) | + result = stars + instruction.getResultId() and order1 = instruction.getBlock().getDisplayIndex() and order2 = instruction.getDisplayIndexInBlock() ) or - exists(Operand operand, Instruction instruction | - operand = node.asOperand() and + exists(Operand operand, Instruction instruction, string stars | + operand = getOperand(node, stars) and instruction = operand.getUse() | - result = instruction.getResultId() + "." + operand.getDumpId() and + result = stars + instruction.getResultId() + "." + operand.getDumpId() and order1 = instruction.getBlock().getDisplayIndex() and order2 = instruction.getDisplayIndexInBlock() ) - or - result = "var(" + node.asVariable().getQualifiedName() + ")" and - order1 = 1000000 and - order2 = 0 } diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/dataflow/ProductFlow.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ProductFlow.qll similarity index 93% rename from cpp/ql/lib/experimental/semmle/code/cpp/dataflow/ProductFlow.qll rename to cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ProductFlow.qll index 8fd43a6ee0c..cb06245c568 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/dataflow/ProductFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ProductFlow.qll @@ -1,10 +1,29 @@ -import semmle.code.cpp.ir.dataflow.DataFlow -private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate -private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil -private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplCommon +/** + * Provides a library for global (inter-procedural) data flow analysis of two + * values "simultaneously". This can be used, for example, if you want to track + * a memory allocation as well as the size of the allocation. + * + * Intuitively, you can think of this as regular dataflow, but where each node + * in the dataflow graph has been replaced by a pair of nodes `(node1, node2)`, + * and two node pairs `(n11, n12)`, `(n21, n22)` is then connected by a dataflow + * edge if there's a regular dataflow edge between `n11` and `n21`, and `n12` + * and `n22`. + * + * Note that the above intuition does not reflect the actual implementation. + */ + +import semmle.code.cpp.dataflow.new.DataFlow +private import DataFlowPrivate +private import DataFlowUtil +private import DataFlowImplCommon private import codeql.util.Unit +/** + * Provides classes for performing global (inter-procedural) data flow analyses + * on a product dataflow graph. + */ module ProductFlow { + /** An input configuration for product data-flow. */ signature module ConfigSig { /** * Holds if `(source1, source2)` is a relevant data flow source. @@ -70,6 +89,9 @@ module ProductFlow { default predicate isBarrierIn2(DataFlow::Node node) { none() } } + /** + * The output of a global data flow computation. + */ module Global { private module StateConfig implements StateConfigSig { class FlowState1 = Unit; @@ -138,6 +160,7 @@ module ProductFlow { import GlobalWithState } + /** An input configuration for data flow using flow state. */ signature module StateConfigSig { bindingset[this] class FlowState1; @@ -247,6 +270,9 @@ module ProductFlow { default predicate isBarrierIn2(DataFlow::Node node) { none() } } + /** + * The output of a global data flow computation. + */ module GlobalWithState { class PathNode1 = Flow1::PathNode; @@ -260,6 +286,7 @@ module ProductFlow { class FlowState2 = Config::FlowState2; + /** Holds if data can flow from `(source1, source2)` to `(sink1, sink2)`. */ predicate flowPath( Flow1::PathNode source1, Flow2::PathNode source2, Flow1::PathNode sink1, Flow2::PathNode sink2 ) { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IR.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IR.qll index c96783fe6e8..79873d8366e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IR.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IR.qll @@ -77,4 +77,16 @@ class IRPropertyProvider extends TIRPropertyProvider { * Gets the value of the property named `key` for the specified operand. */ string getOperandProperty(Operand operand, string key) { none() } + + /** + * Holds if the instruction `instr` should be included when printing + * the IR instructions. + */ + predicate shouldPrintInstruction(Instruction instr) { any() } + + /** + * Holds if the operand `operand` should be included when printing the an + * instruction's operand list. + */ + predicate shouldPrintOperand(Operand operand) { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll index 78008a6c69b..4de4279b54c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll @@ -255,14 +255,28 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Holds if `i` is the `index`th instruction the block starting with `first`. */ - private Instruction getInstructionFromFirst(Instruction first, int index) = - shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) + /** Gets the index of `i` in its `IRBlock`. */ + private int getMemberIndex(Instruction i) { + startsBasicBlock(i) and + result = 0 + or + exists(Instruction iPrev | + adjacentInBlock(iPrev, i) and + result = getMemberIndex(iPrev) + 1 + ) + } + + private module BlockAdjacency = QlBuiltins::EquivalenceRelation; /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - result = getInstructionFromFirst(getFirstInstruction(block), index) + exists(Instruction first | block = MkIRBlock(first) | + first = result and index = 0 + or + index = getMemberIndex(result) and + BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) + ) } cached diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll index 2ababa6199a..b9106a7bfc7 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll @@ -42,6 +42,14 @@ private predicate shouldPrintFunction(Language::Declaration decl) { exists(PrintIRConfiguration config | config.shouldPrintFunction(decl)) } +private predicate shouldPrintInstruction(Instruction i) { + exists(IRPropertyProvider provider | provider.shouldPrintInstruction(i)) +} + +private predicate shouldPrintOperand(Operand operand) { + exists(IRPropertyProvider provider | provider.shouldPrintOperand(operand)) +} + private string getAdditionalInstructionProperty(Instruction instr, string key) { exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key)) } @@ -84,7 +92,9 @@ private string getOperandPropertyString(Operand operand) { private newtype TPrintableIRNode = TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or - TPrintableInstruction(Instruction instr) { shouldPrintFunction(instr.getEnclosingFunction()) } + TPrintableInstruction(Instruction instr) { + shouldPrintInstruction(instr) and shouldPrintFunction(instr.getEnclosingFunction()) + } /** * A node to be emitted in the IR graph. @@ -252,7 +262,8 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio private string getOperandsString() { result = concat(Operand operand | - operand = instr.getAnOperand() + operand = instr.getAnOperand() and + shouldPrintOperand(operand) | operand.getDumpString() + getOperandPropertyString(operand), ", " order by diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IR.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IR.qll index c96783fe6e8..79873d8366e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IR.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IR.qll @@ -77,4 +77,16 @@ class IRPropertyProvider extends TIRPropertyProvider { * Gets the value of the property named `key` for the specified operand. */ string getOperandProperty(Operand operand, string key) { none() } + + /** + * Holds if the instruction `instr` should be included when printing + * the IR instructions. + */ + predicate shouldPrintInstruction(Instruction instr) { any() } + + /** + * Holds if the operand `operand` should be included when printing the an + * instruction's operand list. + */ + predicate shouldPrintOperand(Operand operand) { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll index 78008a6c69b..4de4279b54c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll @@ -255,14 +255,28 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Holds if `i` is the `index`th instruction the block starting with `first`. */ - private Instruction getInstructionFromFirst(Instruction first, int index) = - shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) + /** Gets the index of `i` in its `IRBlock`. */ + private int getMemberIndex(Instruction i) { + startsBasicBlock(i) and + result = 0 + or + exists(Instruction iPrev | + adjacentInBlock(iPrev, i) and + result = getMemberIndex(iPrev) + 1 + ) + } + + private module BlockAdjacency = QlBuiltins::EquivalenceRelation; /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - result = getInstructionFromFirst(getFirstInstruction(block), index) + exists(Instruction first | block = MkIRBlock(first) | + first = result and index = 0 + or + index = getMemberIndex(result) and + BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) + ) } cached diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/PrintIR.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/PrintIR.qll index 2ababa6199a..b9106a7bfc7 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/PrintIR.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/PrintIR.qll @@ -42,6 +42,14 @@ private predicate shouldPrintFunction(Language::Declaration decl) { exists(PrintIRConfiguration config | config.shouldPrintFunction(decl)) } +private predicate shouldPrintInstruction(Instruction i) { + exists(IRPropertyProvider provider | provider.shouldPrintInstruction(i)) +} + +private predicate shouldPrintOperand(Operand operand) { + exists(IRPropertyProvider provider | provider.shouldPrintOperand(operand)) +} + private string getAdditionalInstructionProperty(Instruction instr, string key) { exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key)) } @@ -84,7 +92,9 @@ private string getOperandPropertyString(Operand operand) { private newtype TPrintableIRNode = TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or - TPrintableInstruction(Instruction instr) { shouldPrintFunction(instr.getEnclosingFunction()) } + TPrintableInstruction(Instruction instr) { + shouldPrintInstruction(instr) and shouldPrintFunction(instr.getEnclosingFunction()) + } /** * A node to be emitted in the IR graph. @@ -252,7 +262,8 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio private string getOperandsString() { result = concat(Operand operand | - operand = instr.getAnOperand() + operand = instr.getAnOperand() and + shouldPrintOperand(operand) | operand.getDumpString() + getOperandPropertyString(operand), ", " order by diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IR.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IR.qll index c96783fe6e8..79873d8366e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IR.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IR.qll @@ -77,4 +77,16 @@ class IRPropertyProvider extends TIRPropertyProvider { * Gets the value of the property named `key` for the specified operand. */ string getOperandProperty(Operand operand, string key) { none() } + + /** + * Holds if the instruction `instr` should be included when printing + * the IR instructions. + */ + predicate shouldPrintInstruction(Instruction instr) { any() } + + /** + * Holds if the operand `operand` should be included when printing the an + * instruction's operand list. + */ + predicate shouldPrintOperand(Operand operand) { any() } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll index 78008a6c69b..4de4279b54c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll @@ -255,14 +255,28 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Holds if `i` is the `index`th instruction the block starting with `first`. */ - private Instruction getInstructionFromFirst(Instruction first, int index) = - shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) + /** Gets the index of `i` in its `IRBlock`. */ + private int getMemberIndex(Instruction i) { + startsBasicBlock(i) and + result = 0 + or + exists(Instruction iPrev | + adjacentInBlock(iPrev, i) and + result = getMemberIndex(iPrev) + 1 + ) + } + + private module BlockAdjacency = QlBuiltins::EquivalenceRelation; /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - result = getInstructionFromFirst(getFirstInstruction(block), index) + exists(Instruction first | block = MkIRBlock(first) | + first = result and index = 0 + or + index = getMemberIndex(result) and + BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) + ) } cached diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll index 2ababa6199a..b9106a7bfc7 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll @@ -42,6 +42,14 @@ private predicate shouldPrintFunction(Language::Declaration decl) { exists(PrintIRConfiguration config | config.shouldPrintFunction(decl)) } +private predicate shouldPrintInstruction(Instruction i) { + exists(IRPropertyProvider provider | provider.shouldPrintInstruction(i)) +} + +private predicate shouldPrintOperand(Operand operand) { + exists(IRPropertyProvider provider | provider.shouldPrintOperand(operand)) +} + private string getAdditionalInstructionProperty(Instruction instr, string key) { exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key)) } @@ -84,7 +92,9 @@ private string getOperandPropertyString(Operand operand) { private newtype TPrintableIRNode = TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or - TPrintableInstruction(Instruction instr) { shouldPrintFunction(instr.getEnclosingFunction()) } + TPrintableInstruction(Instruction instr) { + shouldPrintInstruction(instr) and shouldPrintFunction(instr.getEnclosingFunction()) + } /** * A node to be emitted in the IR graph. @@ -252,7 +262,8 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio private string getOperandsString() { result = concat(Operand operand | - operand = instr.getAnOperand() + operand = instr.getAnOperand() and + shouldPrintOperand(operand) | operand.getDumpString() + getOperandPropertyString(operand), ", " order by diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisStage.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisStage.qll index 58c6e62fe2e..c07a3ea55a0 100644 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisStage.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisStage.qll @@ -729,7 +729,7 @@ module RangeStage< ) { exists(SemExpr e, D::Delta d1, D::Delta d2 | unequalFlowStepIntegralSsa(v, pos, e, d1, reason) and - boundedUpper(e, b, d1) and + boundedUpper(e, b, d2) and boundedLower(e, b, d2) and delta = D::fromFloat(D::toFloat(d1) + D::toFloat(d2)) ) diff --git a/cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.cpp b/cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.cpp similarity index 100% rename from cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.cpp rename to cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.cpp diff --git a/cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.qhelp b/cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.qhelp similarity index 100% rename from cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.qhelp rename to cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.qhelp diff --git a/cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.ql b/cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql similarity index 99% rename from cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.ql rename to cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql index 81d7f68a46f..0d8648aac0a 100644 --- a/cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.ql +++ b/cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql @@ -4,16 +4,17 @@ * may result in a buffer overflow. * @kind path-problem * @problem.severity error + * @security-severity 9.3 + * @precision medium * @id cpp/overrun-write * @tags reliability * security - * experimental * external/cwe/cwe-119 * external/cwe/cwe-131 */ import cpp -import experimental.semmle.code.cpp.dataflow.ProductFlow +import semmle.code.cpp.ir.dataflow.internal.ProductFlow import semmle.code.cpp.ir.IR import semmle.code.cpp.models.interfaces.Allocation import semmle.code.cpp.models.interfaces.ArrayFunction diff --git a/cpp/ql/src/change-notes/2023-05-24-overrun-write-query.md b/cpp/ql/src/change-notes/2023-05-24-overrun-write-query.md new file mode 100644 index 00000000000..32195223fcd --- /dev/null +++ b/cpp/ql/src/change-notes/2023-05-24-overrun-write-query.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `cpp/overrun-write`, to detect buffer overflows in C-style functions that manipulate buffers. diff --git a/cpp/ql/src/experimental/Likely Bugs/ArrayAccessProductFlow.ql b/cpp/ql/src/experimental/Likely Bugs/ArrayAccessProductFlow.ql index a5df698aeea..ffb9362417e 100644 --- a/cpp/ql/src/experimental/Likely Bugs/ArrayAccessProductFlow.ql +++ b/cpp/ql/src/experimental/Likely Bugs/ArrayAccessProductFlow.ql @@ -10,7 +10,7 @@ */ import cpp -import experimental.semmle.code.cpp.dataflow.ProductFlow +import semmle.code.cpp.ir.dataflow.internal.ProductFlow import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.Bound diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql index bc68a7f14d5..735375870ea 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql @@ -14,7 +14,7 @@ import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysi import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific import semmle.code.cpp.ir.IR import semmle.code.cpp.ir.dataflow.DataFlow -import PointerArithmeticToDerefFlow::PathGraph +import FieldAddressToDerefFlow::PathGraph pragma[nomagic] Instruction getABoundIn(SemBound b, IRFunction func) { @@ -42,21 +42,6 @@ bindingset[b] pragma[inline_late] predicate bounded2(Instruction i, Instruction b, int delta) { boundedImpl(i, b, delta) } -module FieldAddressToPointerArithmeticConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { isFieldAddressSource(_, source) } - - predicate isSink(DataFlow::Node sink) { - exists(PointerAddInstruction pai | pai.getLeft() = sink.asInstruction()) - } -} - -module FieldAddressToPointerArithmeticFlow = - DataFlow::Global; - -predicate isFieldAddressSource(Field f, DataFlow::Node source) { - source.asInstruction().(FieldAddressInstruction).getField() = f -} - bindingset[delta] predicate isInvalidPointerDerefSinkImpl( int delta, Instruction i, AddressOperand addr, string operation @@ -93,38 +78,95 @@ predicate isInvalidPointerDerefSink2(DataFlow::Node sink, Instruction i, string ) } -predicate isConstantSizeOverflowSource(Field f, PointerAddInstruction pai, int delta) { - exists(int size, int bound, DataFlow::Node source, DataFlow::InstructionNode sink | - FieldAddressToPointerArithmeticFlow::flow(source, sink) and - isFieldAddressSource(f, source) and - pai.getLeft() = sink.asInstruction() and - f.getUnspecifiedType().(ArrayType).getArraySize() = size and - semBounded(getSemanticExpr(pai.getRight()), any(SemZeroBound b), bound, true, _) and - delta = bound - size and - delta >= 0 and - size != 0 and - size != 1 - ) +pragma[nomagic] +predicate arrayTypeHasSizes(ArrayType arr, int baseTypeSize, int arraySize) { + arr.getBaseType().getSize() = baseTypeSize and + arr.getArraySize() = arraySize +} + +predicate pointerArithOverflow0( + PointerArithmeticInstruction pai, Field f, int size, int bound, int delta +) { + arrayTypeHasSizes(f.getUnspecifiedType(), pai.getElementSize(), size) and + semBounded(getSemanticExpr(pai.getRight()), any(SemZeroBound b), bound, true, _) and + delta = bound - size and + delta >= 0 and + size != 0 and + size != 1 } module PointerArithmeticToDerefConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { - isConstantSizeOverflowSource(_, source.asInstruction(), _) + pointerArithOverflow0(source.asInstruction(), _, _, _, _) } - pragma[inline] + predicate isBarrierIn(DataFlow::Node node) { isSource(node) } + + predicate isBarrierOut(DataFlow::Node node) { isSink(node) } + predicate isSink(DataFlow::Node sink) { isInvalidPointerDerefSink1(sink, _, _) } } module PointerArithmeticToDerefFlow = DataFlow::Global; +predicate pointerArithOverflow( + PointerArithmeticInstruction pai, Field f, int size, int bound, int delta +) { + pointerArithOverflow0(pai, f, size, bound, delta) and + PointerArithmeticToDerefFlow::flow(DataFlow::instructionNode(pai), _) +} + +module FieldAddressToDerefConfig implements DataFlow::StateConfigSig { + newtype FlowState = + additional TArray(Field f) { pointerArithOverflow(_, f, _, _, _) } or + additional TOverflowArithmetic(PointerArithmeticInstruction pai) { + pointerArithOverflow(pai, _, _, _, _) + } + + predicate isSource(DataFlow::Node source, FlowState state) { + exists(Field f | + source.asInstruction().(FieldAddressInstruction).getField() = f and + state = TArray(f) + ) + } + + predicate isSink(DataFlow::Node sink, FlowState state) { + exists(DataFlow::Node pai | + state = TOverflowArithmetic(pai.asInstruction()) and + PointerArithmeticToDerefFlow::flow(pai, sink) + ) + } + + predicate isBarrier(DataFlow::Node node, FlowState state) { none() } + + predicate isBarrierIn(DataFlow::Node node) { isSource(node, _) } + + predicate isBarrierOut(DataFlow::Node node) { isSink(node, _) } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 + ) { + exists(PointerArithmeticInstruction pai, Field f | + state1 = TArray(f) and + state2 = TOverflowArithmetic(pai) and + pai.getLeft() = node1.asInstruction() and + node2.asInstruction() = pai and + pointerArithOverflow(pai, f, _, _, _) + ) + } +} + +module FieldAddressToDerefFlow = DataFlow::GlobalWithState; + from - Field f, PointerArithmeticToDerefFlow::PathNode source, - PointerArithmeticToDerefFlow::PathNode sink, Instruction deref, string operation, int delta + Field f, FieldAddressToDerefFlow::PathNode source, PointerArithmeticInstruction pai, + FieldAddressToDerefFlow::PathNode sink, Instruction deref, string operation, int delta where - PointerArithmeticToDerefFlow::flowPath(source, sink) and + FieldAddressToDerefFlow::flowPath(source, sink) and isInvalidPointerDerefSink2(sink.getNode(), deref, operation) and - isConstantSizeOverflowSource(f, source.getNode().asInstruction(), delta) -select source, source, sink, + source.getState() = FieldAddressToDerefConfig::TArray(f) and + sink.getState() = FieldAddressToDerefConfig::TOverflowArithmetic(pai) and + pointerArithOverflow(pai, f, _, _, delta) +select pai, source, sink, "This pointer arithmetic may have an off-by-" + (delta + 1) + " error allowing it to overrun $@ at this $@.", f, f.getName(), deref, operation diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql index f5403ad4c03..07189cea9d9 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql @@ -16,7 +16,7 @@ */ import cpp -import experimental.semmle.code.cpp.dataflow.ProductFlow +import semmle.code.cpp.ir.dataflow.internal.ProductFlow import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific import semmle.code.cpp.ir.IR diff --git a/cpp/ql/test/TestUtilities/dataflow/FlowTestCommon.qll b/cpp/ql/test/TestUtilities/dataflow/FlowTestCommon.qll index d2172604384..8f393cccde5 100644 --- a/cpp/ql/test/TestUtilities/dataflow/FlowTestCommon.qll +++ b/cpp/ql/test/TestUtilities/dataflow/FlowTestCommon.qll @@ -16,18 +16,16 @@ private import semmle.code.cpp.ir.dataflow.DataFlow::DataFlow as IRDataFlow private import semmle.code.cpp.dataflow.DataFlow::DataFlow as AstDataFlow import TestUtilities.InlineExpectationsTest -class IRFlowTest extends InlineExpectationsTest { - IRFlowTest() { this = "IRFlowTest" } +module IRFlowTest implements TestSig { + string getARelevantTag() { result = "ir" } - override string getARelevantTag() { result = "ir" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { - exists(IRDataFlow::Node source, IRDataFlow::Node sink, IRDataFlow::Configuration conf, int n | + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(IRDataFlow::Node source, IRDataFlow::Node sink, int n | tag = "ir" and - conf.hasFlow(source, sink) and + Flow::flow(source, sink) and n = strictcount(int line, int column | - conf.hasFlow(any(IRDataFlow::Node otherSource | + Flow::flow(any(IRDataFlow::Node otherSource | otherSource.hasLocationInfo(_, line, column, _, _) ), sink) ) and @@ -47,20 +45,16 @@ class IRFlowTest extends InlineExpectationsTest { } } -class AstFlowTest extends InlineExpectationsTest { - AstFlowTest() { this = "ASTFlowTest" } +module AstFlowTest implements TestSig { + string getARelevantTag() { result = "ast" } - override string getARelevantTag() { result = "ast" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { - exists( - AstDataFlow::Node source, AstDataFlow::Node sink, AstDataFlow::Configuration conf, int n - | + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(AstDataFlow::Node source, AstDataFlow::Node sink, int n | tag = "ast" and - conf.hasFlow(source, sink) and + Flow::flow(source, sink) and n = strictcount(int line, int column | - conf.hasFlow(any(AstDataFlow::Node otherSource | + Flow::flow(any(AstDataFlow::Node otherSource | otherSource.hasLocationInfo(_, line, column, _, _) ), sink) ) and @@ -79,6 +73,3 @@ class AstFlowTest extends InlineExpectationsTest { ) } } - -/** DEPRECATED: Alias for AstFlowTest */ -deprecated class ASTFlowTest = AstFlowTest; diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-119/OverrunWriteProductFlow.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-119/OverrunWriteProductFlow.qlref deleted file mode 100644 index 21ced45de5d..00000000000 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-119/OverrunWriteProductFlow.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Likely Bugs/OverrunWriteProductFlow.ql \ No newline at end of file diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/constant-size/ConstantSizeArrayOffByOne.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/constant-size/ConstantSizeArrayOffByOne.expected index e201ef15af9..7d3df8cb7cb 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/constant-size/ConstantSizeArrayOffByOne.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/constant-size/ConstantSizeArrayOffByOne.expected @@ -1,37 +1,46 @@ edges -| test.cpp:66:32:66:32 | p | test.cpp:66:32:66:32 | p | -| test.cpp:66:32:66:32 | p | test.cpp:67:5:67:6 | * ... | -| test.cpp:66:32:66:32 | p | test.cpp:67:6:67:6 | p | +| test.cpp:35:10:35:12 | buf | test.cpp:35:5:35:22 | access to array | +| test.cpp:36:10:36:12 | buf | test.cpp:36:5:36:24 | access to array | +| test.cpp:43:14:43:16 | buf | test.cpp:43:9:43:19 | access to array | +| test.cpp:49:10:49:12 | buf | test.cpp:49:5:49:22 | access to array | +| test.cpp:50:10:50:12 | buf | test.cpp:50:5:50:24 | access to array | +| test.cpp:57:14:57:16 | buf | test.cpp:57:9:57:19 | access to array | +| test.cpp:61:14:61:16 | buf | test.cpp:61:9:61:19 | access to array | +| test.cpp:70:33:70:33 | p | test.cpp:72:5:72:15 | access to array | | test.cpp:77:26:77:44 | & ... | test.cpp:66:32:66:32 | p | -| test.cpp:77:26:77:44 | & ... | test.cpp:66:32:66:32 | p | -| test.cpp:77:27:77:44 | access to array | test.cpp:77:26:77:44 | & ... | +| test.cpp:77:32:77:34 | buf | test.cpp:77:26:77:44 | & ... | +| test.cpp:79:27:79:34 | buf | test.cpp:70:33:70:33 | p | +| test.cpp:79:32:79:34 | buf | test.cpp:79:27:79:34 | buf | nodes | test.cpp:35:5:35:22 | access to array | semmle.label | access to array | +| test.cpp:35:10:35:12 | buf | semmle.label | buf | | test.cpp:36:5:36:24 | access to array | semmle.label | access to array | +| test.cpp:36:10:36:12 | buf | semmle.label | buf | | test.cpp:43:9:43:19 | access to array | semmle.label | access to array | +| test.cpp:43:14:43:16 | buf | semmle.label | buf | | test.cpp:49:5:49:22 | access to array | semmle.label | access to array | +| test.cpp:49:10:49:12 | buf | semmle.label | buf | | test.cpp:50:5:50:24 | access to array | semmle.label | access to array | +| test.cpp:50:10:50:12 | buf | semmle.label | buf | | test.cpp:57:9:57:19 | access to array | semmle.label | access to array | +| test.cpp:57:14:57:16 | buf | semmle.label | buf | | test.cpp:61:9:61:19 | access to array | semmle.label | access to array | +| test.cpp:61:14:61:16 | buf | semmle.label | buf | | test.cpp:66:32:66:32 | p | semmle.label | p | -| test.cpp:66:32:66:32 | p | semmle.label | p | -| test.cpp:66:32:66:32 | p | semmle.label | p | -| test.cpp:67:5:67:6 | * ... | semmle.label | * ... | -| test.cpp:67:6:67:6 | p | semmle.label | p | +| test.cpp:70:33:70:33 | p | semmle.label | p | | test.cpp:72:5:72:15 | access to array | semmle.label | access to array | | test.cpp:77:26:77:44 | & ... | semmle.label | & ... | -| test.cpp:77:27:77:44 | access to array | semmle.label | access to array | +| test.cpp:77:32:77:34 | buf | semmle.label | buf | +| test.cpp:79:27:79:34 | buf | semmle.label | buf | +| test.cpp:79:32:79:34 | buf | semmle.label | buf | subpaths #select -| test.cpp:35:5:35:22 | access to array | test.cpp:35:5:35:22 | access to array | test.cpp:35:5:35:22 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:35:5:35:26 | Store: ... = ... | write | -| test.cpp:36:5:36:24 | access to array | test.cpp:36:5:36:24 | access to array | test.cpp:36:5:36:24 | access to array | This pointer arithmetic may have an off-by-2 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:36:5:36:28 | Store: ... = ... | write | -| test.cpp:43:9:43:19 | access to array | test.cpp:43:9:43:19 | access to array | test.cpp:43:9:43:19 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:43:9:43:23 | Store: ... = ... | write | -| test.cpp:49:5:49:22 | access to array | test.cpp:49:5:49:22 | access to array | test.cpp:49:5:49:22 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:19:9:19:11 | buf | buf | test.cpp:49:5:49:26 | Store: ... = ... | write | -| test.cpp:50:5:50:24 | access to array | test.cpp:50:5:50:24 | access to array | test.cpp:50:5:50:24 | access to array | This pointer arithmetic may have an off-by-2 error allowing it to overrun $@ at this $@. | test.cpp:19:9:19:11 | buf | buf | test.cpp:50:5:50:28 | Store: ... = ... | write | -| test.cpp:57:9:57:19 | access to array | test.cpp:57:9:57:19 | access to array | test.cpp:57:9:57:19 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:19:9:19:11 | buf | buf | test.cpp:57:9:57:23 | Store: ... = ... | write | -| test.cpp:61:9:61:19 | access to array | test.cpp:61:9:61:19 | access to array | test.cpp:61:9:61:19 | access to array | This pointer arithmetic may have an off-by-2 error allowing it to overrun $@ at this $@. | test.cpp:19:9:19:11 | buf | buf | test.cpp:61:9:61:23 | Store: ... = ... | write | -| test.cpp:72:5:72:15 | access to array | test.cpp:72:5:72:15 | access to array | test.cpp:72:5:72:15 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:72:5:72:19 | Store: ... = ... | write | -| test.cpp:77:27:77:44 | access to array | test.cpp:77:27:77:44 | access to array | test.cpp:66:32:66:32 | p | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:67:5:67:10 | Store: ... = ... | write | -| test.cpp:77:27:77:44 | access to array | test.cpp:77:27:77:44 | access to array | test.cpp:66:32:66:32 | p | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:67:5:67:10 | Store: ... = ... | write | -| test.cpp:77:27:77:44 | access to array | test.cpp:77:27:77:44 | access to array | test.cpp:67:5:67:6 | * ... | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:67:5:67:10 | Store: ... = ... | write | -| test.cpp:77:27:77:44 | access to array | test.cpp:77:27:77:44 | access to array | test.cpp:67:6:67:6 | p | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:67:5:67:10 | Store: ... = ... | write | +| test.cpp:35:5:35:22 | PointerAdd: access to array | test.cpp:35:10:35:12 | buf | test.cpp:35:5:35:22 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:35:5:35:26 | Store: ... = ... | write | +| test.cpp:36:5:36:24 | PointerAdd: access to array | test.cpp:36:10:36:12 | buf | test.cpp:36:5:36:24 | access to array | This pointer arithmetic may have an off-by-2 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:36:5:36:28 | Store: ... = ... | write | +| test.cpp:43:9:43:19 | PointerAdd: access to array | test.cpp:43:14:43:16 | buf | test.cpp:43:9:43:19 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:43:9:43:23 | Store: ... = ... | write | +| test.cpp:49:5:49:22 | PointerAdd: access to array | test.cpp:49:10:49:12 | buf | test.cpp:49:5:49:22 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:19:9:19:11 | buf | buf | test.cpp:49:5:49:26 | Store: ... = ... | write | +| test.cpp:50:5:50:24 | PointerAdd: access to array | test.cpp:50:10:50:12 | buf | test.cpp:50:5:50:24 | access to array | This pointer arithmetic may have an off-by-2 error allowing it to overrun $@ at this $@. | test.cpp:19:9:19:11 | buf | buf | test.cpp:50:5:50:28 | Store: ... = ... | write | +| test.cpp:57:9:57:19 | PointerAdd: access to array | test.cpp:57:14:57:16 | buf | test.cpp:57:9:57:19 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:19:9:19:11 | buf | buf | test.cpp:57:9:57:23 | Store: ... = ... | write | +| test.cpp:61:9:61:19 | PointerAdd: access to array | test.cpp:61:14:61:16 | buf | test.cpp:61:9:61:19 | access to array | This pointer arithmetic may have an off-by-2 error allowing it to overrun $@ at this $@. | test.cpp:19:9:19:11 | buf | buf | test.cpp:61:9:61:23 | Store: ... = ... | write | +| test.cpp:72:5:72:15 | PointerAdd: access to array | test.cpp:79:32:79:34 | buf | test.cpp:72:5:72:15 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:72:5:72:19 | Store: ... = ... | write | +| test.cpp:77:27:77:44 | PointerAdd: access to array | test.cpp:77:32:77:34 | buf | test.cpp:66:32:66:32 | p | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:67:5:67:10 | Store: ... = ... | write | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/constant-size/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/constant-size/test.cpp index df4cd7b4491..a33f43bfa49 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/constant-size/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/constant-size/test.cpp @@ -78,3 +78,45 @@ void testInterproc(BigArray *arr) { addToPointerAndAssign(arr->buf); } + +#define MAX_SIZE_BYTES 4096 + +void testCharIndex(BigArray *arr) { + char *charBuf = (char*) arr->buf; + + charBuf[MAX_SIZE_BYTES - 1] = 0; // GOOD + charBuf[MAX_SIZE_BYTES] = 0; // BAD [FALSE NEGATIVE] +} + +void testEqRefinement() { + int arr[MAX_SIZE]; + + for(int i = 0; i <= MAX_SIZE; i++) { + if(i != MAX_SIZE) { + arr[i] = 0; // GOOD + } + } +} + +void testEqRefinement2() { + int arr[MAX_SIZE]; + + int n = 0; + + for(int i = 0; i <= MAX_SIZE; i++) { + if(n == 0) { + if(i == MAX_SIZE) { + break; + } + n = arr[i]; // GOOD + continue; + } + + if (i == MAX_SIZE || n != arr[i]) { + if (i == MAX_SIZE) { + break; + } + n = arr[i]; // GOOD + } + } +} diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected index 4ef8b163372..1487088ca9f 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/InvalidPointerDeref.expected @@ -653,31 +653,24 @@ edges | test.cpp:304:15:304:26 | new[] | test.cpp:308:5:308:6 | xs | | test.cpp:308:5:308:6 | xs | test.cpp:308:5:308:11 | access to array | | test.cpp:308:5:308:11 | access to array | test.cpp:308:5:308:29 | Store: ... = ... | -| test.cpp:313:16:313:29 | new[] | test.cpp:314:17:314:18 | xs | -| test.cpp:314:17:314:18 | xs | test.cpp:314:17:314:25 | ... + ... | -| test.cpp:314:17:314:18 | xs | test.cpp:314:17:314:25 | ... + ... | -| test.cpp:314:17:314:18 | xs | test.cpp:318:13:318:20 | * ... | -| test.cpp:314:17:314:25 | ... + ... | test.cpp:318:14:318:20 | current | -| test.cpp:314:17:314:25 | ... + ... | test.cpp:318:14:318:20 | current | -| test.cpp:314:17:314:25 | ... + ... | test.cpp:320:13:320:20 | * ... | -| test.cpp:314:17:314:25 | ... + ... | test.cpp:320:13:320:20 | * ... | -| test.cpp:314:17:314:25 | ... + ... | test.cpp:320:14:320:20 | current | -| test.cpp:314:17:314:25 | ... + ... | test.cpp:320:14:320:20 | current | -| test.cpp:318:13:318:20 | * ... | test.cpp:318:14:318:20 | current | -| test.cpp:318:13:318:20 | * ... | test.cpp:320:13:320:20 | * ... | -| test.cpp:318:13:318:20 | * ... | test.cpp:320:14:320:20 | current | -| test.cpp:318:14:318:20 | current | test.cpp:314:17:314:25 | Store: ... + ... | -| test.cpp:318:14:318:20 | current | test.cpp:318:13:318:20 | Load: * ... | -| test.cpp:318:14:318:20 | current | test.cpp:320:10:320:21 | Store: -- ... | -| test.cpp:318:14:318:20 | current | test.cpp:320:12:320:21 | Load: (...) | -| test.cpp:320:13:320:20 | * ... | test.cpp:314:17:314:25 | Store: ... + ... | -| test.cpp:320:13:320:20 | * ... | test.cpp:318:13:318:20 | Load: * ... | -| test.cpp:320:13:320:20 | * ... | test.cpp:320:10:320:21 | Store: -- ... | -| test.cpp:320:13:320:20 | * ... | test.cpp:320:12:320:21 | Load: (...) | -| test.cpp:320:14:320:20 | current | test.cpp:314:17:314:25 | Store: ... + ... | -| test.cpp:320:14:320:20 | current | test.cpp:318:13:318:20 | Load: * ... | -| test.cpp:320:14:320:20 | current | test.cpp:320:10:320:21 | Store: -- ... | -| test.cpp:320:14:320:20 | current | test.cpp:320:12:320:21 | Load: (...) | +| test.cpp:313:14:313:27 | new[] | test.cpp:314:15:314:16 | xs | +| test.cpp:325:14:325:27 | new[] | test.cpp:326:15:326:16 | xs | +| test.cpp:326:15:326:16 | xs | test.cpp:326:15:326:23 | ... + ... | +| test.cpp:326:15:326:16 | xs | test.cpp:326:15:326:23 | ... + ... | +| test.cpp:326:15:326:16 | xs | test.cpp:338:8:338:15 | * ... | +| test.cpp:326:15:326:16 | xs | test.cpp:341:8:341:17 | * ... | +| test.cpp:326:15:326:23 | ... + ... | test.cpp:342:8:342:17 | * ... | +| test.cpp:326:15:326:23 | ... + ... | test.cpp:342:8:342:17 | * ... | +| test.cpp:338:8:338:15 | * ... | test.cpp:342:8:342:17 | * ... | +| test.cpp:341:8:341:17 | * ... | test.cpp:342:8:342:17 | * ... | +| test.cpp:342:8:342:17 | * ... | test.cpp:333:5:333:21 | Store: ... = ... | +| test.cpp:342:8:342:17 | * ... | test.cpp:341:5:341:21 | Store: ... = ... | +| test.cpp:347:14:347:27 | new[] | test.cpp:348:15:348:16 | xs | +| test.cpp:348:15:348:16 | xs | test.cpp:350:16:350:19 | ... ++ | +| test.cpp:348:15:348:16 | xs | test.cpp:350:16:350:19 | ... ++ | +| test.cpp:350:16:350:19 | ... ++ | test.cpp:350:15:350:19 | Load: * ... | +| test.cpp:350:16:350:19 | ... ++ | test.cpp:350:16:350:19 | ... ++ | +| test.cpp:350:16:350:19 | ... ++ | test.cpp:350:16:350:19 | ... ++ | subpaths #select | test.cpp:6:14:6:15 | Load: * ... | test.cpp:4:15:4:20 | call to malloc | test.cpp:6:14:6:15 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:4:15:4:20 | call to malloc | call to malloc | test.cpp:5:19:5:22 | size | size | @@ -703,7 +696,6 @@ subpaths | test.cpp:264:13:264:14 | Load: * ... | test.cpp:260:13:260:24 | new[] | test.cpp:264:13:264:14 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:260:13:260:24 | new[] | new[] | test.cpp:261:19:261:21 | len | len | | test.cpp:274:5:274:10 | Store: ... = ... | test.cpp:270:13:270:24 | new[] | test.cpp:274:5:274:10 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:270:13:270:24 | new[] | new[] | test.cpp:271:19:271:21 | len | len | | test.cpp:308:5:308:29 | Store: ... = ... | test.cpp:304:15:304:26 | new[] | test.cpp:308:5:308:29 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:304:15:304:26 | new[] | new[] | test.cpp:308:8:308:10 | ... + ... | ... + ... | -| test.cpp:314:17:314:25 | Store: ... + ... | test.cpp:313:16:313:29 | new[] | test.cpp:314:17:314:25 | Store: ... + ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:313:16:313:29 | new[] | new[] | test.cpp:314:22:314:25 | size | size | -| test.cpp:318:13:318:20 | Load: * ... | test.cpp:313:16:313:29 | new[] | test.cpp:318:13:318:20 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:313:16:313:29 | new[] | new[] | test.cpp:314:22:314:25 | size | size | -| test.cpp:320:10:320:21 | Store: -- ... | test.cpp:313:16:313:29 | new[] | test.cpp:320:10:320:21 | Store: -- ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:313:16:313:29 | new[] | new[] | test.cpp:314:22:314:25 | size | size | -| test.cpp:320:12:320:21 | Load: (...) | test.cpp:313:16:313:29 | new[] | test.cpp:320:12:320:21 | Load: (...) | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:313:16:313:29 | new[] | new[] | test.cpp:314:22:314:25 | size | size | +| test.cpp:333:5:333:21 | Store: ... = ... | test.cpp:325:14:325:27 | new[] | test.cpp:333:5:333:21 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:325:14:325:27 | new[] | new[] | test.cpp:326:20:326:23 | size | size | +| test.cpp:341:5:341:21 | Store: ... = ... | test.cpp:325:14:325:27 | new[] | test.cpp:341:5:341:21 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:325:14:325:27 | new[] | new[] | test.cpp:326:20:326:23 | size | size | +| test.cpp:350:15:350:19 | Load: * ... | test.cpp:347:14:347:27 | new[] | test.cpp:350:15:350:19 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:347:14:347:27 | new[] | new[] | test.cpp:348:20:348:23 | size | size | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp index 05ae4a2ac57..b6741535e42 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/pointer-deref/test.cpp @@ -310,15 +310,43 @@ void test21() { } void test22(unsigned size, int val) { - char *xs = new char[size]; - char *end = xs + size; // GOOD [FALSE POSITIVE] - char **current = &end; - do - { - if( *current - xs < 1 ) // GOOD [FALSE POSITIVE] - return; - *--(*current) = 0; // GOOD [FALSE POSITIVE] - val >>= 8; - } - while( val > 0 ); + char *xs = new char[size]; + char *end = xs + size; // GOOD + char **current = &end; + do { + if (*current - xs < 1) // GOOD + return; + *--(*current) = 0; // GOOD + val >>= 8; + } while (val > 0); +} + +void test23(unsigned size, int val) { + char *xs = new char[size]; + char *end = xs + size; + char **current = &end; + + if (val < 1) { + if(*current - xs < 1) + return; + + *--(*current) = 0; // GOOD [FALSE POSITIVE] + return; + } + + if (val < 2) { + if(*current - xs < 2) + return; + + *--(*current) = 0; // GOOD [FALSE POSITIVE] + *--(*current) = 0; // GOOD + } +} + +void test24(unsigned size) { + char *xs = new char[size]; + char *end = xs + size; + if (xs < end) { + int val = *xs++; // GOOD [FALSE POSITIVE] + } } diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.expected b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.expected index 6f00f28e455..15a586f6f32 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.expected +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.expected @@ -1,2 +1,4 @@ WARNING: Module TaintedWithPath has been deprecated and may be removed in future (tainted.ql:9,8-47) WARNING: Predicate tainted has been deprecated and may be removed in future (tainted.ql:20,49-74) +failures +testFailures diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.ql b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.ql index 177c7ac2387..92fb3994721 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.ql +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.ql @@ -38,12 +38,10 @@ predicate irTaint(Element source, TaintedWithPath::PathNode predNode, string tag ) } -class IRDefaultTaintTrackingTest extends InlineExpectationsTest { - IRDefaultTaintTrackingTest() { this = "IRDefaultTaintTrackingTest" } +module IRDefaultTaintTrackingTest implements TestSig { + string getARelevantTag() { result = ["ir-path", "ir-sink"] } - override string getARelevantTag() { result = ["ir-path", "ir-sink"] } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(Element elem, TaintedWithPath::PathNode node, int n | irTaint(_, node, tag) and elem = getElementFromPathNode(node) and @@ -67,12 +65,10 @@ class IRDefaultTaintTrackingTest extends InlineExpectationsTest { } } -class AstTaintTrackingTest extends InlineExpectationsTest { - AstTaintTrackingTest() { this = "ASTTaintTrackingTest" } +module AstTaintTrackingTest implements TestSig { + string getARelevantTag() { result = "ast" } - override string getARelevantTag() { result = "ast" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(Expr source, Element tainted, int n | tag = "ast" and astTaint(source, tainted) and @@ -100,3 +96,5 @@ class AstTaintTrackingTest extends InlineExpectationsTest { ) } } + +import MakeTest> diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.expected b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.expected index 5c235d0802d..4cac8898022 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.expected +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.expected @@ -1,2 +1,4 @@ WARNING: Module TaintedWithPath has been deprecated and may be removed in future (tainted.ql:10,8-47) WARNING: Predicate tainted has been deprecated and may be removed in future (tainted.ql:21,3-28) +failures +testFailures diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.ql b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.ql index 5c9583b800a..6b51f265d1e 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.ql +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.ql @@ -29,12 +29,10 @@ predicate irTaint(Expr source, Element sink) { TaintedWithPath::taintedWithPath(source, sink, _, _) } -class IRDefaultTaintTrackingTest extends InlineExpectationsTest { - IRDefaultTaintTrackingTest() { this = "IRDefaultTaintTrackingTest" } +module IRDefaultTaintTrackingTest implements TestSig { + string getARelevantTag() { result = "ir" } - override string getARelevantTag() { result = "ir" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(Expr source, Element tainted, int n | tag = "ir" and irTaint(source, tainted) and @@ -55,12 +53,10 @@ class IRDefaultTaintTrackingTest extends InlineExpectationsTest { } } -class AstTaintTrackingTest extends InlineExpectationsTest { - AstTaintTrackingTest() { this = "ASTTaintTrackingTest" } +module AstTaintTrackingTest implements TestSig { + string getARelevantTag() { result = "ast" } - override string getARelevantTag() { result = "ast" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(Expr source, Element tainted, int n | tag = "ast" and astTaint(source, tainted) and @@ -80,3 +76,5 @@ class AstTaintTrackingTest extends InlineExpectationsTest { ) } } + +import MakeTest> diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals/global.expected b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals/global.expected index b1d79c1079e..4ebf9d0d0e0 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals/global.expected +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals/global.expected @@ -1,2 +1,4 @@ WARNING: Predicate taintedIncludingGlobalVars has been deprecated and may be removed in future (global.ql:8,3-47) WARNING: Predicate taintedIncludingGlobalVars has been deprecated and may be removed in future (global.ql:12,3-53) +failures +testFailures diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals/global.ql b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals/global.ql index a7a8560908e..1179c76937d 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals/global.ql +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/globals/global.ql @@ -12,12 +12,10 @@ predicate irTaint(Expr source, Element sink, string globalVar) { IRDefaultTaintTracking::taintedIncludingGlobalVars(source, sink, globalVar) and globalVar != "" } -class IRGlobalDefaultTaintTrackingTest extends InlineExpectationsTest { - IRGlobalDefaultTaintTrackingTest() { this = "IRGlobalDefaultTaintTrackingTest" } +module IRGlobalDefaultTaintTrackingTest implements TestSig { + string getARelevantTag() { result = "ir" } - override string getARelevantTag() { result = "ir" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(Element tainted | tag = "ir" and irTaint(_, tainted, value) and @@ -27,12 +25,10 @@ class IRGlobalDefaultTaintTrackingTest extends InlineExpectationsTest { } } -class AstGlobalDefaultTaintTrackingTest extends InlineExpectationsTest { - AstGlobalDefaultTaintTrackingTest() { this = "ASTGlobalDefaultTaintTrackingTest" } +module AstGlobalDefaultTaintTrackingTest implements TestSig { + string getARelevantTag() { result = "ast" } - override string getARelevantTag() { result = "ast" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(Element tainted | tag = "ast" and astTaint(_, tainted, value) and @@ -41,3 +37,5 @@ class AstGlobalDefaultTaintTrackingTest extends InlineExpectationsTest { ) } } + +import MakeTest> diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/has-parameter-flow-out.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/has-parameter-flow-out.expected index e69de29bb2d..48de9172b36 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/has-parameter-flow-out.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/has-parameter-flow-out.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/has-parameter-flow-out.ql b/cpp/ql/test/library-tests/dataflow/dataflow-tests/has-parameter-flow-out.ql index bdeeccbc211..4b637fda714 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/has-parameter-flow-out.ql +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/has-parameter-flow-out.ql @@ -5,12 +5,10 @@ module AstTest { private import semmle.code.cpp.dataflow.DataFlow::DataFlow private import semmle.code.cpp.dataflow.internal.DataFlowPrivate - class AstParameterDefTest extends InlineExpectationsTest { - AstParameterDefTest() { this = "AstParameterDefTest" } + module AstParameterDefTest implements TestSig { + string getARelevantTag() { result = "ast-def" } - override string getARelevantTag() { result = "ast-def" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(Function f, Parameter p, RefParameterFinalValueNode n | p.isNamed() and n.getParameter() = p and @@ -33,12 +31,10 @@ module IRTest { (if k = 0 then result = "" else result = "*" + stars(k - 1)) } - class IRParameterDefTest extends InlineExpectationsTest { - IRParameterDefTest() { this = "IRParameterDefTest" } + module IRParameterDefTest implements TestSig { + string getARelevantTag() { result = "ir-def" } - override string getARelevantTag() { result = "ir-def" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(Function f, Parameter p, FinalParameterNode n | p.isNamed() and n.getParameter() = p and @@ -51,3 +47,5 @@ module IRTest { } } } + +import MakeTest> diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-number-of-outnodes.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-number-of-outnodes.expected index e69de29bb2d..48de9172b36 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-number-of-outnodes.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-number-of-outnodes.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-number-of-outnodes.ql b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-number-of-outnodes.ql index f5fcd216882..95423a1ec7d 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-number-of-outnodes.ql +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-number-of-outnodes.ql @@ -5,12 +5,10 @@ module AstTest { private import semmle.code.cpp.dataflow.DataFlow::DataFlow private import semmle.code.cpp.dataflow.internal.DataFlowPrivate - class AstMultipleOutNodesTest extends InlineExpectationsTest { - AstMultipleOutNodesTest() { this = "AstMultipleOutNodesTest" } + module AstMultipleOutNodesTest implements TestSig { + string getARelevantTag() { result = "ast-count(" + any(ReturnKind k).toString() + ")" } - override string getARelevantTag() { result = "ast-count(" + any(ReturnKind k).toString() + ")" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(DataFlowCall call, int n, ReturnKind kind | call.getLocation() = location and n = strictcount(getAnOutNode(call, kind)) and @@ -27,12 +25,10 @@ module IRTest { private import semmle.code.cpp.ir.dataflow.DataFlow private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate - class IRMultipleOutNodesTest extends InlineExpectationsTest { - IRMultipleOutNodesTest() { this = "IRMultipleOutNodesTest" } + module IRMultipleOutNodesTest implements TestSig { + string getARelevantTag() { result = "ir-count(" + any(ReturnKind k).toString() + ")" } - override string getARelevantTag() { result = "ir-count(" + any(ReturnKind k).toString() + ")" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(DataFlowCall call, int n, ReturnKind kind | call.getLocation() = location and n = strictcount(getAnOutNode(call, kind)) and @@ -44,3 +40,5 @@ module IRTest { } } } + +import MakeTest> diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected index e69de29bb2d..48de9172b36 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.ql b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.ql index 3847e27e2a0..ea27ec0d51d 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.ql +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.ql @@ -16,10 +16,8 @@ module AstTest { } /** Common data flow configuration to be used by tests. */ - class AstTestAllocationConfig extends DataFlow::Configuration { - AstTestAllocationConfig() { this = "ASTTestAllocationConfig" } - - override predicate isSource(DataFlow::Node source) { + module AstTestAllocationConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr().(FunctionCall).getTarget().getName() = "source" or source.asParameter().getName().matches("source%") @@ -32,18 +30,20 @@ module AstTest { exists(source.asUninitialized()) } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(FunctionCall call | call.getTarget().getName() = ["sink", "indirect_sink"] and sink.asExpr() = call.getAnArgument() ) } - override predicate isBarrier(DataFlow::Node barrier) { + predicate isBarrier(DataFlow::Node barrier) { barrier.asExpr().(VariableAccess).getTarget().hasName("barrier") or barrier = DataFlow::BarrierGuard::getABarrierNode() } } + + module AstFlow = DataFlow::Global; } module IRTest { @@ -67,10 +67,8 @@ module IRTest { } /** Common data flow configuration to be used by tests. */ - class IRTestAllocationConfig extends DataFlow::Configuration { - IRTestAllocationConfig() { this = "IRTestAllocationConfig" } - - override predicate isSource(DataFlow::Node source) { + module IRTestAllocationConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr().(FunctionCall).getTarget().getName() = "source" or source.asIndirectExpr(1).(FunctionCall).getTarget().getName() = "indirect_source" @@ -82,7 +80,7 @@ module IRTest { exists(source.asUninitialized()) } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(FunctionCall call, Expr e | e = call.getAnArgument() | call.getTarget().getName() = "sink" and sink.asExpr() = e @@ -92,7 +90,7 @@ module IRTest { ) } - override predicate isBarrier(DataFlow::Node barrier) { + predicate isBarrier(DataFlow::Node barrier) { exists(Expr barrierExpr | barrierExpr in [barrier.asExpr(), barrier.asIndirectExpr()] | barrierExpr.(VariableAccess).getTarget().hasName("barrier") ) @@ -102,4 +100,8 @@ module IRTest { barrier = DataFlow::BarrierGuard::getAnIndirectBarrierNode() } } + + module IRFlow = DataFlow::Global; } + +import MakeTest, IRFlowTest>> diff --git a/cpp/ql/test/library-tests/dataflow/fields/ASTConfiguration.qll b/cpp/ql/test/library-tests/dataflow/fields/ASTConfiguration.qll index 39d6cff3492..b0d5b607de9 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/ASTConfiguration.qll +++ b/cpp/ql/test/library-tests/dataflow/fields/ASTConfiguration.qll @@ -1,10 +1,8 @@ private import semmle.code.cpp.dataflow.DataFlow private import DataFlow -class AstConf extends Configuration { - AstConf() { this = "ASTFieldFlowConf" } - - override predicate isSource(Node src) { +module AstConfig implements ConfigSig { + predicate isSource(Node src) { src.asExpr() instanceof NewExpr or src.asExpr().(Call).getTarget().hasName("user_input") @@ -15,14 +13,14 @@ class AstConf extends Configuration { ) } - override predicate isSink(Node sink) { + predicate isSink(Node sink) { exists(Call c | c.getTarget().hasName("sink") and c.getAnArgument() = sink.asExpr() ) } - override predicate isAdditionalFlowStep(Node a, Node b) { + predicate isAdditionalFlowStep(Node a, Node b) { b.asPartialDefinition() = any(Call c | c.getTarget().hasName("insert") and c.getAnArgument() = a.asExpr()) .getQualifier() @@ -31,5 +29,4 @@ class AstConf extends Configuration { } } -/** DEPRECATED: Alias for AstConf */ -deprecated class ASTConf = AstConf; +module AstFlow = Global; diff --git a/cpp/ql/test/library-tests/dataflow/fields/IRConfiguration.qll b/cpp/ql/test/library-tests/dataflow/fields/IRConfiguration.qll index dac495f132b..494d15efb9c 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/IRConfiguration.qll +++ b/cpp/ql/test/library-tests/dataflow/fields/IRConfiguration.qll @@ -1,10 +1,8 @@ private import semmle.code.cpp.ir.dataflow.DataFlow private import DataFlow -class IRConf extends Configuration { - IRConf() { this = "IRFieldFlowConf" } - - override predicate isSource(Node src) { +module IRConfig implements ConfigSig { + predicate isSource(Node src) { src.asExpr() instanceof NewExpr or src.asExpr().(Call).getTarget().hasName("user_input") @@ -15,14 +13,14 @@ class IRConf extends Configuration { ) } - override predicate isSink(Node sink) { + predicate isSink(Node sink) { exists(Call c | c.getTarget().hasName("sink") and c.getAnArgument() = [sink.asExpr(), sink.asIndirectExpr(), sink.asConvertedExpr()] ) } - override predicate isAdditionalFlowStep(Node a, Node b) { + predicate isAdditionalFlowStep(Node a, Node b) { b.asPartialDefinition() = any(Call c | c.getTarget().hasName("insert") and c.getAnArgument() = a.asExpr()) .getQualifier() @@ -30,3 +28,5 @@ class IRConf extends Configuration { b.asExpr().(AddressOfExpr).getOperand() = a.asExpr() } } + +module IRFlow = Global; diff --git a/cpp/ql/test/library-tests/dataflow/fields/flow.expected b/cpp/ql/test/library-tests/dataflow/fields/flow.expected index e69de29bb2d..48de9172b36 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/flow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/cpp/ql/test/library-tests/dataflow/fields/flow.ql b/cpp/ql/test/library-tests/dataflow/fields/flow.ql index f902afd33db..433aa0ad68f 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/flow.ql +++ b/cpp/ql/test/library-tests/dataflow/fields/flow.ql @@ -1,9 +1,11 @@ import TestUtilities.dataflow.FlowTestCommon module AstTest { - private import ASTConfiguration + import ASTConfiguration } module IRTest { - private import IRConfiguration + import IRConfiguration } + +import MakeTest, IRFlowTest>> diff --git a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.ql b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.ql index b918417cd66..d20dec6a94f 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.ql +++ b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.ql @@ -4,8 +4,8 @@ import semmle.code.cpp.ir.dataflow.DataFlow import IRConfiguration -import DataFlow::PathGraph +import IRFlow::PathGraph -from DataFlow::PathNode src, DataFlow::PathNode sink, IRConf conf -where conf.hasFlowPath(src, sink) +from IRFlow::PathNode src, IRFlow::PathNode sink +where IRFlow::flowPath(src, sink) select sink, src, sink, sink + " flows from $@", src, src.toString() diff --git a/cpp/ql/test/library-tests/dataflow/fields/path-flow.ql b/cpp/ql/test/library-tests/dataflow/fields/path-flow.ql index 7456e114712..6958ae19700 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/path-flow.ql +++ b/cpp/ql/test/library-tests/dataflow/fields/path-flow.ql @@ -4,8 +4,8 @@ import semmle.code.cpp.dataflow.DataFlow import ASTConfiguration -import DataFlow::PathGraph +import AstFlow::PathGraph -from DataFlow::PathNode src, DataFlow::PathNode sink, AstConf conf -where conf.hasFlowPath(src, sink) +from AstFlow::PathNode src, AstFlow::PathNode sink +where AstFlow::flowPath(src, sink) select sink, src, sink, sink + " flows from $@", src, src.toString() diff --git a/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.expected b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.expected index e69de29bb2d..48de9172b36 100644 --- a/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.ql b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.ql index d16552d983d..b887539d588 100644 --- a/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.ql +++ b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.ql @@ -3,37 +3,39 @@ import TestUtilities.dataflow.FlowTestCommon module AstTest { private import semmle.code.cpp.dataflow.TaintTracking - class AstSmartPointerTaintConfig extends TaintTracking::Configuration { - AstSmartPointerTaintConfig() { this = "ASTSmartPointerTaintConfig" } - - override predicate isSource(DataFlow::Node source) { + module AstSmartPointerTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr().(FunctionCall).getTarget().getName() = "source" } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(FunctionCall call | call.getTarget().getName() = "sink" and sink.asExpr() = call.getAnArgument() ) } } + + module AstFlow = TaintTracking::Global; } module IRTest { private import semmle.code.cpp.ir.dataflow.TaintTracking - class IRSmartPointerTaintConfig extends TaintTracking::Configuration { - IRSmartPointerTaintConfig() { this = "IRSmartPointerTaintConfig" } - - override predicate isSource(DataFlow::Node source) { + module IRSmartPointerTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr().(FunctionCall).getTarget().getName() = "source" } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(FunctionCall call | call.getTarget().getName() = "sink" and sink.asExpr() = call.getAnArgument() ) } } + + module IRFlow = TaintTracking::Global; } + +import MakeTest, IRFlowTest>> diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.expected b/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.expected index e69de29bb2d..48de9172b36 100644 --- a/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.expected +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.ql b/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.ql index cb687f1d3bf..15f5f43576a 100644 --- a/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.ql +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.ql @@ -4,12 +4,10 @@ import cpp import TestUtilities.InlineExpectationsTest import semmle.code.cpp.security.FlowSources -class LocalFlowSourceTest extends InlineExpectationsTest { - LocalFlowSourceTest() { this = "LocalFlowSourceTest" } +module LocalFlowSourceTest implements TestSig { + string getARelevantTag() { result = "local_source" } - override string getARelevantTag() { result = "local_source" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "local_source" and exists(LocalFlowSource node, int n | n = @@ -30,3 +28,5 @@ class LocalFlowSourceTest extends InlineExpectationsTest { ) } } + +import MakeTest diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/remote-flow.expected b/cpp/ql/test/library-tests/dataflow/source-sink-tests/remote-flow.expected index e69de29bb2d..48de9172b36 100644 --- a/cpp/ql/test/library-tests/dataflow/source-sink-tests/remote-flow.expected +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/remote-flow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/remote-flow.ql b/cpp/ql/test/library-tests/dataflow/source-sink-tests/remote-flow.ql index 703b62b9ffc..45427141fe0 100644 --- a/cpp/ql/test/library-tests/dataflow/source-sink-tests/remote-flow.ql +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/remote-flow.ql @@ -4,12 +4,10 @@ import cpp import TestUtilities.InlineExpectationsTest import semmle.code.cpp.security.FlowSources -class RemoteFlowSourceTest extends InlineExpectationsTest { - RemoteFlowSourceTest() { this = "RemoteFlowSourceTest" } +module RemoteFlowSourceTest implements TestSig { + string getARelevantTag() { result = "remote_source" } - override string getARelevantTag() { result = "remote_source" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "remote_source" and exists(RemoteFlowSource node, int n | n = @@ -31,12 +29,10 @@ class RemoteFlowSourceTest extends InlineExpectationsTest { } } -class RemoteFlowSinkTest extends InlineExpectationsTest { - RemoteFlowSinkTest() { this = "RemoteFlowSinkTest" } +module RemoteFlowSinkTest implements TestSig { + string getARelevantTag() { result = "remote_sink" } - override string getARelevantTag() { result = "remote_sink" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { tag = "remote_sink" and exists(RemoteFlowSink node, int n | n = @@ -57,3 +53,5 @@ class RemoteFlowSinkTest extends InlineExpectationsTest { ) } } + +import MakeTest> diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 85fc3526dc7..907cccd197b 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -8090,20 +8090,20 @@ | vector.cpp:520:25:520:31 | call to vector | vector.cpp:523:8:523:9 | vs | | | vector.cpp:520:25:520:31 | call to vector | vector.cpp:524:8:524:9 | vs | | | vector.cpp:520:25:520:31 | call to vector | vector.cpp:526:8:526:9 | vs | | -| vector.cpp:520:25:520:31 | call to vector | vector.cpp:539:8:539:9 | vs | | -| vector.cpp:520:25:520:31 | call to vector | vector.cpp:540:2:540:2 | vs | | +| vector.cpp:520:25:520:31 | call to vector | vector.cpp:532:8:532:9 | vs | | +| vector.cpp:520:25:520:31 | call to vector | vector.cpp:533:2:533:2 | vs | | | vector.cpp:520:30:520:30 | 0 | vector.cpp:520:25:520:31 | call to vector | TAINT | | vector.cpp:523:8:523:9 | ref arg vs | vector.cpp:524:8:524:9 | vs | | | vector.cpp:523:8:523:9 | ref arg vs | vector.cpp:526:8:526:9 | vs | | -| vector.cpp:523:8:523:9 | ref arg vs | vector.cpp:539:8:539:9 | vs | | -| vector.cpp:523:8:523:9 | ref arg vs | vector.cpp:540:2:540:2 | vs | | +| vector.cpp:523:8:523:9 | ref arg vs | vector.cpp:532:8:532:9 | vs | | +| vector.cpp:523:8:523:9 | ref arg vs | vector.cpp:533:2:533:2 | vs | | | vector.cpp:523:8:523:9 | vs | vector.cpp:523:10:523:10 | call to operator[] | TAINT | | vector.cpp:524:8:524:9 | ref arg vs | vector.cpp:526:8:526:9 | vs | | -| vector.cpp:524:8:524:9 | ref arg vs | vector.cpp:539:8:539:9 | vs | | -| vector.cpp:524:8:524:9 | ref arg vs | vector.cpp:540:2:540:2 | vs | | +| vector.cpp:524:8:524:9 | ref arg vs | vector.cpp:532:8:532:9 | vs | | +| vector.cpp:524:8:524:9 | ref arg vs | vector.cpp:533:2:533:2 | vs | | | vector.cpp:524:8:524:9 | vs | vector.cpp:524:10:524:10 | call to operator[] | TAINT | -| vector.cpp:526:8:526:9 | ref arg vs | vector.cpp:539:8:539:9 | vs | | -| vector.cpp:526:8:526:9 | ref arg vs | vector.cpp:540:2:540:2 | vs | | +| vector.cpp:526:8:526:9 | ref arg vs | vector.cpp:532:8:532:9 | vs | | +| vector.cpp:526:8:526:9 | ref arg vs | vector.cpp:533:2:533:2 | vs | | | vector.cpp:526:8:526:9 | vs | vector.cpp:526:11:526:15 | call to begin | TAINT | | vector.cpp:526:11:526:15 | call to begin | vector.cpp:526:3:526:17 | ... = ... | | | vector.cpp:526:11:526:15 | call to begin | vector.cpp:527:9:527:10 | it | | @@ -8128,5 +8128,5 @@ | vector.cpp:530:3:530:4 | ref arg it | vector.cpp:531:9:531:10 | it | | | vector.cpp:530:9:530:14 | call to source | vector.cpp:530:3:530:4 | ref arg it | TAINT | | vector.cpp:531:9:531:10 | it | vector.cpp:531:8:531:8 | call to operator* | TAINT | -| vector.cpp:539:8:539:9 | ref arg vs | vector.cpp:540:2:540:2 | vs | | -| vector.cpp:539:8:539:9 | vs | vector.cpp:539:10:539:10 | call to operator[] | TAINT | +| vector.cpp:532:8:532:9 | ref arg vs | vector.cpp:533:2:533:2 | vs | | +| vector.cpp:532:8:532:9 | vs | vector.cpp:532:10:532:10 | call to operator[] | TAINT | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index e69de29bb2d..48de9172b36 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql index fc0b0976348..ef79f065921 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql @@ -43,10 +43,8 @@ module AstTest { private import semmle.code.cpp.models.interfaces.Taint /** Common data flow configuration to be used by tests. */ - class AstTestAllocationConfig extends TaintTracking::Configuration { - AstTestAllocationConfig() { this = "ASTTestAllocationConfig" } - - override predicate isSource(DataFlow::Node source) { + module AstTestAllocationConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr().(FunctionCall).getTarget().getName() = "source" or source.asParameter().getName().matches("source%") @@ -60,17 +58,19 @@ module AstTest { ) } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(FunctionCall call | call.getTarget().getName() = "sink" and sink.asExpr() = call.getAnArgument() ) } - override predicate isSanitizer(DataFlow::Node barrier) { + predicate isBarrier(DataFlow::Node barrier) { barrier.asExpr().(VariableAccess).getTarget().hasName("sanitizer") } } + + module AstFlow = TaintTracking::Global; } module IRTest { @@ -78,10 +78,8 @@ module IRTest { private import semmle.code.cpp.ir.dataflow.TaintTracking /** Common data flow configuration to be used by tests. */ - class TestAllocationConfig extends TaintTracking::Configuration { - TestAllocationConfig() { this = "TestAllocationConfig" } - - override predicate isSource(DataFlow::Node source) { + module TestAllocationConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr().(FunctionCall).getTarget().getName() = "source" or source.asIndirectExpr().(FunctionCall).getTarget().getName() = "source" @@ -94,21 +92,25 @@ module IRTest { ) } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(FunctionCall call | call.getTarget().getName() = "sink" and [sink.asExpr(), sink.asIndirectExpr()] = call.getAnArgument() ) } - override predicate isSanitizer(DataFlow::Node barrier) { + predicate isBarrier(DataFlow::Node barrier) { barrier.asExpr().(VariableAccess).getTarget().hasName("sanitizer") } - override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { + predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) { // allow arbitrary reads at sinks - this.isSink(node) and + isSink(node) and c.(DataFlow::FieldContent).getField().getDeclaringType() = node.getType().getUnspecifiedType() } } + + module IRFlow = TaintTracking::Global; } + +import MakeTest, IRFlowTest>> 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 19824641560..a26ac8f0513 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp @@ -523,19 +523,12 @@ void test_vector_iterator() { sink(vs[1]); sink(vs[source()]); // $ MISSING: ast,ir - it = vs.begin(); // (1) + it = vs.begin(); sink(*it); it += 1; sink(*it); - it += source(); // (2) - sink(*it); // $ ast,ir // (3) - // This FP happens because of the following flows: - // 1. There's a write to the iterator at (2) - // 2. This write propagates to `it` on the next line at (3) - // 3. There's a taint step from `it` to `*it` at (3) - // 4. The `*it` is seen as a use of `vs` because of (1). - // 5. There's use-use flow from `*it` at (3) (which is a use of `vs`) to `vs` at (4) - // 6. There's a taint step from vs to vs[1] - sink(vs[1]); // $ SPURIOUS: ir // (4) + it += source(); + sink(*it); // $ ast,ir + sink(vs[1]); // clean } } diff --git a/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.expected b/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.expected index e69de29bb2d..48de9172b36 100644 --- a/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.expected +++ b/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.ql b/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.ql index 6cfb22803bd..5ba30a1627d 100644 --- a/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.ql +++ b/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.ql @@ -12,12 +12,10 @@ import TestUtilities.InlineExpectationsTest module ModulusAnalysisInstantiated = ModulusAnalysis>; -class ModulusAnalysisTest extends InlineExpectationsTest { - ModulusAnalysisTest() { this = "ModulusAnalysisTest" } +module ModulusAnalysisTest implements TestSig { + string getARelevantTag() { result = "mod" } - override string getARelevantTag() { result = "mod" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(SemExpr e, IR::CallInstruction call | getSemanticExpr(call.getArgument(0)) = e and call.getStaticCallTarget().hasName("mod") and @@ -29,6 +27,8 @@ class ModulusAnalysisTest extends InlineExpectationsTest { } } +import MakeTest + private string getAModString(SemExpr e) { exists(SemBound b, int delta, int mod | ModulusAnalysisInstantiated::semExprModulus(e, b, delta, mod) and diff --git a/cpp/ql/test/library-tests/ir/points_to/points_to.expected b/cpp/ql/test/library-tests/ir/points_to/points_to.expected index e69de29bb2d..48de9172b36 100644 --- a/cpp/ql/test/library-tests/ir/points_to/points_to.expected +++ b/cpp/ql/test/library-tests/ir/points_to/points_to.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/cpp/ql/test/library-tests/ir/points_to/points_to.ql b/cpp/ql/test/library-tests/ir/points_to/points_to.ql index 6cc7b7efb34..2eafcc55ef0 100644 --- a/cpp/ql/test/library-tests/ir/points_to/points_to.ql +++ b/cpp/ql/test/library-tests/ir/points_to/points_to.ql @@ -21,12 +21,10 @@ module Raw { result = getOperandMemoryLocation(instr.getAnOperand()) } - class RawPointsToTest extends InlineExpectationsTest { - RawPointsToTest() { this = "RawPointsToTest" } + module RawPointsToTest implements TestSig { + string getARelevantTag() { result = "raw" } - override string getARelevantTag() { result = "raw" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(Instruction instr, MemoryLocation memLocation | memLocation = getAMemoryAccess(instr) and tag = "raw" and @@ -49,12 +47,10 @@ module UnaliasedSsa { result = getOperandMemoryLocation(instr.getAnOperand()) } - class UnaliasedSsaPointsToTest extends InlineExpectationsTest { - UnaliasedSsaPointsToTest() { this = "UnaliasedSSAPointsToTest" } + module UnaliasedSsaPointsToTest implements TestSig { + string getARelevantTag() { result = "ussa" } - override string getARelevantTag() { result = "ussa" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(Instruction instr, MemoryLocation memLocation | memLocation = getAMemoryAccess(instr) and not memLocation.getVirtualVariable() instanceof AliasedVirtualVariable and @@ -69,3 +65,5 @@ module UnaliasedSsa { } } } + +import MakeTest> diff --git a/cpp/ql/test/library-tests/ir/range-analysis/Overflow.expected b/cpp/ql/test/library-tests/ir/range-analysis/Overflow.expected index e69de29bb2d..48de9172b36 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/Overflow.expected +++ b/cpp/ql/test/library-tests/ir/range-analysis/Overflow.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/cpp/ql/test/library-tests/ir/range-analysis/Overflow.ql b/cpp/ql/test/library-tests/ir/range-analysis/Overflow.ql index e0491e6e0ed..40d80f3d7b0 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/Overflow.ql +++ b/cpp/ql/test/library-tests/ir/range-analysis/Overflow.ql @@ -2,12 +2,10 @@ import cpp import semmle.code.cpp.rangeanalysis.new.SimpleRangeAnalysis import TestUtilities.InlineExpectationsTest -class RangeAnalysisTest extends InlineExpectationsTest { - RangeAnalysisTest() { this = "RangeAnalysisTest" } +module RangeAnalysisTest implements TestSig { + string getARelevantTag() { result = "overflow" } - override string getARelevantTag() { result = "overflow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(Expr e | tag = "overflow" and element = e.toString() and @@ -21,3 +19,5 @@ class RangeAnalysisTest extends InlineExpectationsTest { ) } } + +import MakeTest diff --git a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.expected b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.expected index e69de29bb2d..48de9172b36 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.expected +++ b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql index 6c79e56cc5b..b5a86c23d97 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql +++ b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql @@ -5,12 +5,10 @@ import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific import semmle.code.cpp.ir.IR as IR import TestUtilities.InlineExpectationsTest -class RangeAnalysisTest extends InlineExpectationsTest { - RangeAnalysisTest() { this = "RangeAnalysisTest" } +module RangeAnalysisTest implements TestSig { + string getARelevantTag() { result = "range" } - override string getARelevantTag() { result = "range" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(SemExpr e, IR::CallInstruction call | getSemanticExpr(call.getArgument(0)) = e and call.getStaticCallTarget().hasName("range") and @@ -22,6 +20,8 @@ class RangeAnalysisTest extends InlineExpectationsTest { } } +import MakeTest + private string getDirectionString(boolean d) { result = "<=" and d = true or @@ -40,14 +40,7 @@ bindingset[delta] private string getBoundString(SemBound b, float delta) { b instanceof SemZeroBound and result = delta.toString() or - result = - strictconcat(b.(SemSsaBound) - .getAVariable() - .(SemanticExprConfig::SsaVariable) - .asInstruction() - .getAst() - .toString(), ":" - ) + getOffsetString(delta) + result = strictconcat(b.(SemSsaBound).getAVariable().toString(), " | ") + getOffsetString(delta) } private string getARangeString(SemExpr e) { diff --git a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp index eed0a7d7e47..df29578409b 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp @@ -8,7 +8,7 @@ int test1(struct List* p) { int count = 0; for (; p; p = p->next) { count = count+1; - range(count); // $ range===count:p+1 + range(count); // $ range="==Phi: p | Store: count+1" } range(count); return count; @@ -18,7 +18,7 @@ int test2(struct List* p) { int count = 0; for (; p; p = p->next) { count = (count+1) % 10; - range(count); // $ range=<=9 range=>=-9 range=<=count:p+1 + range(count); // $ range=<=9 range=>=-9 range="<=Phi: p | Store: count+1" } range(count); // $ range=>=-9 range=<=9 return count; @@ -29,7 +29,7 @@ int test3(struct List* p) { for (; p; p = p->next) { range(count++); // $ range=>=-9 range=<=9 count = count % 10; - range(count); // $ range=<=9 range=>=-9 range="<=... +++0" range=<=count:p+1 + range(count); // $ range=<=9 range=>=-9 range="<=Store: ... +++0" range="<=Phi: p | Store: count+1" } range(count); // $ range=>=-9 range=<=9 return count; @@ -42,11 +42,11 @@ int test4() { range(i); // $ range=<=1 range=>=0 range(total); total += i; - range(total); // $ range=<=i+1 range=<=i+1 MISSING: range=>=0 range=>=i+0 + range(total); // $ range="<=Phi: i+1" MISSING: range=>=0 range=>=i+0 } range(total); // $ MISSING: range=>=0 range(i); // $ range===2 - range(total + i); // $ range=<=i+2 MISSING: range===i+2 range=>=2 range=>=i+0 + range(total + i); // $ range="<=Phi: i+2" MISSING: range===i+2 range=>=2 range=>=i+0 return total + i; } @@ -57,11 +57,11 @@ int test5() { range(i); // $ range=<=1 range=>=0 range(total); // $ MISSING: range=>=0 total += i; - range(total); // $ range=<=i+1 MISSING: range=>=0 range=>=i+0 + range(total); // $ range="<=Phi: i+1" MISSING: range=>=0 range=>=i+0 } range(total); // $ MISSING: range=>=0 range(i); // $ range===2 - range(total + i); // $ range=<=i+2 MISSING: range===i+2 range=>=2 range=>=i+0 + range(total + i); // $ range="<=Phi: i+2" MISSING: range===i+2 range=>=2 range=>=i+0 return total + i; } @@ -72,7 +72,7 @@ int test6() { range(i); // $ range=<=1 range=>=0 range(total); // $ MISSING: range=>=0 total += i; - range(total); // $ range=<=i+1 MISSING: range=>=0 range=>=i+0 + range(total); // $ range="<=Phi: i+1" MISSING: range=>=0 range=>=i+0 } return total + i; } @@ -93,12 +93,12 @@ int test8(int x, int y) { if (-1000 < y && y < 10) { range(y); // $ range=<=9 range=>=-999 if (x < y-2) { - range(x); // $ range=<=6 range=<=y-3 - range(y); // $ range=<=9 range=>=-999 range=>=x+3 + range(x); // $ range=<=6 range="<=InitializeParameter: y | Store: y-3" + range(y); // $ range=<=9 range=>=-999 range=">=InitializeParameter: x | Store: x+3" return x; } - range(x); // $ range=>=-1001 range=>=y-2 - range(y); // $ range=<=9 range=<=x+2 range=>=-999 + range(x); // $ range=>=-1001 range=">=InitializeParameter: y | Store: y-2" + range(y); // $ range=<=9 range="<=InitializeParameter: x | Store: x+2" range=>=-999 } range(x); range(y); @@ -127,12 +127,12 @@ int test10(int x, int y) { if (y > 7) { range(y); // $ range=>=8 if (x < y) { - range(x); // $ range=<=y-1 - range(y); // $ range=>=8 range=>=x+1 + range(x); // $ range="<=InitializeParameter: y-1" + range(y); // $ range=>=8 range=">=InitializeParameter: x | Store: x+1" return 0; } - range(x); // $ range=>=8 range=>=y+0 - range(y); // $ range=<=x+0 range=>=8 + range(x); // $ range=>=8 range=">=InitializeParameter: y+0" + range(y); // $ range="<=InitializeParameter: x | Store: x+0" range=>=8 return x; } range(y); // $ range=<=7 @@ -145,7 +145,7 @@ int test11(char *p) { range(*p); if (c != '\0') { *p++ = '\0'; - range(p); // $ range===p+1 + range(p); // $ range="==InitializeParameter: p+1" range(*p); } if (c == ':') { @@ -155,7 +155,7 @@ int test11(char *p) { if (c != '\0') { range(c); *p++ = '\0'; - range(p); // $ range=<=p+2 range===c+1 range=>=p+1 + range(p); // $ range="<=InitializeParameter: p+2" range="==Phi: c+1" range=">=InitializeParameter: p+1" } if (c != ',') { return 1; @@ -193,7 +193,7 @@ int test13(char c, int i) { unsigned int y = x-1; // $ overflow=- range(y); // $ range===-1 overflow=- int z = i+1; // $ overflow=+ - range(z); // $ range===i+1 + range(z); // $ range="==InitializeParameter: i+1" range(c + i + uc + x + y + z); // $ overflow=+- overflow=+ overflow=- MISSING: range=>=1 range((double)(c + i + uc + x + y + z)); // $ overflow=+ overflow=+- overflow=- MISSING: range=>=1 return (double)(c + i + uc + x + y + z); // $ overflow=+- overflow=+ overflow=- @@ -245,7 +245,7 @@ int test_unary(int a) { range(c); // $ range=<=0 range=>=-11 range(b+c); // $ range=<=11 range=>=-11 MISSING:range=">=- ...+0" total += b+c; - range(total); // $ range=<=0+11 range=<=19 range=>=0-11 range=>=-19 + range(total); // $ range="<=Phi: 0+11" range=<=19 range=">=Phi: 0-11" range=>=-19 } if (-7 <= a && a <= 11) { range(a); // $ range=<=11 range=>=-7 @@ -255,7 +255,7 @@ int test_unary(int a) { range(c); // $ range=<=7 range=>=-11 range(b+c); // $ range=<=18 range=>=-18 total += b+c; - range(total); // $ range="<=- ...+18" range=">=- ...-18" range=<=0+29 range=<=37 range=>=0-29 range=>=-37 + range(total); // $ range="<=Phi: - ...+18" range=">=Phi: - ...-18" range="<=Phi: 0+29" range=<=37 range=">=Phi: 0-29" range=>=-37 } if (-7 <= a && a <= 1) { range(a); // $ range=<=1 range=>=-7 @@ -265,7 +265,7 @@ int test_unary(int a) { range(c); // $ range=<=7 range=>=-1 range(b+c); // $ range=<=8 range=>=-8 total += b+c; - range(total); // $ range="<=- ...+8" range="<=- ...+26" range=">=- ...-8" range=">=- ...-26" range=<=0+37 range=<=45 range=>=0-37 range=>=-45 + range(total); // $ range="<=Phi: - ...+8" range="<=Phi: - ...+26" range=">=Phi: - ...-8" range=">=Phi: - ...-26" range="<=Phi: 0+37" range=<=45 range=">=Phi: 0-37" range=>=-45 } if (-7 <= a && a <= 0) { range(a); // $ range=<=0 range=>=-7 @@ -275,7 +275,7 @@ int test_unary(int a) { range(c); // $ range=<=7 range=>=0 range(b+c); // $ range=>=-7 range=<=7 MISSING:range="<=- ...+0" total += b+c; - range(total); // $ range="<=- ...+7" range="<=- ...+15" range="<=- ...+33" range=">=- ...-7" range=">=- ...-15" range=">=- ...-33" range=<=0+44 range=<=52 range=>=0-44 range=>=-52 + range(total); // $ range="<=Phi: - ...+7" range="<=Phi: - ...+15" range="<=Phi: - ...+33" range=">=Phi: - ...-7" range=">=Phi: - ...-15" range=">=Phi: - ...-33" range="<=Phi: 0+44" range=<=52 Unexpected result: range=">=Phi: 0-44" range=>=-52 } if (-7 <= a && a <= -2) { range(a); // $ range=<=-2 range=>=-7 @@ -285,9 +285,9 @@ int test_unary(int a) { range(c); // $ range=<=7 range=>=2 range(b+c); // $ range=<=5 range=>=-5 total += b+c; - range(total); // $ range="<=- ...+5" range="<=- ...+12" range="<=- ...+20" range="<=- ...+38" range=">=- ...-5" range=">=- ...-12" range=">=- ...-20" range=">=- ...-38" range=<=0+49 range=<=57 range=>=0-49 range=>=-57 + range(total); // $ range="<=Phi: - ...+5" range="<=Phi: - ...+12" range="<=Phi: - ...+20" range="<=Phi: - ...+38" range=">=Phi: - ...-5" range=">=Phi: - ...-12" range=">=Phi: - ...-20" range=">=Phi: - ...-38" range="<=Phi: 0+49" range=<=57 range=">=Phi: 0-49" range=>=-57 } - range(total); // $ range="<=- ...+5" range="<=- ...+12" range="<=- ...+20" range="<=- ...+38" range=">=- ...-5" range=">=- ...-12" range=">=- ...-20" range=">=- ...-38" range=<=0+49 range=<=57 range=>=0-49 range=>=-57 + range(total); // $ range="<=Phi: - ...+5" range="<=Phi: - ...+12" range="<=Phi: - ...+20" range="<=Phi: - ...+38" range=">=Phi: - ...-5" range=">=Phi: - ...-12" range=">=Phi: - ...-20" range=">=Phi: - ...-38" range="<=Phi: 0+49" range=<=57 range=">=Phi: 0-49" range=>=-57 return total; } @@ -310,7 +310,7 @@ int test_mult01(int a, int b) { int r = a*b; // 0 .. 253 range(r); // $ range=<=253 range=>=0 total += r; - range(total); // $ range=<=3+253 range=<=506 range=>=0 range=>=3+0 + range(total); // $ range="<=Phi: 3+253" range=<=506 range=>=0 range=">=Phi: 3+0" } if (3 <= a && a <= 11 && -13 <= b && b <= 23) { range(a); // $ range=<=11 range=>=3 @@ -326,7 +326,7 @@ int test_mult01(int a, int b) { int r = a*b; // -143 .. 0 range(r); // $ range=<=0 range=>=-143 total += r; - range(total); // $ range=>=3-143 + range(total); // $ range=">=Phi: 3-143" } if (3 <= a && a <= 11 && -13 <= b && b <= -7) { range(a); // $ range=<=11 range=>=3 @@ -334,9 +334,9 @@ int test_mult01(int a, int b) { int r = a*b; // -143 .. -21 range(r); // $ range=<=-21 range=>=-143 total += r; - range(total); // $ range=>=3-143 range=>=3-286 + range(total); // $ range=">=Phi: 3-143" range=">=Phi: 3-286" } - range(total); // $ range=>=3-143 range=>=3-286 + range(total); // $ range=">=Phi: 3-143" range=">=Phi: 3-286" return total; } @@ -358,7 +358,7 @@ int test_mult02(int a, int b) { int r = a*b; // 0 .. 253 range(r); // $ range=<=253 range=>=0 total += r; - range(total); // $ range=>=0 range=>=0+0 range=<=0+253 range=<=506 + range(total); // $ range=>=0 range=">=Phi: 0+0" range="<=Phi: 0+253" range=<=506 } if (0 <= a && a <= 11 && -13 <= b && b <= 23) { range(a); // $ range=<=11 range=>=0 @@ -374,7 +374,7 @@ int test_mult02(int a, int b) { int r = a*b; // -143 .. 0 range(r); // $ range=<=0 range=>=-143 total += r; - range(total); // $ range=>=0-143 + range(total); // $ range=">=Phi: 0-143" } if (0 <= a && a <= 11 && -13 <= b && b <= -7) { range(a); // $ range=<=11 range=>=0 @@ -382,9 +382,9 @@ int test_mult02(int a, int b) { int r = a*b; // -143 .. 0 range(r); // $ range=<=0 range=>=-143 total += r; - range(total); // $ range=>=0-143 range=>=0-286 + range(total); // $ range=">=Phi: 0-143" range=">=Phi: 0-286" } - range(total); // $range=>=0-143 range=>=0-286 + range(total); // $range=">=Phi: 0-143" range=">=Phi: 0-286" return total; } @@ -453,7 +453,7 @@ int test_mult04(int a, int b) { int r = a*b; // -391 .. 0 range(r); // $ range=<=0 range=>=-391 total += r; - range(total); // $ range="<=- ...+0" range=<=0 range=">=- ...-391" range=>=-782 + range(total); // $ range="<=Phi: - ...+0" range=<=0 range=">=Phi: - ...-391" range=>=-782 } if (-17 <= a && a <= 0 && -13 <= b && b <= 23) { range(a); // $ range=<=0 range=>=-17 @@ -469,7 +469,7 @@ int test_mult04(int a, int b) { int r = a*b; // 0 .. 221 range(r); // $ range=<=221 range=>=0 total += r; - range(total); // $ range="<=- ...+221" + range(total); // $ range="<=Phi: - ...+221" } if (-17 <= a && a <= 0 && -13 <= b && b <= -7) { range(a); // $ range=<=0 range=>=-17 @@ -477,9 +477,9 @@ int test_mult04(int a, int b) { int r = a*b; // 0 .. 221 range(r); // $ range=<=221 range=>=0 total += r; - range(total); // $ range="<=- ...+221" range="<=- ...+442" + range(total); // $ range="<=Phi: - ...+221" range="<=Phi: - ...+442" } - range(total); // $ range="<=- ...+221" range="<=- ...+442" + range(total); // $ range="<=Phi: - ...+221" range="<=Phi: - ...+442" return total; } @@ -501,7 +501,7 @@ int test_mult05(int a, int b) { int r = a*b; // -391 .. 0 range(r); // $ range=<=0 range=>=-391 total += r; - range(total); // $ range="<=- ...+0" range=<=0 range=">=- ...-391" range=>=-782 + range(total); // $ range="<=Phi: - ...+0" range=<=0 range=">=Phi: - ...-391" range=>=-782 } if (-17 <= a && a <= -2 && -13 <= b && b <= 23) { range(a); // $ range=<=-2 range=>=-17 @@ -517,7 +517,7 @@ int test_mult05(int a, int b) { int r = a*b; // 0 .. 221 range(r); // $ range=<=221 range=>=0 total += r; - range(total); // $ range="<=- ...+221" + range(total); // $ range="<=Phi: - ...+221" } if (-17 <= a && a <= -2 && -13 <= b && b <= -7) { range(a); // $ range=<=-2 range=>=-17 @@ -525,9 +525,9 @@ int test_mult05(int a, int b) { int r = a*b; // 14 .. 221 range(r); // $ range=<=221 range=>=14 total += r; - range(total); // $ range="<=- ...+221" range="<=- ...+442" + range(total); // $ range="<=Phi: - ...+221" range="<=Phi: - ...+442" } - range(total); // $ range="<=- ...+221" range="<=- ...+442" + range(total); // $ range="<=Phi: - ...+221" range="<=Phi: - ...+442" return total; } @@ -541,7 +541,7 @@ int test16(int x) { while (i < 3) { range(i); // $ range=<=2 range=>=0 i++; - range(i); // $ range=<=3 range=>=1 range="==... = ...:i+1" SPURIOUS:range="==... = ...:i+1" + range(i); // $ range=<=3 range=>=1 range="==Phi: i | Store: ... = ...+1" } range(d); d = i; @@ -640,14 +640,14 @@ unsigned int test_comma01(unsigned int x) { unsigned int y1; unsigned int y2; y1 = (++y, y); - range(y1); // $ range=<=101 range="==... ? ... : ...+1" + range(y1); // $ range=<=101 range="==Phi: ... ? ... : ... | Store: ... ? ... : ...+1" y2 = (y++, - range(y), // $ range=<=102 range="==++ ...:... = ...+1" range="==... ? ... : ...+2" + range(y), // $ range=<=102 range="==Store: ++ ... | Store: ... = ...+1" range="==Phi: ... ? ... : ... | Store: ... ? ... : ...+2" y += 3, - range(y), // $ range=<=105 range="==++ ...:... = ...+4" range="==... +++3" range="==... ? ... : ...+5" + range(y), // $ range=<=105 range="==Store: ++ ... | Store: ... = ...+4" range="==Store: ... +++3" range="==Phi: ... ? ... : ... | Store: ... ? ... : ...+5" y); - range(y2); // $ range=<=105 range="==++ ...:... = ...+4" range="==... +++3" range="==... ? ... : ...+5" - range(y1 + y2); // $ range=<=206 range="<=... ? ... : ...+106" MISSING: range=">=++ ...:... = ...+5" range=">=... +++4" range=">=... += ...:... = ...+1" range=">=... ? ... : ...+6" + range(y2); // $ range=<=105 range="==Store: ++ ... | Store: ... = ...+4" range="==Store: ... +++3" Unexpected result: range="==Phi: ... ? ... : ... | Store: ... ? ... : ...+5" + range(y1 + y2); // $ range=<=206 range="<=Phi: ... ? ... : ... | Store: ... ? ... : ...+106" MISSING: range=">=++ ...:... = ...+5" range=">=... +++4" range=">=... += ...:... = ...+1" range=">=... ? ... : ...+6" return y1 + y2; } @@ -672,7 +672,7 @@ void test17() { range(i); // $ range===50 i = 20 + (j -= 10); - range(i); // $ range="==... += ...:... = ...+10" range===60 + range(i); // $ range="==Store: ... += ... | Store: ... = ...+10" range===60 } // Tests for unsigned multiplication. @@ -693,7 +693,7 @@ int test_unsigned_mult01(unsigned int a, unsigned b) { int r = a*b; // 0 .. 253 range(r);// $ range=>=0 range=<=253 total += r; - range(total); // $ range=">=(unsigned int)...+0" range=>=0 range=<=506 range="<=(unsigned int)...+253" + range(total); // $ range=">=Phi: (unsigned int)...+0" range=>=0 range=<=506 range="<=Phi: (unsigned int)...+253" } if (3 <= a && a <= 11 && 13 <= b && b <= 23) { range(a); // $ range=<=11 range=>=3 @@ -701,9 +701,9 @@ int test_unsigned_mult01(unsigned int a, unsigned b) { int r = a*b; // 39 .. 253 range(r); // $ range=>=39 range=<=253 total += r; - range(total); // $ range=>=39 range=<=759 range="<=(unsigned int)...+253" range="<=(unsigned int)...+506" range=">=(unsigned int)...+39" + range(total); // $ range=>=39 range=<=759 range="<=Phi: (unsigned int)...+253" range="<=Phi: (unsigned int)...+506" range=">=Phi: (unsigned int)...+39" } - range(total); // $ range=>=0 range=<=759 range=">=(unsigned int)...+0" range="<=(unsigned int)...+506" range="<=(unsigned int)...+253" + range(total); // $ range=>=0 range=<=759 range=">=Phi: (unsigned int)...+0" range="<=Phi: (unsigned int)...+506" range="<=Phi: (unsigned int)...+253" return total; } @@ -722,16 +722,16 @@ int test_unsigned_mult02(unsigned b) { int r = 11*b; // 0 .. 253 range(r); // $ range=>=0 range=<=253 total += r; - range(total); // $ range=">=(unsigned int)...+0" range=>=0 range="<=(unsigned int)...+253" range=<=506 + range(total); // $ range=">=Phi: (unsigned int)...+0" range=>=0 range="<=Phi: (unsigned int)...+253" range=<=506 } if (13 <= b && b <= 23) { range(b); // $ range=<=23 range=>=13 int r = 11*b; // 143 .. 253 range(r); // $ range=>=143 range=<=253 total += r; - range(total); // $ range="<=(unsigned int)...+253" range="<=(unsigned int)...+506" range=">=(unsigned int)...+143" range=>=143 range=<=759 + range(total); // $ range="<=Phi: (unsigned int)...+253" range="<=Phi: (unsigned int)...+506" range=">=Phi: (unsigned int)...+143" range=>=143 range=<=759 } - range(total); // $ range=>=0 range=<=759 range=">=(unsigned int)...+0" range="<=(unsigned int)...+506" range="<=(unsigned int)...+253" + range(total); // $ range=>=0 range=<=759 range=">=Phi: (unsigned int)...+0" range="<=Phi: (unsigned int)...+506" range="<=Phi: (unsigned int)...+253" return total; } @@ -851,7 +851,7 @@ int notequal_type_endpoint(unsigned n) { n--; // 1 .. } - range(n); // $ range=<=n+0 // 0 .. 0 + range(n); // $ range="<=InitializeParameter: n+0" // 0 .. 0 } void notequal_refinement(short n) { @@ -946,7 +946,7 @@ void widen_recursive_expr() { for (s = 0; s < 10; s++) { range(s); // $ range=<=9 range=>=0 int result = s + s; - range(result); // $ range=<=18 range=<=s+9 range=>=0 range=>=s+0 + range(result); // $ range=<=18 Unexpected result: range="<=Phi: s+9" range=>=0 Unexpected result: range=">=Phi: s+0" } } @@ -974,7 +974,7 @@ void test_mod_neg(int s) { void test_mod_ternary(int s, bool b) { int s2 = s % (b ? 5 : 500); - range(s2); // $ range=>=-499 range=<=499 range="<=... ? ... : ...-1" + range(s2); // $ range=>=-499 range=<=499 range="<=Phi: ... ? ... : ...-1" } void test_mod_ternary2(int s, bool b1, bool b2) { diff --git a/cpp/ql/test/library-tests/ir/range-analysis/test.cpp b/cpp/ql/test/library-tests/ir/range-analysis/test.cpp index 4c5a3c558c2..95e6474124a 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/test.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/test.cpp @@ -16,8 +16,8 @@ int sum = x + y; // $ overflow=+- } else { if (y > 300) { - range(x); // $ range=>=302 range=<=400 range=<=y+1 MISSING: range===y+1 - range(y); // $ range=>=301 range=<=399 range===x-1 + range(x); // $ range=>=302 range=<=400 range="<=InitializeParameter: y+1" MISSING: range===y+1 + range(y); // $ range=>=301 range=<=399 range="==InitializeParameter: x | Store: x-1" int sum = x + y; } } @@ -39,9 +39,9 @@ } if (y == x - 1 && y > 300 && y + 2 == z && z == 350) { // $ overflow=+ overflow=- - range(x); // $ range===349 range===y+1 range===z-1 - range(y); // $ range===348 range=>=x-1 range===z-2 MISSING: range===x-1 - range(z); // $ range===350 range=<=y+2 MISSING: range===x+1 range===y+2 + range(x); // $ range===349 range="==InitializeParameter: y+1" range="==InitializeParameter: z-1" + range(y); // $ range===348 range=">=InitializeParameter: x | Store: x-1" range="==InitializeParameter: z-2" MISSING: range===x-1 + range(z); // $ range===350 range="<=InitializeParameter: y+2" MISSING: range===x+1 range===y+2 return x + y + z; } } @@ -56,6 +56,17 @@ while (f3_get(n)) n+=2; for (int i = 0; i < n; i += 2) { - range(i); // $ range=>=0 SPURIOUS: range="<=call to f3_get-1" range="<=call to f3_get-2" + range(i); // $ range=>=0 SPURIOUS: range="<=Phi: call to f3_get-1" range="<=Phi: call to f3_get-2" } } + +int f4(int x) { + for (int i = 0; i <= 100; i++) { + range(i); // $ range=<=100 range=>=0 + if(i == 100) { + range(i); // $ range===100 + } else { + range(i); // $ range=<=99 range=>=0 + } + } +} diff --git a/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.expected b/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.expected index e69de29bb2d..48de9172b36 100644 --- a/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.expected +++ b/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.ql b/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.ql index a3cfaa82ed4..fcc796577d1 100644 --- a/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.ql +++ b/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.ql @@ -11,12 +11,10 @@ import TestUtilities.InlineExpectationsTest module SignAnalysisInstantiated = SignAnalysis>; -class SignAnalysisTest extends InlineExpectationsTest { - SignAnalysisTest() { this = "SignAnalysisTest" } +module SignAnalysisTest implements TestSig { + string getARelevantTag() { result = "sign" } - override string getARelevantTag() { result = "sign" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(SemExpr e, IR::CallInstruction call | getSemanticExpr(call.getArgument(0)) = e and call.getStaticCallTarget().hasName("sign") and @@ -28,6 +26,8 @@ class SignAnalysisTest extends InlineExpectationsTest { } } +import MakeTest + private string getASignString(SemExpr e) { result = strictconcat(SignAnalysisInstantiated::semExprSign(e).toString(), "") } diff --git a/cpp/ql/test/library-tests/ir/types/irtypes.expected b/cpp/ql/test/library-tests/ir/types/irtypes.expected index e69de29bb2d..48de9172b36 100644 --- a/cpp/ql/test/library-tests/ir/types/irtypes.expected +++ b/cpp/ql/test/library-tests/ir/types/irtypes.expected @@ -0,0 +1,2 @@ +failures +testFailures diff --git a/cpp/ql/test/library-tests/ir/types/irtypes.ql b/cpp/ql/test/library-tests/ir/types/irtypes.ql index 56a7666458b..eb69111465b 100644 --- a/cpp/ql/test/library-tests/ir/types/irtypes.ql +++ b/cpp/ql/test/library-tests/ir/types/irtypes.ql @@ -2,12 +2,10 @@ private import cpp private import semmle.code.cpp.ir.implementation.raw.IR import TestUtilities.InlineExpectationsTest -class IRTypesTest extends InlineExpectationsTest { - IRTypesTest() { this = "IRTypesTest" } +module IRTypesTest implements TestSig { + string getARelevantTag() { result = "irtype" } - override string getARelevantTag() { result = "irtype" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { + predicate hasActualResult(Location location, string element, string tag, string value) { exists(IRUserVariable irVar | location = irVar.getLocation() and element = irVar.toString() and @@ -16,3 +14,5 @@ class IRTypesTest extends InlineExpectationsTest { ) } } + +import MakeTest diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected index 54bad8e6cbc..16e74b982c1 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected @@ -23,8 +23,6 @@ edges | test_free.cpp:239:14:239:15 | * ... | test_free.cpp:241:9:241:10 | * ... | | test_free.cpp:239:14:239:15 | * ... | test_free.cpp:241:9:241:10 | * ... | | test_free.cpp:239:14:239:15 | * ... | test_free.cpp:241:9:241:10 | * ... | -| test_free.cpp:239:14:239:15 | * ... | test_free.cpp:241:10:241:10 | b | -| test_free.cpp:239:14:239:15 | * ... | test_free.cpp:241:10:241:10 | b | | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | @@ -61,7 +59,6 @@ nodes | test_free.cpp:239:14:239:15 | * ... | semmle.label | * ... | | test_free.cpp:241:9:241:10 | * ... | semmle.label | * ... | | test_free.cpp:241:9:241:10 | * ... | semmle.label | * ... | -| test_free.cpp:241:10:241:10 | b | semmle.label | b | | test_free.cpp:245:10:245:11 | * ... | semmle.label | * ... | | test_free.cpp:245:10:245:11 | * ... | semmle.label | * ... | | test_free.cpp:246:9:246:10 | * ... | semmle.label | * ... | @@ -92,8 +89,6 @@ subpaths | test_free.cpp:241:9:241:10 | * ... | test_free.cpp:239:14:239:15 | * ... | test_free.cpp:241:9:241:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:239:9:239:12 | call to free | call to free | | test_free.cpp:241:9:241:10 | * ... | test_free.cpp:239:14:239:15 | * ... | test_free.cpp:241:9:241:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:239:9:239:12 | call to free | call to free | | test_free.cpp:241:9:241:10 | * ... | test_free.cpp:239:14:239:15 | * ... | test_free.cpp:241:9:241:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:239:9:239:12 | call to free | call to free | -| test_free.cpp:241:10:241:10 | b | test_free.cpp:239:14:239:15 | * ... | test_free.cpp:241:10:241:10 | b | Memory may have been previously freed by $@. | test_free.cpp:239:9:239:12 | call to free | call to free | -| test_free.cpp:241:10:241:10 | b | test_free.cpp:239:14:239:15 | * ... | test_free.cpp:241:10:241:10 | b | Memory may have been previously freed by $@. | test_free.cpp:239:9:239:12 | call to free | call to free | | test_free.cpp:246:9:246:10 | * ... | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:245:5:245:8 | call to free | call to free | | test_free.cpp:246:9:246:10 | * ... | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:245:5:245:8 | call to free | call to free | | test_free.cpp:246:9:246:10 | * ... | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:245:5:245:8 | call to free | call to free | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-119/OverrunWriteProductFlow.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected similarity index 100% rename from cpp/ql/test/experimental/query-tests/Security/CWE/CWE-119/OverrunWriteProductFlow.expected rename to cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.qlref new file mode 100644 index 00000000000..1a418e6abc6 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-119/OverrunWriteProductFlow.ql \ No newline at end of file diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-119/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/test.cpp similarity index 100% rename from cpp/ql/test/experimental/query-tests/Security/CWE/CWE-119/test.cpp rename to cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/test.cpp diff --git a/csharp/documentation/library-coverage/coverage.csv b/csharp/documentation/library-coverage/coverage.csv index cb01c5e13ad..a4a6a534105 100644 --- a/csharp/documentation/library-coverage/coverage.csv +++ b/csharp/documentation/library-coverage/coverage.csv @@ -1,9 +1,9 @@ -package,sink,source,summary,sink:code,sink:encryption-decryptor,sink:encryption-encryptor,sink:encryption-keyprop,sink:encryption-symmetrickey,sink:html,sink:remote,sink:sql,sink:xss,source:file,source:file-write,source:local,source:remote,summary:taint,summary:value -Dapper,55,,,,,,,,,,55,,,,,,, +package,sink,source,summary,sink:code-injection,sink:encryption-decryptor,sink:encryption-encryptor,sink:encryption-keyprop,sink:encryption-symmetrickey,sink:file-content-store,sink:html-injection,sink:js-injection,sink:sql-injection,source:file,source:file-write,source:local,source:remote,summary:taint,summary:value +Dapper,55,,,,,,,,,,,55,,,,,, JsonToItemsTaskFactory,,,7,,,,,,,,,,,,,,7, -Microsoft.ApplicationBlocks.Data,28,,,,,,,,,,28,,,,,,, +Microsoft.ApplicationBlocks.Data,28,,,,,,,,,,,28,,,,,, Microsoft.CSharp,,,24,,,,,,,,,,,,,,24, -Microsoft.EntityFrameworkCore,6,,,,,,,,,,6,,,,,,, +Microsoft.EntityFrameworkCore,6,,12,,,,,,,,,6,,,,,,12 Microsoft.Extensions.Caching.Distributed,,,15,,,,,,,,,,,,,,15, Microsoft.Extensions.Caching.Memory,,,46,,,,,,,,,,,,,,45,1 Microsoft.Extensions.Configuration,,,83,,,,,,,,,,,,,,80,3 @@ -21,8 +21,8 @@ Microsoft.NET.Build.Tasks,,,1,,,,,,,,,,,,,,1, Microsoft.NETCore.Platforms.BuildTasks,,,4,,,,,,,,,,,,,,4, Microsoft.VisualBasic,,,10,,,,,,,,,,,,,,5,5 Microsoft.Win32,,,8,,,,,,,,,,,,,,8, -MySql.Data.MySqlClient,48,,,,,,,,,,48,,,,,,, +MySql.Data.MySqlClient,48,,,,,,,,,,,48,,,,,, Newtonsoft.Json,,,91,,,,,,,,,,,,,,73,18 -ServiceStack,194,,7,27,,,,,,75,92,,,,,,7, -System,65,25,12154,,8,8,9,,4,,33,3,1,17,3,4,10163,1991 +ServiceStack,194,,7,27,,,,,75,,,92,,,,,7, +System,65,25,12157,,8,8,9,,,4,3,33,1,17,3,4,10163,1994 Windows.Security.Cryptography.Core,1,,,,,,,1,,,,,,,,,, diff --git a/csharp/documentation/library-coverage/coverage.rst b/csharp/documentation/library-coverage/coverage.rst index 3837422c867..163638d895f 100644 --- a/csharp/documentation/library-coverage/coverage.rst +++ b/csharp/documentation/library-coverage/coverage.rst @@ -8,7 +8,7 @@ C# framework & library support Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting` `ServiceStack `_,"``ServiceStack.*``, ``ServiceStack``",,7,194, - System,"``System.*``, ``System``",25,12154,65,7 - Others,"``Dapper``, ``JsonToItemsTaskFactory``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NETCore.Platforms.BuildTasks``, ``Microsoft.VisualBasic``, ``Microsoft.Win32``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``Windows.Security.Cryptography.Core``",,556,138, - Totals,,25,12717,397,7 + System,"``System.*``, ``System``",25,12157,65,7 + Others,"``Dapper``, ``JsonToItemsTaskFactory``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NETCore.Platforms.BuildTasks``, ``Microsoft.VisualBasic``, ``Microsoft.Win32``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``Windows.Security.Cryptography.Core``",,568,138, + Totals,,25,12732,397,7 diff --git a/csharp/documentation/library-coverage/cwe-sink.csv b/csharp/documentation/library-coverage/cwe-sink.csv index e71e194a2ed..70f0034ecd3 100644 --- a/csharp/documentation/library-coverage/cwe-sink.csv +++ b/csharp/documentation/library-coverage/cwe-sink.csv @@ -1,2 +1,2 @@ CWE,Sink identifier,Label -CWE-079,html xss,Cross-site scripting \ No newline at end of file +CWE-079,html-injection js-injection,Cross-site scripting diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs index 3984e7c00cf..698be2e2c35 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs @@ -211,6 +211,11 @@ namespace Semmle.Extraction.CSharp.Entities return Default.CreateGenerated(cx, parent, childIndex, location, ValueAsString(null)); } + if (type.SpecialType is SpecialType.System_DateTime) + { + return DateTimeObjectCreation.CreateGenerated(cx, parent, childIndex, type, defaultValue, location); + } + // const literal: return Literal.CreateGenerated(cx, parent, childIndex, type, defaultValue, location); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation/DateTimeObjectCreation.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation/DateTimeObjectCreation.cs new file mode 100644 index 00000000000..52fcb3629f3 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation/DateTimeObjectCreation.cs @@ -0,0 +1,70 @@ +using Microsoft.CodeAnalysis; +using System.Linq; +using System.IO; +using Semmle.Extraction.Kinds; + +namespace Semmle.Extraction.CSharp.Entities.Expressions +{ + internal class DateTimeObjectCreation : Expression + { + private readonly IMethodSymbol constructorSymbol; + + private DateTimeObjectCreation(IMethodSymbol constructorSymbol, ExpressionInfo info) : base(info) + { + this.constructorSymbol = constructorSymbol; + } + + // Gets the value of a System.DateTime object as a string containing the ticks. + private static long ValueAsLong(object? value) => + value is System.DateTime d ? d.Ticks : 0; + + // Gets the System.DateTime(long) constructor from the `type` symbol. + private static IMethodSymbol? GetDateTimeConstructor(ITypeSymbol? type) + { + return type?.GetMembers() + .Where(m => + m is IMethodSymbol c && + c.GetName() == "ctor" && + c.Parameters.Length == 1 && + c.Parameters[0].Type.SpecialType == SpecialType.System_Int64) + .Cast() + .FirstOrDefault(); + } + + + protected void PopulateExpression(TextWriter trapFile) + { + var constructor = Constructor.Create(Context, constructorSymbol); + trapFile.expr_call(this, constructor); + } + + protected new Expression TryPopulate() + { + Context.Try(null, null, () => PopulateExpression(Context.TrapWriter.Writer)); + return this; + } + + // Gets an expression that represents a System.DateTime object creation. + // The `type` symbol must be a System.DateTime type and the value must be a System.DateTime object. + // The expression that is being created is a call to the System.DateTime(long) constructor, where + // the number of ticks from the `value` object is used as the argument to the constructor call. + public static Expression CreateGenerated(Context cx, IExpressionParentEntity parent, int childIndex, ITypeSymbol type, object? value, Extraction.Entities.Location location) + { + var constructorSymbol = GetDateTimeConstructor(type) ?? throw new InternalError("Could not find symbol for System.DateTime(long)"); + var expr = new DateTimeObjectCreation(constructorSymbol, new ExpressionInfo( + cx, + AnnotatedTypeSymbol.CreateNotAnnotated(type), + location, + ExprKind.OBJECT_CREATION, + parent, + childIndex, + true, + null)); + + var longTypeSymbol = constructorSymbol.Parameters[0].Type; + Literal.CreateGenerated(cx, expr, 0, longTypeSymbol, ValueAsLong(value), location); + + return expr.TryPopulate(); + } + } +} \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs index ec4f44c21c7..79855875d02 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs @@ -381,8 +381,17 @@ namespace Semmle.Extraction.CSharp references => ResolveReferences(compilerArguments, analyser, canonicalPathCache, references), (analyser, syntaxTrees) => { + var paths = compilerArguments.SourceFiles + .Select(src => src.Path) + .ToList(); + + if (compilerArguments.GeneratedFilesOutputDirectory is not null) + { + paths.AddRange(Directory.GetFiles(compilerArguments.GeneratedFilesOutputDirectory, "*.cs", SearchOption.AllDirectories)); + } + return ReadSyntaxTrees( - compilerArguments.SourceFiles.Select(src => canonicalPathCache.GetCanonicalPath(src.Path)), + paths.Select(canonicalPathCache.GetCanonicalPath), analyser, compilerArguments.ParseOptions, compilerArguments.Encoding, diff --git a/csharp/ql/integration-tests/all-platforms/cshtml/Files.expected b/csharp/ql/integration-tests/all-platforms/cshtml/Files.expected new file mode 100644 index 00000000000..86a8cd34b88 --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/cshtml/Files.expected @@ -0,0 +1,6 @@ +| Program.cs:0:0:0:0 | Program.cs | +| obj/Debug/net7.0/.NETCoreApp,Version=v7.0.AssemblyAttributes.cs:0:0:0:0 | obj/Debug/net7.0/.NETCoreApp,Version=v7.0.AssemblyAttributes.cs | +| obj/Debug/net7.0/cshtml.AssemblyInfo.cs:0:0:0:0 | obj/Debug/net7.0/cshtml.AssemblyInfo.cs | +| obj/Debug/net7.0/cshtml.GlobalUsings.g.cs:0:0:0:0 | obj/Debug/net7.0/cshtml.GlobalUsings.g.cs | +| obj/Debug/net7.0/cshtml.RazorAssemblyInfo.cs:0:0:0:0 | obj/Debug/net7.0/cshtml.RazorAssemblyInfo.cs | +| obj/Debug/net7.0/generated/Microsoft.NET.Sdk.Razor.SourceGenerators/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Views_Home_Index_cshtml.g.cs:0:0:0:0 | obj/Debug/net7.0/generated/Microsoft.NET.Sdk.Razor.SourceGenerators/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Views_Home_Index_cshtml.g.cs | diff --git a/csharp/ql/integration-tests/all-platforms/cshtml/Files.ql b/csharp/ql/integration-tests/all-platforms/cshtml/Files.ql new file mode 100644 index 00000000000..bea5557a25f --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/cshtml/Files.ql @@ -0,0 +1,5 @@ +import csharp + +from File f +where f.fromSource() +select f diff --git a/csharp/ql/integration-tests/all-platforms/cshtml/Program.cs b/csharp/ql/integration-tests/all-platforms/cshtml/Program.cs new file mode 100644 index 00000000000..47eee48cc79 --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/cshtml/Program.cs @@ -0,0 +1 @@ +var dummy = "dummy"; \ No newline at end of file diff --git a/csharp/ql/integration-tests/all-platforms/cshtml/Views/Home/Index.cshtml b/csharp/ql/integration-tests/all-platforms/cshtml/Views/Home/Index.cshtml new file mode 100644 index 00000000000..52ffe012e42 --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/cshtml/Views/Home/Index.cshtml @@ -0,0 +1,8 @@ +@{ + ViewData["Title"] = "Home Page"; +} + +
+

Welcome

+

Learn about building Web apps with ASP.NET Core.

+
diff --git a/csharp/ql/integration-tests/all-platforms/cshtml/cshtml.csproj b/csharp/ql/integration-tests/all-platforms/cshtml/cshtml.csproj new file mode 100644 index 00000000000..01d15e87dc4 --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/cshtml/cshtml.csproj @@ -0,0 +1,14 @@ + + + + Exe + net7.0 + enable + enable + + + + + + + diff --git a/csharp/ql/integration-tests/all-platforms/cshtml/test.py b/csharp/ql/integration-tests/all-platforms/cshtml/test.py new file mode 100644 index 00000000000..24cc83b4f2d --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/cshtml/test.py @@ -0,0 +1,3 @@ +from create_database_utils import * + +run_codeql_database_create(['dotnet build'], lang="csharp", extra_args=["--extractor-option=cil=false"]) diff --git a/csharp/ql/lib/change-notes/2023-05-17-update-csharp-sink-kinds.md b/csharp/ql/lib/change-notes/2023-05-17-update-csharp-sink-kinds.md new file mode 100644 index 00000000000..ce6d618af5e --- /dev/null +++ b/csharp/ql/lib/change-notes/2023-05-17-update-csharp-sink-kinds.md @@ -0,0 +1,9 @@ +--- +category: minorAnalysis +--- +* Updated the following C# sink kind names. Any custom data extensions that use these sink kinds will need to be updated accordingly in order to continue working. + * `code` to `code-injection` + * `sql` to `sql-injection` + * `html` to `html-injection` + * `xss` to `js-injection` + * `remote` to `file-content-store` diff --git a/csharp/ql/lib/change-notes/2023-05-30-source-generators.md b/csharp/ql/lib/change-notes/2023-05-30-source-generators.md new file mode 100644 index 00000000000..5483ce6af35 --- /dev/null +++ b/csharp/ql/lib/change-notes/2023-05-30-source-generators.md @@ -0,0 +1,4 @@ +--- +category: majorAnalysis +--- +* The extractor has been changed to run after the traced compiler call. This allows inspecting compiler generated files, such as the output of source generators. With this change, `.cshtml` files and their generated `.cshtml.g.cs` counterparts are extracted on dotnet 6 and above. diff --git a/csharp/ql/lib/ext/Dapper.model.yml b/csharp/ql/lib/ext/Dapper.model.yml index e72f3b076a6..78e92bbf191 100644 --- a/csharp/ql/lib/ext/Dapper.model.yml +++ b/csharp/ql/lib/ext/Dapper.model.yml @@ -3,58 +3,58 @@ extensions: pack: codeql/csharp-all extensible: sinkModel data: - - ["Dapper", "SqlMapper", False, "Execute", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "ExecuteAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "ExecuteReader", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "ExecuteReaderAsync", "(System.Data.DbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "ExecuteReaderAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "ExecuteScalar", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "ExecuteScalar<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "ExecuteScalarAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "ExecuteScalarAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "Query", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Boolean,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["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", "manual"] - - ["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", "manual"] - - ["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", "manual"] - - ["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", "manual"] - - ["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", "manual"] - - ["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", "manual"] - - ["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", "manual"] - - ["Dapper", "SqlMapper", False, "Query<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Boolean,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["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", "manual"] - - ["Dapper", "SqlMapper", False, "QueryAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["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", "manual"] - - ["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", "manual"] - - ["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", "manual"] - - ["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", "manual"] - - ["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", "manual"] - - ["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", "manual"] - - ["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", "manual"] - - ["Dapper", "SqlMapper", False, "QueryAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["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", "manual"] - - ["Dapper", "SqlMapper", False, "QueryFirst", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QueryFirst", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[2]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QueryFirst<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QueryFirstAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QueryFirstAsync", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[2]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QueryFirstAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QueryFirstOrDefault", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QueryFirstOrDefault", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[2]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QueryFirstOrDefault<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QueryFirstOrDefaultAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QueryFirstOrDefaultAsync", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[2]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QueryFirstOrDefaultAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QueryMultiple", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QueryMultipleAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QuerySingle", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QuerySingle", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[2]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QuerySingle<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QuerySingleAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QuerySingleAsync", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[2]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QuerySingleAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QuerySingleOrDefault", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QuerySingleOrDefault", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[2]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QuerySingleOrDefault<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QuerySingleOrDefaultAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QuerySingleOrDefaultAsync", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[2]", "sql", "manual"] - - ["Dapper", "SqlMapper", False, "QuerySingleOrDefaultAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql", "manual"] + - ["Dapper", "SqlMapper", False, "Execute", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "ExecuteAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "ExecuteReader", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "ExecuteReaderAsync", "(System.Data.DbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "ExecuteReaderAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "ExecuteScalar", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "ExecuteScalar<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "ExecuteScalarAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "ExecuteScalarAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "Query", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Boolean,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["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-injection", "manual"] + - ["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-injection", "manual"] + - ["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-injection", "manual"] + - ["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-injection", "manual"] + - ["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-injection", "manual"] + - ["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-injection", "manual"] + - ["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-injection", "manual"] + - ["Dapper", "SqlMapper", False, "Query<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Boolean,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["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-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QueryAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["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-injection", "manual"] + - ["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-injection", "manual"] + - ["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-injection", "manual"] + - ["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-injection", "manual"] + - ["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-injection", "manual"] + - ["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-injection", "manual"] + - ["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-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QueryAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["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-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QueryFirst", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QueryFirst", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[2]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QueryFirst<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QueryFirstAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QueryFirstAsync", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[2]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QueryFirstAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QueryFirstOrDefault", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QueryFirstOrDefault", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[2]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QueryFirstOrDefault<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QueryFirstOrDefaultAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QueryFirstOrDefaultAsync", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[2]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QueryFirstOrDefaultAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QueryMultiple", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QueryMultipleAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QuerySingle", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QuerySingle", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[2]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QuerySingle<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QuerySingleAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QuerySingleAsync", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[2]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QuerySingleAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QuerySingleOrDefault", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QuerySingleOrDefault", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[2]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QuerySingleOrDefault<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QuerySingleOrDefaultAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QuerySingleOrDefaultAsync", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[2]", "sql-injection", "manual"] + - ["Dapper", "SqlMapper", False, "QuerySingleOrDefaultAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable,System.Nullable)", "", "Argument[1]", "sql-injection", "manual"] diff --git a/csharp/ql/lib/ext/Microsoft.ApplicationBlocks.Data.model.yml b/csharp/ql/lib/ext/Microsoft.ApplicationBlocks.Data.model.yml index 5b5e2657bfd..0bb437b5b44 100644 --- a/csharp/ql/lib/ext/Microsoft.ApplicationBlocks.Data.model.yml +++ b/csharp/ql/lib/ext/Microsoft.ApplicationBlocks.Data.model.yml @@ -3,31 +3,31 @@ extensions: pack: codeql/csharp-all extensible: sinkModel data: - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteDataset", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String)", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteDataset", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteDataset", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String)", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteDataset", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteDataset", "(System.String,System.Data.CommandType,System.String)", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteDataset", "(System.String,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteNonQuery", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String)", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteNonQuery", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteNonQuery", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String)", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteNonQuery", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteNonQuery", "(System.String,System.Data.CommandType,System.String)", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteNonQuery", "(System.String,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteReader", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String)", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteReader", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteReader", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String)", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteReader", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteReader", "(System.String,System.Data.CommandType,System.String)", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteReader", "(System.String,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteScalar", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String)", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteScalar", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteScalar", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String)", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteScalar", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteScalar", "(System.String,System.Data.CommandType,System.String)", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteScalar", "(System.String,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteXmlReader", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String)", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteXmlReader", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteXmlReader", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String)", "", "Argument[2]", "sql", "manual"] - - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteXmlReader", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteDataset", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String)", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteDataset", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteDataset", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String)", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteDataset", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteDataset", "(System.String,System.Data.CommandType,System.String)", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteDataset", "(System.String,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteNonQuery", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String)", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteNonQuery", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteNonQuery", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String)", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteNonQuery", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteNonQuery", "(System.String,System.Data.CommandType,System.String)", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteNonQuery", "(System.String,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteReader", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String)", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteReader", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteReader", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String)", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteReader", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteReader", "(System.String,System.Data.CommandType,System.String)", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteReader", "(System.String,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteScalar", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String)", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteScalar", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteScalar", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String)", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteScalar", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteScalar", "(System.String,System.Data.CommandType,System.String)", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteScalar", "(System.String,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteXmlReader", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String)", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteXmlReader", "(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteXmlReader", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String)", "", "Argument[2]", "sql-injection", "manual"] + - ["Microsoft.ApplicationBlocks.Data", "SqlHelper", False, "ExecuteXmlReader", "(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[])", "", "Argument[2]", "sql-injection", "manual"] diff --git a/csharp/ql/lib/ext/Microsoft.EntityFrameworkCore.model.yml b/csharp/ql/lib/ext/Microsoft.EntityFrameworkCore.model.yml index 3928adf0624..23fefe987a7 100644 --- a/csharp/ql/lib/ext/Microsoft.EntityFrameworkCore.model.yml +++ b/csharp/ql/lib/ext/Microsoft.EntityFrameworkCore.model.yml @@ -1,11 +1,29 @@ extensions: + - addsTo: + pack: codeql/csharp-all + extensible: summaryModel + data: + - ["Microsoft.EntityFrameworkCore", "DbSet<>", False, "Add", "(TEntity)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] + - ["Microsoft.EntityFrameworkCore", "DbSet<>", False, "AddAsync", "(TEntity,System.Threading.CancellationToken)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] + - ["Microsoft.EntityFrameworkCore", "DbSet<>", False, "AddRange", "(System.Collections.Generic.IEnumerable)", "", "Argument[0].WithElement", "Argument[this]", "value", "manual"] + - ["Microsoft.EntityFrameworkCore", "DbSet<>", False, "AddRange", "(TEntity[])", "", "Argument[0].WithElement", "Argument[this]", "value", "manual"] + - ["Microsoft.EntityFrameworkCore", "DbSet<>", False, "AddRangeAsync", "(System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[0].WithElement", "Argument[this]", "value", "manual"] + - ["Microsoft.EntityFrameworkCore", "DbSet<>", False, "AddRangeAsync", "(TEntity[])", "", "Argument[0].WithElement", "Argument[this]", "value", "manual"] + - ["Microsoft.EntityFrameworkCore", "DbSet<>", False, "Attach", "(TEntity)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] + - ["Microsoft.EntityFrameworkCore", "DbSet<>", False, "AttachRange", "(System.Collections.Generic.IEnumerable)", "", "Argument[0].WithElement", "Argument[this]", "value", "manual"] + - ["Microsoft.EntityFrameworkCore", "DbSet<>", False, "AttachRange", "(TEntity[])", "", "Argument[0].WithElement", "Argument[this]", "value", "manual"] + - ["Microsoft.EntityFrameworkCore", "DbSet<>", False, "Update", "(TEntity)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] + - ["Microsoft.EntityFrameworkCore", "DbSet<>", False, "UpdateRange", "(System.Collections.Generic.IEnumerable)", "", "Argument[0].WithElement", "Argument[this]", "value", "manual"] + - ["Microsoft.EntityFrameworkCore", "DbSet<>", False, "UpdateRange", "(TEntity[])", "", "Argument[0].WithElement", "Argument[this]", "value", "manual"] + + - addsTo: pack: codeql/csharp-all extensible: sinkModel data: - - ["Microsoft.EntityFrameworkCore", "RelationalDatabaseFacadeExtensions", False, "ExecuteSqlRaw", "(Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql", "manual"] - - ["Microsoft.EntityFrameworkCore", "RelationalDatabaseFacadeExtensions", False, "ExecuteSqlRaw", "(Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade,System.String,System.Object[])", "", "Argument[1]", "sql", "manual"] - - ["Microsoft.EntityFrameworkCore", "RelationalDatabaseFacadeExtensions", False, "ExecuteSqlRawAsync", "(Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["Microsoft.EntityFrameworkCore", "RelationalDatabaseFacadeExtensions", False, "ExecuteSqlRawAsync", "(Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade,System.String,System.Object[])", "", "Argument[1]", "sql", "manual"] - - ["Microsoft.EntityFrameworkCore", "RelationalDatabaseFacadeExtensions", False, "ExecuteSqlRawAsync", "(Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["Microsoft.EntityFrameworkCore", "RelationalQueryableExtensions", False, "FromSqlRaw<>", "(Microsoft.EntityFrameworkCore.DbSet,System.String,System.Object[])", "", "Argument[1]", "sql", "manual"] + - ["Microsoft.EntityFrameworkCore", "RelationalDatabaseFacadeExtensions", False, "ExecuteSqlRaw", "(Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql-injection", "manual"] + - ["Microsoft.EntityFrameworkCore", "RelationalDatabaseFacadeExtensions", False, "ExecuteSqlRaw", "(Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade,System.String,System.Object[])", "", "Argument[1]", "sql-injection", "manual"] + - ["Microsoft.EntityFrameworkCore", "RelationalDatabaseFacadeExtensions", False, "ExecuteSqlRawAsync", "(Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["Microsoft.EntityFrameworkCore", "RelationalDatabaseFacadeExtensions", False, "ExecuteSqlRawAsync", "(Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade,System.String,System.Object[])", "", "Argument[1]", "sql-injection", "manual"] + - ["Microsoft.EntityFrameworkCore", "RelationalDatabaseFacadeExtensions", False, "ExecuteSqlRawAsync", "(Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["Microsoft.EntityFrameworkCore", "RelationalQueryableExtensions", False, "FromSqlRaw<>", "(Microsoft.EntityFrameworkCore.DbSet,System.String,System.Object[])", "", "Argument[1]", "sql-injection", "manual"] diff --git a/csharp/ql/lib/ext/MySql.Data.MySqlClient.model.yml b/csharp/ql/lib/ext/MySql.Data.MySqlClient.model.yml index 70d849e122a..2e1c75b0873 100644 --- a/csharp/ql/lib/ext/MySql.Data.MySqlClient.model.yml +++ b/csharp/ql/lib/ext/MySql.Data.MySqlClient.model.yml @@ -3,51 +3,51 @@ extensions: pack: codeql/csharp-all extensible: sinkModel data: - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDataRow", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDataRowAsync", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDataRowAsync", "(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDataset", "(MySql.Data.MySqlClient.MySqlConnection,System.String)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDataset", "(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDataset", "(System.String,System.String)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDataset", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDatasetAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDatasetAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDatasetAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDatasetAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDatasetAsync", "(System.String,System.String)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDatasetAsync", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDatasetAsync", "(System.String,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDatasetAsync", "(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteNonQuery", "(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteNonQuery", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteNonQueryAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteNonQueryAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteNonQueryAsync", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteNonQueryAsync", "(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReader", "(MySql.Data.MySqlClient.MySqlConnection,System.String)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReader", "(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReader", "(System.String,System.String)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReader", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReaderAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReaderAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReaderAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReaderAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReaderAsync", "(System.String,System.String)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReaderAsync", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReaderAsync", "(System.String,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReaderAsync", "(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalar", "(MySql.Data.MySqlClient.MySqlConnection,System.String)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalar", "(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalar", "(System.String,System.String)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalar", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalarAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalarAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalarAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalarAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalarAsync", "(System.String,System.String)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalarAsync", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalarAsync", "(System.String,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalarAsync", "(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "UpdateDataset", "(System.String,System.String,System.Data.DataSet,System.String)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "UpdateDatasetAsync", "(System.String,System.String,System.Data.DataSet,System.String)", "", "Argument[1]", "sql", "manual"] - - ["MySql.Data.MySqlClient", "MySqlHelper", False, "UpdateDatasetAsync", "(System.String,System.String,System.Data.DataSet,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDataRow", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDataRowAsync", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDataRowAsync", "(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDataset", "(MySql.Data.MySqlClient.MySqlConnection,System.String)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDataset", "(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDataset", "(System.String,System.String)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDataset", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDatasetAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDatasetAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDatasetAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDatasetAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDatasetAsync", "(System.String,System.String)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDatasetAsync", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDatasetAsync", "(System.String,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteDatasetAsync", "(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteNonQuery", "(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteNonQuery", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteNonQueryAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteNonQueryAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteNonQueryAsync", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteNonQueryAsync", "(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReader", "(MySql.Data.MySqlClient.MySqlConnection,System.String)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReader", "(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReader", "(System.String,System.String)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReader", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReaderAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReaderAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReaderAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReaderAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReaderAsync", "(System.String,System.String)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReaderAsync", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReaderAsync", "(System.String,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteReaderAsync", "(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalar", "(MySql.Data.MySqlClient.MySqlConnection,System.String)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalar", "(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalar", "(System.String,System.String)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalar", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalarAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalarAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalarAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalarAsync", "(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalarAsync", "(System.String,System.String)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalarAsync", "(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalarAsync", "(System.String,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "ExecuteScalarAsync", "(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[])", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "UpdateDataset", "(System.String,System.String,System.Data.DataSet,System.String)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "UpdateDatasetAsync", "(System.String,System.String,System.Data.DataSet,System.String)", "", "Argument[1]", "sql-injection", "manual"] + - ["MySql.Data.MySqlClient", "MySqlHelper", False, "UpdateDatasetAsync", "(System.String,System.String,System.Data.DataSet,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] diff --git a/csharp/ql/lib/ext/ServiceStack.OrmLite.model.yml b/csharp/ql/lib/ext/ServiceStack.OrmLite.model.yml index ea7634bc244..3d6148c330f 100644 --- a/csharp/ql/lib/ext/ServiceStack.OrmLite.model.yml +++ b/csharp/ql/lib/ext/ServiceStack.OrmLite.model.yml @@ -3,95 +3,95 @@ extensions: pack: codeql/csharp-all extensible: sinkModel data: - - ["ServiceStack.OrmLite", "IUntypedSqlExpression", True, "UnsafeAnd", "(System.String,System.Object[])", "", "Argument[0]", "sql", "manual"] - - ["ServiceStack.OrmLite", "IUntypedSqlExpression", True, "UnsafeFrom", "(System.String)", "", "Argument[0]", "sql", "manual"] - - ["ServiceStack.OrmLite", "IUntypedSqlExpression", True, "UnsafeOr", "(System.String,System.Object[])", "", "Argument[0]", "sql", "manual"] - - ["ServiceStack.OrmLite", "IUntypedSqlExpression", True, "UnsafeSelect", "(System.String)", "", "Argument[0]", "sql", "manual"] - - ["ServiceStack.OrmLite", "IUntypedSqlExpression", True, "UnsafeWhere", "(System.String,System.Object[])", "", "Argument[0]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Column<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Column<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "ColumnDistinct<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "ColumnDistinct<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "ColumnLazy<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "ColumnLazy<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Dictionary<,>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "ExecuteNonQuery", "(System.Data.IDbConnection,System.String)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "ExecuteNonQuery", "(System.Data.IDbConnection,System.String,System.Action)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "ExecuteNonQuery", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "ExecuteNonQuery", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Exists<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "KeyValuePairs", "(System.Data.IDbConnection,System.String,System.System.Object)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Lookup<,>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Lookup<,>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Scalar<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Scalar<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Select<>", "(System.Data.IDbConnection,System.String)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Select<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Select<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Select<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Select<>", "(System.Data.IDbConnection,System.Type,System.String,System.Object)", "", "Argument[2]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SelectLazy<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SelectNonDefaults<>", "(System.Data.IDbConnection,System.String,T)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Single<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Single<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlColumn<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlColumn<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlColumn<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlList<>", "(System.Data.IDbConnection,System.String,System.Action)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlList<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlList<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlList<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlScalar<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlScalar<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlScalar<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ColumnAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ColumnAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ColumnDistinctAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ColumnDistinctAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "DictionaryAsync<,>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ExecuteNonQueryAsync", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ExecuteNonQueryAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ExecuteNonQueryAsync", "(System.Data.IDbConnection,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ExistsAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "KeyValuePairsAsync<,>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "KeyValuePairsAsync<,>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "LookupAsync<,>", "(System.Data.IDbCommand,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "LookupAsync<,>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "LookupAsync<,>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ScalarAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ScalarAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SelectAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SelectAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SelectAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SelectAsync<>", "(System.Data.IDbConnection,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SelectAsync<>", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[2]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SelectNonDefaultsAsync<>", "(System.Data.IDbConnection,System.String,T,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SingleAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SingleAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlColumnAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlColumnAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlColumnAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlListAsync<>", "(System.Data.IDbConnection,System.String,System.Action,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlListAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlListAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlListAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlScalarAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlScalarAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlScalarAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadExpressionsApi", False, "RowCount", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadExpressionsApi", False, "RowCount", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteReadExpressionsApiAsync", False, "RowCountAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteWriteApi", False, "ExecuteSql", "(System.Data.IDbConnection,System.String)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteWriteApi", False, "ExecuteSql", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteWriteApi", False, "ExecuteSql", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteWriteApiAsync", False, "ExecuteSqlAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "OrmLiteWriteApiAsync", False, "ExecuteSqlAsync", "(System.Data.IDbConnection,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql", "manual"] - - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeAnd", "(System.String,System.Object[])", "", "Argument[0]", "sql", "manual"] - - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeFrom", "(System.String)", "", "Argument[0]", "sql", "manual"] - - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeGroupBy", "(System.String)", "", "Argument[0]", "sql", "manual"] - - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeHaving", "(System.String,System.Object[])", "", "Argument[0]", "sql", "manual"] - - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeOr", "(System.String,System.Object[])", "", "Argument[0]", "sql", "manual"] - - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeOrderBy", "(System.String)", "", "Argument[0]", "sql", "manual"] - - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeSelect", "(System.String)", "", "Argument[0]", "sql", "manual"] - - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeSelect", "(System.String,System.Boolean)", "", "Argument[0]", "sql", "manual"] - - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeWhere", "(System.String,System.Object[])", "", "Argument[0]", "sql", "manual"] + - ["ServiceStack.OrmLite", "IUntypedSqlExpression", True, "UnsafeAnd", "(System.String,System.Object[])", "", "Argument[0]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "IUntypedSqlExpression", True, "UnsafeFrom", "(System.String)", "", "Argument[0]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "IUntypedSqlExpression", True, "UnsafeOr", "(System.String,System.Object[])", "", "Argument[0]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "IUntypedSqlExpression", True, "UnsafeSelect", "(System.String)", "", "Argument[0]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "IUntypedSqlExpression", True, "UnsafeWhere", "(System.String,System.Object[])", "", "Argument[0]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Column<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Column<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "ColumnDistinct<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "ColumnDistinct<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "ColumnLazy<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "ColumnLazy<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Dictionary<,>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "ExecuteNonQuery", "(System.Data.IDbConnection,System.String)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "ExecuteNonQuery", "(System.Data.IDbConnection,System.String,System.Action)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "ExecuteNonQuery", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "ExecuteNonQuery", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Exists<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "KeyValuePairs", "(System.Data.IDbConnection,System.String,System.System.Object)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Lookup<,>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Lookup<,>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Scalar<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Scalar<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Select<>", "(System.Data.IDbConnection,System.String)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Select<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Select<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Select<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Select<>", "(System.Data.IDbConnection,System.Type,System.String,System.Object)", "", "Argument[2]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SelectLazy<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SelectNonDefaults<>", "(System.Data.IDbConnection,System.String,T)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Single<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "Single<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlColumn<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlColumn<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlColumn<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlList<>", "(System.Data.IDbConnection,System.String,System.Action)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlList<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlList<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlList<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlScalar<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlScalar<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApi", False, "SqlScalar<>", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ColumnAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ColumnAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ColumnDistinctAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ColumnDistinctAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "DictionaryAsync<,>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ExecuteNonQueryAsync", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ExecuteNonQueryAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ExecuteNonQueryAsync", "(System.Data.IDbConnection,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ExistsAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "KeyValuePairsAsync<,>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "KeyValuePairsAsync<,>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "LookupAsync<,>", "(System.Data.IDbCommand,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "LookupAsync<,>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "LookupAsync<,>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ScalarAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "ScalarAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SelectAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SelectAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SelectAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SelectAsync<>", "(System.Data.IDbConnection,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SelectAsync<>", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[2]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SelectNonDefaultsAsync<>", "(System.Data.IDbConnection,System.String,T,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SingleAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SingleAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlColumnAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlColumnAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlColumnAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlListAsync<>", "(System.Data.IDbConnection,System.String,System.Action,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlListAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlListAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlListAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlScalarAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlScalarAsync<>", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadApiAsync", False, "SqlScalarAsync<>", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadExpressionsApi", False, "RowCount", "(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadExpressionsApi", False, "RowCount", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteReadExpressionsApiAsync", False, "RowCountAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteWriteApi", False, "ExecuteSql", "(System.Data.IDbConnection,System.String)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteWriteApi", False, "ExecuteSql", "(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteWriteApi", False, "ExecuteSql", "(System.Data.IDbConnection,System.String,System.Object)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteWriteApiAsync", False, "ExecuteSqlAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "OrmLiteWriteApiAsync", False, "ExecuteSqlAsync", "(System.Data.IDbConnection,System.String,System.Threading.CancellationToken)", "", "Argument[1]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeAnd", "(System.String,System.Object[])", "", "Argument[0]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeFrom", "(System.String)", "", "Argument[0]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeGroupBy", "(System.String)", "", "Argument[0]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeHaving", "(System.String,System.Object[])", "", "Argument[0]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeOr", "(System.String,System.Object[])", "", "Argument[0]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeOrderBy", "(System.String)", "", "Argument[0]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeSelect", "(System.String)", "", "Argument[0]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeSelect", "(System.String,System.Boolean)", "", "Argument[0]", "sql-injection", "manual"] + - ["ServiceStack.OrmLite", "SqlExpression<>", True, "UnsafeWhere", "(System.String,System.Object[])", "", "Argument[0]", "sql-injection", "manual"] diff --git a/csharp/ql/lib/ext/ServiceStack.Redis.model.yml b/csharp/ql/lib/ext/ServiceStack.Redis.model.yml index 46415828318..9016c393077 100644 --- a/csharp/ql/lib/ext/ServiceStack.Redis.model.yml +++ b/csharp/ql/lib/ext/ServiceStack.Redis.model.yml @@ -3,30 +3,30 @@ extensions: pack: codeql/csharp-all extensible: sinkModel data: - - ["ServiceStack.Redis", "IRedisClient", True, "Custom", "(System.Object[])", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClient", True, "ExecCachedLua", "(System.String,System.Func)", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClient", True, "ExecLua", "(System.String,System.String[])", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClient", True, "ExecLua", "(System.String,System.String[],System.String[])", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClient", True, "ExecLuaAsInt", "(System.String,System.String[])", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClient", True, "ExecLuaAsInt", "(System.String,System.String[],System.String[])", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClient", True, "ExecLuaAsList", "(System.String,System.String[])", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClient", True, "ExecLuaAsList", "(System.String,System.String[],System.String[])", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClient", True, "ExecLuaAsString", "(System.String,System.String[])", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClient", True, "ExecLuaAsString", "(System.String,System.String[],System.String[])", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClient", True, "LoadLuaScript", "(System.String)", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClientAsync", True, "CustomAsync", "(System.Object[])", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClientAsync", True, "CustomAsync", "(System.Object[],System.Threading.CancellationToken)", "", "Argument[0].Element", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecCachedLuaAsync", "(System.String,System.Func>,System.Threading.CancellationToken)", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsIntAsync", "(System.String,System.String[])", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsIntAsync", "(System.String,System.String[],System.String[],System.Threading.CancellationToken)", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsIntAsync", "(System.String,System.String[],System.Threading.CancellationToken)", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsListAsync", "(System.String,System.String[])", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsListAsync", "(System.String,System.String[],System.String[],System.Threading.CancellationToken)", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsListAsync", "(System.String,System.String[],System.Threading.CancellationToken)", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsStringAsync", "(System.String,System.String[])", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsStringAsync", "(System.String,System.String[],System.String[],System.Threading.CancellationToken)", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsStringAsync", "(System.String,System.String[],System.Threading.CancellationToken)", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsync", "(System.String,System.String[])", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsync", "(System.String,System.String[],System.String[],System.Threading.CancellationToken)", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsync", "(System.String,System.String[],System.Threading.CancellationToken)", "", "Argument[0]", "code", "manual"] - - ["ServiceStack.Redis", "IRedisClientAsync", True, "LoadLuaScriptAsync", "(System.String,System.Threading.CancellationToken)", "", "Argument[0]", "code", "manual"] + - ["ServiceStack.Redis", "IRedisClient", True, "Custom", "(System.Object[])", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClient", True, "ExecCachedLua", "(System.String,System.Func)", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClient", True, "ExecLua", "(System.String,System.String[])", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClient", True, "ExecLua", "(System.String,System.String[],System.String[])", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClient", True, "ExecLuaAsInt", "(System.String,System.String[])", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClient", True, "ExecLuaAsInt", "(System.String,System.String[],System.String[])", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClient", True, "ExecLuaAsList", "(System.String,System.String[])", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClient", True, "ExecLuaAsList", "(System.String,System.String[],System.String[])", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClient", True, "ExecLuaAsString", "(System.String,System.String[])", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClient", True, "ExecLuaAsString", "(System.String,System.String[],System.String[])", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClient", True, "LoadLuaScript", "(System.String)", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClientAsync", True, "CustomAsync", "(System.Object[])", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClientAsync", True, "CustomAsync", "(System.Object[],System.Threading.CancellationToken)", "", "Argument[0].Element", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecCachedLuaAsync", "(System.String,System.Func>,System.Threading.CancellationToken)", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsIntAsync", "(System.String,System.String[])", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsIntAsync", "(System.String,System.String[],System.String[],System.Threading.CancellationToken)", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsIntAsync", "(System.String,System.String[],System.Threading.CancellationToken)", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsListAsync", "(System.String,System.String[])", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsListAsync", "(System.String,System.String[],System.String[],System.Threading.CancellationToken)", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsListAsync", "(System.String,System.String[],System.Threading.CancellationToken)", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsStringAsync", "(System.String,System.String[])", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsStringAsync", "(System.String,System.String[],System.String[],System.Threading.CancellationToken)", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsStringAsync", "(System.String,System.String[],System.Threading.CancellationToken)", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsync", "(System.String,System.String[])", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsync", "(System.String,System.String[],System.String[],System.Threading.CancellationToken)", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClientAsync", True, "ExecLuaAsync", "(System.String,System.String[],System.Threading.CancellationToken)", "", "Argument[0]", "code-injection", "manual"] + - ["ServiceStack.Redis", "IRedisClientAsync", True, "LoadLuaScriptAsync", "(System.String,System.Threading.CancellationToken)", "", "Argument[0]", "code-injection", "manual"] diff --git a/csharp/ql/lib/ext/ServiceStack.model.yml b/csharp/ql/lib/ext/ServiceStack.model.yml index 988c7f3b8f9..19188e5eeb5 100644 --- a/csharp/ql/lib/ext/ServiceStack.model.yml +++ b/csharp/ql/lib/ext/ServiceStack.model.yml @@ -3,81 +3,81 @@ extensions: pack: codeql/csharp-all extensible: sinkModel data: - - ["ServiceStack", "IOneWayClient", True, "SendAllOneWay", "(System.Collections.Generic.IEnumerable)", "", "Argument[1].Element", "remote", "manual"] - - ["ServiceStack", "IOneWayClient", True, "SendOneWay", "(System.Object)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IOneWayClient", True, "SendOneWay", "(System.String,System.Object)", "", "Argument[1]", "remote", "manual"] - - ["ServiceStack", "IRestClient", True, "Patch<>", "(System.String,System.Object)", "", "Argument[1]", "remote", "manual"] - - ["ServiceStack", "IRestClient", True, "Post<>", "(System.String,System.Object)", "", "Argument[1]", "remote", "manual"] - - ["ServiceStack", "IRestClient", True, "Put<>", "(System.String,System.Object)", "", "Argument[1]", "remote", "manual"] - - ["ServiceStack", "IRestClient", True, "Send<>", "(System.String,System.String,System.Object)", "", "Argument[2]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "CustomMethodAsync", "(System.String,ServiceStack.IReturnVoid,System.Threading.CancellationToken)", "", "Argument[1]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "CustomMethodAsync<>", "(System.String,ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[1]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "CustomMethodAsync<>", "(System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "DeleteAsync", "(ServiceStack.IReturnVoid,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "DeleteAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "DeleteAsync<>", "(System.Object,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "GetAsync", "(ServiceStack.IReturnVoid,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "GetAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "GetAsync<>", "(System.Object,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "PatchAsync", "(ServiceStack.IReturnVoid,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "PatchAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "PatchAsync<>", "(System.Object,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "PostAsync", "(ServiceStack.IReturnVoid,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "PostAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "PostAsync<>", "(System.Object,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "PutAsync", "(ServiceStack.IReturnVoid,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "PutAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientAsync", True, "PutAsync<>", "(System.Object,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "CustomMethod", "(System.String,ServiceStack.IReturnVoid)", "", "Argument[1]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "CustomMethod<>", "(System.String,ServiceStack.IReturn)", "", "Argument[1]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "CustomMethod<>", "(System.String,System.Object)", "", "Argument[1]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "Delete", "(ServiceStack.IReturnVoid)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "Delete<>", "(ServiceStack.IReturn)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "Delete<>", "(System.Object)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "Get", "(ServiceStack.IReturnVoid)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "Get<>", "(ServiceStack.IReturn)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "Get<>", "(System.Object)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "Patch", "(ServiceStack.IReturnVoid)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "Patch<>", "(ServiceStack.IReturn)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "Patch<>", "(System.Object)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "Post", "(ServiceStack.IReturnVoid)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "Post<>", "(ServiceStack.IReturn)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "Post<>", "(System.Object)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "Put", "(ServiceStack.IReturnVoid)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "Put<>", "(ServiceStack.IReturn)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestClientSync", True, "Put<>", "(System.Object)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestGateway", True, "Delete<>", "(ServiceStack.IReturn)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestGateway", True, "Get<>", "(ServiceStack.IReturn)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestGateway", True, "Post<>", "(ServiceStack.IReturn)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestGateway", True, "Put<>", "(ServiceStack.IReturn)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestGateway", True, "Send<>", "(ServiceStack.IReturn)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestGatewayAsync", True, "DeleteAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestGatewayAsync", True, "GetAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestGatewayAsync", True, "PostAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestGatewayAsync", True, "PutAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IRestGatewayAsync", True, "SendAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IServiceGateway", True, "Publish", "(System.Object)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IServiceGateway", True, "PublishAll", "(System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "remote", "manual"] - - ["ServiceStack", "IServiceGateway", True, "Send<>", "(System.Object)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IServiceGateway", True, "SendAll<>", "(System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "remote", "manual"] - - ["ServiceStack", "IServiceGatewayAsync", True, "PublishAllAsync", "(System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[0].Element", "remote", "manual"] - - ["ServiceStack", "IServiceGatewayAsync", True, "PublishAsync", "(System.Object,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "IServiceGatewayAsync", True, "SendAllAsync<>", "(System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[0].Element", "remote", "manual"] - - ["ServiceStack", "IServiceGatewayAsync", True, "SendAsync<>", "(System.Object,System.Threading.CancellationToken)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "ServiceClientBase", True, "CustomMethod", "(System.String,System.String,System.Object)", "", "Argument[2]", "remote", "manual"] - - ["ServiceStack", "ServiceClientBase", True, "CustomMethod<>", "(System.String,System.String,System.Object)", "", "Argument[2]", "remote", "manual"] - - ["ServiceStack", "ServiceClientBase", True, "CustomMethodAsync<>", "(System.String,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[2]", "remote", "manual"] - - ["ServiceStack", "ServiceClientBase", True, "Delete", "(System.Object)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "ServiceClientBase", True, "DownloadBytes", "(System.String,System.String,System.Object)", "", "Argument[2]", "remote", "manual"] - - ["ServiceStack", "ServiceClientBase", True, "DownloadBytesAsync", "(System.String,System.String,System.Object)", "", "Argument[2]", "remote", "manual"] - - ["ServiceStack", "ServiceClientBase", True, "Get", "(System.Object)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "ServiceClientBase", True, "Head", "(ServiceStack.IReturn)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "ServiceClientBase", True, "Head", "(System.Object)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "ServiceClientBase", True, "Patch", "(System.Object)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "ServiceClientBase", True, "Post", "(System.Object)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "ServiceClientBase", True, "Publish<>", "(ServiceStack.Messaging.IMessage)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "ServiceClientBase", True, "Publish<>", "(T)", "", "Argument[0]", "remote", "manual"] - - ["ServiceStack", "ServiceClientBase", True, "Put", "(System.Object)", "", "Argument[0]", "remote", "manual"] + - ["ServiceStack", "IOneWayClient", True, "SendAllOneWay", "(System.Collections.Generic.IEnumerable)", "", "Argument[1].Element", "file-content-store", "manual"] + - ["ServiceStack", "IOneWayClient", True, "SendOneWay", "(System.Object)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IOneWayClient", True, "SendOneWay", "(System.String,System.Object)", "", "Argument[1]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClient", True, "Patch<>", "(System.String,System.Object)", "", "Argument[1]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClient", True, "Post<>", "(System.String,System.Object)", "", "Argument[1]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClient", True, "Put<>", "(System.String,System.Object)", "", "Argument[1]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClient", True, "Send<>", "(System.String,System.String,System.Object)", "", "Argument[2]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "CustomMethodAsync", "(System.String,ServiceStack.IReturnVoid,System.Threading.CancellationToken)", "", "Argument[1]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "CustomMethodAsync<>", "(System.String,ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[1]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "CustomMethodAsync<>", "(System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[1]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "DeleteAsync", "(ServiceStack.IReturnVoid,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "DeleteAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "DeleteAsync<>", "(System.Object,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "GetAsync", "(ServiceStack.IReturnVoid,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "GetAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "GetAsync<>", "(System.Object,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "PatchAsync", "(ServiceStack.IReturnVoid,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "PatchAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "PatchAsync<>", "(System.Object,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "PostAsync", "(ServiceStack.IReturnVoid,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "PostAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "PostAsync<>", "(System.Object,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "PutAsync", "(ServiceStack.IReturnVoid,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "PutAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientAsync", True, "PutAsync<>", "(System.Object,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "CustomMethod", "(System.String,ServiceStack.IReturnVoid)", "", "Argument[1]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "CustomMethod<>", "(System.String,ServiceStack.IReturn)", "", "Argument[1]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "CustomMethod<>", "(System.String,System.Object)", "", "Argument[1]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "Delete", "(ServiceStack.IReturnVoid)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "Delete<>", "(ServiceStack.IReturn)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "Delete<>", "(System.Object)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "Get", "(ServiceStack.IReturnVoid)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "Get<>", "(ServiceStack.IReturn)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "Get<>", "(System.Object)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "Patch", "(ServiceStack.IReturnVoid)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "Patch<>", "(ServiceStack.IReturn)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "Patch<>", "(System.Object)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "Post", "(ServiceStack.IReturnVoid)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "Post<>", "(ServiceStack.IReturn)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "Post<>", "(System.Object)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "Put", "(ServiceStack.IReturnVoid)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "Put<>", "(ServiceStack.IReturn)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestClientSync", True, "Put<>", "(System.Object)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestGateway", True, "Delete<>", "(ServiceStack.IReturn)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestGateway", True, "Get<>", "(ServiceStack.IReturn)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestGateway", True, "Post<>", "(ServiceStack.IReturn)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestGateway", True, "Put<>", "(ServiceStack.IReturn)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestGateway", True, "Send<>", "(ServiceStack.IReturn)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestGatewayAsync", True, "DeleteAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestGatewayAsync", True, "GetAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestGatewayAsync", True, "PostAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestGatewayAsync", True, "PutAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IRestGatewayAsync", True, "SendAsync<>", "(ServiceStack.IReturn,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IServiceGateway", True, "Publish", "(System.Object)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IServiceGateway", True, "PublishAll", "(System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "file-content-store", "manual"] + - ["ServiceStack", "IServiceGateway", True, "Send<>", "(System.Object)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IServiceGateway", True, "SendAll<>", "(System.Collections.Generic.IEnumerable)", "", "Argument[0].Element", "file-content-store", "manual"] + - ["ServiceStack", "IServiceGatewayAsync", True, "PublishAllAsync", "(System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[0].Element", "file-content-store", "manual"] + - ["ServiceStack", "IServiceGatewayAsync", True, "PublishAsync", "(System.Object,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "IServiceGatewayAsync", True, "SendAllAsync<>", "(System.Collections.Generic.IEnumerable,System.Threading.CancellationToken)", "", "Argument[0].Element", "file-content-store", "manual"] + - ["ServiceStack", "IServiceGatewayAsync", True, "SendAsync<>", "(System.Object,System.Threading.CancellationToken)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "ServiceClientBase", True, "CustomMethod", "(System.String,System.String,System.Object)", "", "Argument[2]", "file-content-store", "manual"] + - ["ServiceStack", "ServiceClientBase", True, "CustomMethod<>", "(System.String,System.String,System.Object)", "", "Argument[2]", "file-content-store", "manual"] + - ["ServiceStack", "ServiceClientBase", True, "CustomMethodAsync<>", "(System.String,System.String,System.Object,System.Threading.CancellationToken)", "", "Argument[2]", "file-content-store", "manual"] + - ["ServiceStack", "ServiceClientBase", True, "Delete", "(System.Object)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "ServiceClientBase", True, "DownloadBytes", "(System.String,System.String,System.Object)", "", "Argument[2]", "file-content-store", "manual"] + - ["ServiceStack", "ServiceClientBase", True, "DownloadBytesAsync", "(System.String,System.String,System.Object)", "", "Argument[2]", "file-content-store", "manual"] + - ["ServiceStack", "ServiceClientBase", True, "Get", "(System.Object)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "ServiceClientBase", True, "Head", "(ServiceStack.IReturn)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "ServiceClientBase", True, "Head", "(System.Object)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "ServiceClientBase", True, "Patch", "(System.Object)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "ServiceClientBase", True, "Post", "(System.Object)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "ServiceClientBase", True, "Publish<>", "(ServiceStack.Messaging.IMessage)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "ServiceClientBase", True, "Publish<>", "(T)", "", "Argument[0]", "file-content-store", "manual"] + - ["ServiceStack", "ServiceClientBase", True, "Put", "(System.Object)", "", "Argument[0]", "file-content-store", "manual"] - addsTo: pack: codeql/csharp-all extensible: summaryModel diff --git a/csharp/ql/lib/ext/System.Data.Entity.model.yml b/csharp/ql/lib/ext/System.Data.Entity.model.yml index 36eccd9b38d..4af662ee4c4 100644 --- a/csharp/ql/lib/ext/System.Data.Entity.model.yml +++ b/csharp/ql/lib/ext/System.Data.Entity.model.yml @@ -1,14 +1,22 @@ extensions: + - addsTo: + pack: codeql/csharp-all + extensible: summaryModel + data: + - ["System.Data.Entity", "DbSet<>", False, "Add", "(TEntity)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] + - ["System.Data.Entity", "DbSet<>", False, "AddRange", "(System.Collections.Generic.IEnumerable)", "", "Argument[0].WithElement", "Argument[this]", "value", "manual"] + - ["System.Data.Entity", "DbSet<>", False, "Attach", "(TEntity)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] + - addsTo: pack: codeql/csharp-all extensible: sinkModel data: - - ["System.Data.Entity", "Database", False, "ExecuteSqlCommand", "(System.Data.Entity.TransactionalBehavior,System.String,System.Object[])", "", "Argument[1]", "sql", "manual"] - - ["System.Data.Entity", "Database", False, "ExecuteSqlCommand", "(System.String,System.Object[])", "", "Argument[0]", "sql", "manual"] - - ["System.Data.Entity", "Database", False, "ExecuteSqlCommandAsync", "(System.Data.Entity.TransactionalBehavior,System.String,System.Object[])", "", "Argument[1]", "sql", "manual"] - - ["System.Data.Entity", "Database", False, "ExecuteSqlCommandAsync", "(System.Data.Entity.TransactionalBehavior,System.String,System.Threading.CancellationToken,System.Object[])", "", "Argument[1]", "sql", "manual"] - - ["System.Data.Entity", "Database", False, "ExecuteSqlCommandAsync", "(System.String,System.Object[])", "", "Argument[0]", "sql", "manual"] - - ["System.Data.Entity", "Database", False, "ExecuteSqlCommandAsync", "(System.String,System.Threading.CancellationToken,System.Object[])", "", "Argument[0]", "sql", "manual"] - - ["System.Data.Entity", "Database", False, "SqlQuery", "(System.Type,System.String,System.Object[])", "", "Argument[1]", "sql", "manual"] - - ["System.Data.Entity", "Database", False, "SqlQuery<>", "(System.String,System.Object[])", "", "Argument[0]", "sql", "manual"] - - ["System.Data.Entity", "DbSet", False, "SqlQuery", "(System.String,System.Object[])", "", "Argument[0]", "sql", "manual"] + - ["System.Data.Entity", "Database", False, "ExecuteSqlCommand", "(System.Data.Entity.TransactionalBehavior,System.String,System.Object[])", "", "Argument[1]", "sql-injection", "manual"] + - ["System.Data.Entity", "Database", False, "ExecuteSqlCommand", "(System.String,System.Object[])", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.Entity", "Database", False, "ExecuteSqlCommandAsync", "(System.Data.Entity.TransactionalBehavior,System.String,System.Object[])", "", "Argument[1]", "sql-injection", "manual"] + - ["System.Data.Entity", "Database", False, "ExecuteSqlCommandAsync", "(System.Data.Entity.TransactionalBehavior,System.String,System.Threading.CancellationToken,System.Object[])", "", "Argument[1]", "sql-injection", "manual"] + - ["System.Data.Entity", "Database", False, "ExecuteSqlCommandAsync", "(System.String,System.Object[])", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.Entity", "Database", False, "ExecuteSqlCommandAsync", "(System.String,System.Threading.CancellationToken,System.Object[])", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.Entity", "Database", False, "SqlQuery", "(System.Type,System.String,System.Object[])", "", "Argument[1]", "sql-injection", "manual"] + - ["System.Data.Entity", "Database", False, "SqlQuery<>", "(System.String,System.Object[])", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.Entity", "DbSet", False, "SqlQuery", "(System.String,System.Object[])", "", "Argument[0]", "sql-injection", "manual"] diff --git a/csharp/ql/lib/ext/System.Data.EntityClient.model.yml b/csharp/ql/lib/ext/System.Data.EntityClient.model.yml index 16a24580647..39f3e35094c 100644 --- a/csharp/ql/lib/ext/System.Data.EntityClient.model.yml +++ b/csharp/ql/lib/ext/System.Data.EntityClient.model.yml @@ -3,6 +3,6 @@ extensions: pack: codeql/csharp-all extensible: sinkModel data: - - ["System.Data.EntityClient", "EntityCommand", False, "EntityCommand", "(System.String)", "", "Argument[0]", "sql", "manual"] - - ["System.Data.EntityClient", "EntityCommand", False, "EntityCommand", "(System.String,System.Data.EntityClient.EntityConnection)", "", "Argument[0]", "sql", "manual"] - - ["System.Data.EntityClient", "EntityCommand", False, "EntityCommand", "(System.String,System.Data.EntityClient.EntityConnection,System.Data.EntityClient.EntityTransaction)", "", "Argument[0]", "sql", "manual"] + - ["System.Data.EntityClient", "EntityCommand", False, "EntityCommand", "(System.String)", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.EntityClient", "EntityCommand", False, "EntityCommand", "(System.String,System.Data.EntityClient.EntityConnection)", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.EntityClient", "EntityCommand", False, "EntityCommand", "(System.String,System.Data.EntityClient.EntityConnection,System.Data.EntityClient.EntityTransaction)", "", "Argument[0]", "sql-injection", "manual"] diff --git a/csharp/ql/lib/ext/System.Data.Odbc.model.yml b/csharp/ql/lib/ext/System.Data.Odbc.model.yml index d1f6a24d5fc..0648bb0bbd0 100644 --- a/csharp/ql/lib/ext/System.Data.Odbc.model.yml +++ b/csharp/ql/lib/ext/System.Data.Odbc.model.yml @@ -3,6 +3,6 @@ extensions: pack: codeql/csharp-all extensible: sinkModel data: - - ["System.Data.Odbc", "OdbcCommand", False, "OdbcCommand", "(System.String)", "", "Argument[0]", "sql", "manual"] - - ["System.Data.Odbc", "OdbcCommand", False, "OdbcCommand", "(System.String,System.Data.Odbc.OdbcConnection)", "", "Argument[0]", "sql", "manual"] - - ["System.Data.Odbc", "OdbcCommand", False, "OdbcCommand", "(System.String,System.Data.Odbc.OdbcConnection,System.Data.Odbc.OdbcTransaction)", "", "Argument[0]", "sql", "manual"] + - ["System.Data.Odbc", "OdbcCommand", False, "OdbcCommand", "(System.String)", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.Odbc", "OdbcCommand", False, "OdbcCommand", "(System.String,System.Data.Odbc.OdbcConnection)", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.Odbc", "OdbcCommand", False, "OdbcCommand", "(System.String,System.Data.Odbc.OdbcConnection,System.Data.Odbc.OdbcTransaction)", "", "Argument[0]", "sql-injection", "manual"] diff --git a/csharp/ql/lib/ext/System.Data.OleDb.model.yml b/csharp/ql/lib/ext/System.Data.OleDb.model.yml index ebe3cc8b157..41e686537b8 100644 --- a/csharp/ql/lib/ext/System.Data.OleDb.model.yml +++ b/csharp/ql/lib/ext/System.Data.OleDb.model.yml @@ -3,6 +3,6 @@ extensions: pack: codeql/csharp-all extensible: sinkModel data: - - ["System.Data.OleDb", "OleDbCommand", False, "OleDbCommand", "(System.String)", "", "Argument[0]", "sql", "manual"] - - ["System.Data.OleDb", "OleDbCommand", False, "OleDbCommand", "(System.String,System.Data.OleDb.OleDbConnection)", "", "Argument[0]", "sql", "manual"] - - ["System.Data.OleDb", "OleDbCommand", False, "OleDbCommand", "(System.String,System.Data.OleDb.OleDbConnection,System.Data.OleDb.OleDbTransaction)", "", "Argument[0]", "sql", "manual"] + - ["System.Data.OleDb", "OleDbCommand", False, "OleDbCommand", "(System.String)", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.OleDb", "OleDbCommand", False, "OleDbCommand", "(System.String,System.Data.OleDb.OleDbConnection)", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.OleDb", "OleDbCommand", False, "OleDbCommand", "(System.String,System.Data.OleDb.OleDbConnection,System.Data.OleDb.OleDbTransaction)", "", "Argument[0]", "sql-injection", "manual"] diff --git a/csharp/ql/lib/ext/System.Data.SQLite.model.yml b/csharp/ql/lib/ext/System.Data.SQLite.model.yml index d6d1d70e608..e1cdb6a1a84 100644 --- a/csharp/ql/lib/ext/System.Data.SQLite.model.yml +++ b/csharp/ql/lib/ext/System.Data.SQLite.model.yml @@ -3,13 +3,13 @@ extensions: pack: codeql/csharp-all extensible: sinkModel data: - - ["System.Data.SQLite", "SQLiteCommand", False, "SQLiteCommand", "(System.String)", "", "Argument[0]", "sql", "manual"] - - ["System.Data.SQLite", "SQLiteCommand", False, "SQLiteCommand", "(System.String,System.Data.SQLite.SQLiteConnection)", "", "Argument[0]", "sql", "manual"] - - ["System.Data.SQLite", "SQLiteCommand", False, "SQLiteCommand", "(System.String,System.Data.SQLite.SQLiteConnection,System.Data.SQLite.SQLiteTransaction)", "", "Argument[0]", "sql", "manual"] - - ["System.Data.SQLite", "SQLiteDataAdapter", False, "SQLiteDataAdapter", "(System.Data.SQLite.SQLiteCommand)", "", "Argument[0]", "sql", "manual"] - - ["System.Data.SQLite", "SQLiteDataAdapter", False, "SQLiteDataAdapter", "(System.String,System.Data.SQLite.SQLiteConnection)", "", "Argument[0]", "sql", "manual"] - - ["System.Data.SQLite", "SQLiteDataAdapter", False, "SQLiteDataAdapter", "(System.String,System.String)", "", "Argument[0]", "sql", "manual"] - - ["System.Data.SQLite", "SQLiteDataAdapter", False, "SQLiteDataAdapter", "(System.String,System.String,System.Boolean)", "", "Argument[0]", "sql", "manual"] + - ["System.Data.SQLite", "SQLiteCommand", False, "SQLiteCommand", "(System.String)", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.SQLite", "SQLiteCommand", False, "SQLiteCommand", "(System.String,System.Data.SQLite.SQLiteConnection)", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.SQLite", "SQLiteCommand", False, "SQLiteCommand", "(System.String,System.Data.SQLite.SQLiteConnection,System.Data.SQLite.SQLiteTransaction)", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.SQLite", "SQLiteDataAdapter", False, "SQLiteDataAdapter", "(System.Data.SQLite.SQLiteCommand)", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.SQLite", "SQLiteDataAdapter", False, "SQLiteDataAdapter", "(System.String,System.Data.SQLite.SQLiteConnection)", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.SQLite", "SQLiteDataAdapter", False, "SQLiteDataAdapter", "(System.String,System.String)", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.SQLite", "SQLiteDataAdapter", False, "SQLiteDataAdapter", "(System.String,System.String,System.Boolean)", "", "Argument[0]", "sql-injection", "manual"] - addsTo: pack: codeql/csharp-all extensible: summaryModel diff --git a/csharp/ql/lib/ext/System.Data.SqlClient.model.yml b/csharp/ql/lib/ext/System.Data.SqlClient.model.yml index 2040e0f9798..211fe1faa84 100644 --- a/csharp/ql/lib/ext/System.Data.SqlClient.model.yml +++ b/csharp/ql/lib/ext/System.Data.SqlClient.model.yml @@ -3,12 +3,12 @@ extensions: pack: codeql/csharp-all extensible: sinkModel data: - - ["System.Data.SqlClient", "SqlCommand", False, "SqlCommand", "(System.String)", "", "Argument[0]", "sql", "manual"] - - ["System.Data.SqlClient", "SqlCommand", False, "SqlCommand", "(System.String,System.Data.SqlClient.SqlConnection)", "", "Argument[0]", "sql", "manual"] - - ["System.Data.SqlClient", "SqlCommand", False, "SqlCommand", "(System.String,System.Data.SqlClient.SqlConnection,System.Data.SqlClient.SqlTransaction)", "", "Argument[0]", "sql", "manual"] - - ["System.Data.SqlClient", "SqlDataAdapter", False, "SqlDataAdapter", "(System.Data.SqlClient.SqlCommand)", "", "Argument[0]", "sql", "manual"] - - ["System.Data.SqlClient", "SqlDataAdapter", False, "SqlDataAdapter", "(System.String,System.Data.SqlClient.SqlConnection)", "", "Argument[0]", "sql", "manual"] - - ["System.Data.SqlClient", "SqlDataAdapter", False, "SqlDataAdapter", "(System.String,System.String)", "", "Argument[0]", "sql", "manual"] + - ["System.Data.SqlClient", "SqlCommand", False, "SqlCommand", "(System.String)", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.SqlClient", "SqlCommand", False, "SqlCommand", "(System.String,System.Data.SqlClient.SqlConnection)", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.SqlClient", "SqlCommand", False, "SqlCommand", "(System.String,System.Data.SqlClient.SqlConnection,System.Data.SqlClient.SqlTransaction)", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.SqlClient", "SqlDataAdapter", False, "SqlDataAdapter", "(System.Data.SqlClient.SqlCommand)", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.SqlClient", "SqlDataAdapter", False, "SqlDataAdapter", "(System.String,System.Data.SqlClient.SqlConnection)", "", "Argument[0]", "sql-injection", "manual"] + - ["System.Data.SqlClient", "SqlDataAdapter", False, "SqlDataAdapter", "(System.String,System.String)", "", "Argument[0]", "sql-injection", "manual"] - addsTo: pack: codeql/csharp-all extensible: summaryModel diff --git a/csharp/ql/lib/ext/System.Net.Http.model.yml b/csharp/ql/lib/ext/System.Net.Http.model.yml index 0eafc30988a..4b5f4d193e7 100644 --- a/csharp/ql/lib/ext/System.Net.Http.model.yml +++ b/csharp/ql/lib/ext/System.Net.Http.model.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/csharp-all extensible: sinkModel data: - - ["System.Net.Http", "StringContent", False, "StringContent", "", "", "Argument[0]", "xss", "manual"] + - ["System.Net.Http", "StringContent", False, "StringContent", "", "", "Argument[0]", "js-injection", "manual"] - addsTo: pack: codeql/csharp-all extensible: summaryModel diff --git a/csharp/ql/lib/ext/System.Web.model.yml b/csharp/ql/lib/ext/System.Web.model.yml index 5cf065ec6dd..a2a7470ef8e 100644 --- a/csharp/ql/lib/ext/System.Web.model.yml +++ b/csharp/ql/lib/ext/System.Web.model.yml @@ -3,10 +3,10 @@ extensions: pack: codeql/csharp-all extensible: sinkModel data: - - ["System.Web", "HttpResponse", False, "BinaryWrite", "", "", "Argument[0]", "html", "manual"] - - ["System.Web", "HttpResponse", False, "TransmitFile", "", "", "Argument[0]", "html", "manual"] - - ["System.Web", "HttpResponse", False, "Write", "", "", "Argument[0]", "html", "manual"] - - ["System.Web", "HttpResponse", False, "WriteFile", "", "", "Argument[0]", "html", "manual"] + - ["System.Web", "HttpResponse", False, "BinaryWrite", "", "", "Argument[0]", "html-injection", "manual"] + - ["System.Web", "HttpResponse", False, "TransmitFile", "", "", "Argument[0]", "html-injection", "manual"] + - ["System.Web", "HttpResponse", False, "Write", "", "", "Argument[0]", "html-injection", "manual"] + - ["System.Web", "HttpResponse", False, "WriteFile", "", "", "Argument[0]", "html-injection", "manual"] - addsTo: pack: codeql/csharp-all extensible: summaryModel diff --git a/csharp/ql/lib/ext/generated/dotnet_runtime.model.yml b/csharp/ql/lib/ext/generated/dotnet_runtime.model.yml index 6ec7a3cb93a..a5dc7699795 100644 --- a/csharp/ql/lib/ext/generated/dotnet_runtime.model.yml +++ b/csharp/ql/lib/ext/generated/dotnet_runtime.model.yml @@ -7,10 +7,10 @@ extensions: pack: codeql/csharp-all extensible: sinkModel data: - - ["System.Data.Odbc", "OdbcDataAdapter", false, "OdbcDataAdapter", "(System.String,System.Data.Odbc.OdbcConnection)", "", "Argument[0]", "sql", "df-generated"] - - ["System.Data.Odbc", "OdbcDataAdapter", false, "OdbcDataAdapter", "(System.String,System.String)", "", "Argument[0]", "sql", "df-generated"] - - ["System.Net.Http", "StringContent", false, "StringContent", "(System.String)", "", "Argument[0]", "xss", "df-generated"] - - ["System.Net.Http", "StringContent", false, "StringContent", "(System.String,System.Text.Encoding)", "", "Argument[0]", "xss", "df-generated"] + - ["System.Data.Odbc", "OdbcDataAdapter", false, "OdbcDataAdapter", "(System.String,System.Data.Odbc.OdbcConnection)", "", "Argument[0]", "sql-injection", "df-generated"] + - ["System.Data.Odbc", "OdbcDataAdapter", false, "OdbcDataAdapter", "(System.String,System.String)", "", "Argument[0]", "sql-injection", "df-generated"] + - ["System.Net.Http", "StringContent", false, "StringContent", "(System.String)", "", "Argument[0]", "js-injection", "df-generated"] + - ["System.Net.Http", "StringContent", false, "StringContent", "(System.String,System.Text.Encoding)", "", "Argument[0]", "js-injection", "df-generated"] - ["System.Security.Cryptography", "AesCryptoServiceProvider", false, "CreateDecryptor", "(System.Byte[],System.Byte[])", "", "Argument[0]", "encryption-decryptor", "df-generated"] - ["System.Security.Cryptography", "AesCryptoServiceProvider", false, "CreateEncryptor", "(System.Byte[],System.Byte[])", "", "Argument[0]", "encryption-encryptor", "df-generated"] - ["System.Security.Cryptography", "AesCryptoServiceProvider", false, "set_Key", "(System.Byte[])", "", "Argument[0]", "encryption-keyprop", "df-generated"] @@ -34,7 +34,7 @@ extensions: - ["System.Security.Cryptography", "TripleDESCryptoServiceProvider", false, "CreateEncryptor", "(System.Byte[],System.Byte[])", "", "Argument[0]", "encryption-encryptor", "df-generated"] - ["System.Security.Cryptography", "TripleDESCryptoServiceProvider", false, "set_Key", "(System.Byte[])", "", "Argument[0]", "encryption-keyprop", "df-generated"] - + - addsTo: @@ -51946,6 +51946,3 @@ extensions: - ["System", "WeakReference<>", "TryGetTarget", "(T)", "summary", "df-generated"] - ["System", "WeakReference<>", "WeakReference", "(T)", "summary", "df-generated"] - ["System", "WeakReference<>", "WeakReference", "(T,System.Boolean)", "summary", "df-generated"] - - - \ No newline at end of file diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index 1f57626840b..46a19828a81 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -211,7 +211,8 @@ module ModelValidation { ) or exists(string kind | sinkModel(_, _, _, _, _, _, _, kind, _) | - not kind = ["code", "sql", "xss", "remote", "html"] and + not kind = + ["code-injection", "sql-injection", "js-injection", "html-injection", "file-content-store"] and not kind.matches("encryption-%") and result = "Invalid kind \"" + kind + "\" in sink model." ) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll index 5f781a0407a..e0dfc0d542d 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll @@ -88,31 +88,6 @@ module EntityFramework { EFSummarizedCallable() { any() } } - private class DbSetAddOrUpdateRequiredSummaryComponentStack extends RequiredSummaryComponentStack { - override predicate required(SummaryComponent head, SummaryComponentStack tail) { - head = SummaryComponent::element() and - tail = SummaryComponentStack::argument([-1, 0]) - } - } - - private class DbSetAddOrUpdate extends EFSummarizedCallable { - private boolean range; - - DbSetAddOrUpdate() { this = any(DbSet c).getAnAddOrUpdateMethod(range) } - - override predicate propagatesFlow( - SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue - ) { - ( - if range = true - then input = SummaryComponentStack::elementOf(SummaryComponentStack::argument(0)) - else input = SummaryComponentStack::argument(0) - ) and - output = SummaryComponentStack::elementOf(SummaryComponentStack::qualifier()) and - preservesValue = true - } - } - /** The class `Microsoft.EntityFrameworkCore.DbQuery<>` or `System.Data.Entity.DbQuery<>`. */ class DbQuery extends EFClass, UnboundGenericClass { DbQuery() { this.hasName("DbQuery<>") } 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 76a9a495637..cd035de9414 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll @@ -97,5 +97,5 @@ class RoslynCSharpScriptSink extends Sink { /** Code injection sinks defined through CSV models. */ private class ExternalCodeInjectionExprSink extends Sink { - ExternalCodeInjectionExprSink() { sinkNode(this, "code") } + ExternalCodeInjectionExprSink() { sinkNode(this, "code-injection") } } 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 3cac542cb36..61b2491753a 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/SqlInjectionQuery.qll @@ -78,7 +78,7 @@ class SqlInjectionExprSink extends Sink { /** SQL sinks defined through CSV models. */ private class ExternalSqlInjectionExprSink extends Sink { - ExternalSqlInjectionExprSink() { sinkNode(this, "sql") } + ExternalSqlInjectionExprSink() { sinkNode(this, "sql-injection") } } private class SimpleTypeSanitizer extends Sanitizer, SimpleTypeSanitizedExpr { } 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 0232d9462e2..65ac1687714 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSSinks.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSSinks.qll @@ -24,7 +24,7 @@ abstract class Sink extends DataFlow::ExprNode, RemoteFlowSink { } private class ExternalXssSink extends Sink { - ExternalXssSink() { sinkNode(this, "xss") } + ExternalXssSink() { sinkNode(this, "js-injection") } } private class HtmlSinkSink extends Sink instanceof HtmlSink { 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 d19b0006eb7..1baeff7641b 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 @@ -19,7 +19,7 @@ private import semmle.code.csharp.dataflow.ExternalFlow abstract class ExternalLocationSink extends DataFlow::ExprNode { } private class ExternalModelSink extends ExternalLocationSink { - ExternalModelSink() { sinkNode(this, "remote") } + ExternalModelSink() { sinkNode(this, "file-content-store") } } /** diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/Html.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/Html.qll index 8e83122e2bf..318e298ae1f 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/Html.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/Html.qll @@ -23,7 +23,7 @@ private import semmle.code.asp.AspNet abstract class HtmlSink extends DataFlow::ExprNode, RemoteFlowSink { } private class ExternalHtmlSink extends HtmlSink { - ExternalHtmlSink() { sinkNode(this, "html") } + ExternalHtmlSink() { sinkNode(this, "html-injection") } } /** diff --git a/csharp/ql/src/experimental/ir/implementation/raw/IR.qll b/csharp/ql/src/experimental/ir/implementation/raw/IR.qll index c96783fe6e8..79873d8366e 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/IR.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/IR.qll @@ -77,4 +77,16 @@ class IRPropertyProvider extends TIRPropertyProvider { * Gets the value of the property named `key` for the specified operand. */ string getOperandProperty(Operand operand, string key) { none() } + + /** + * Holds if the instruction `instr` should be included when printing + * the IR instructions. + */ + predicate shouldPrintInstruction(Instruction instr) { any() } + + /** + * Holds if the operand `operand` should be included when printing the an + * instruction's operand list. + */ + predicate shouldPrintOperand(Operand operand) { any() } } diff --git a/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll b/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll index 78008a6c69b..4de4279b54c 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll @@ -255,14 +255,28 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Holds if `i` is the `index`th instruction the block starting with `first`. */ - private Instruction getInstructionFromFirst(Instruction first, int index) = - shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) + /** Gets the index of `i` in its `IRBlock`. */ + private int getMemberIndex(Instruction i) { + startsBasicBlock(i) and + result = 0 + or + exists(Instruction iPrev | + adjacentInBlock(iPrev, i) and + result = getMemberIndex(iPrev) + 1 + ) + } + + private module BlockAdjacency = QlBuiltins::EquivalenceRelation; /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - result = getInstructionFromFirst(getFirstInstruction(block), index) + exists(Instruction first | block = MkIRBlock(first) | + first = result and index = 0 + or + index = getMemberIndex(result) and + BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) + ) } cached diff --git a/csharp/ql/src/experimental/ir/implementation/raw/PrintIR.qll b/csharp/ql/src/experimental/ir/implementation/raw/PrintIR.qll index 2ababa6199a..b9106a7bfc7 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/PrintIR.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/PrintIR.qll @@ -42,6 +42,14 @@ private predicate shouldPrintFunction(Language::Declaration decl) { exists(PrintIRConfiguration config | config.shouldPrintFunction(decl)) } +private predicate shouldPrintInstruction(Instruction i) { + exists(IRPropertyProvider provider | provider.shouldPrintInstruction(i)) +} + +private predicate shouldPrintOperand(Operand operand) { + exists(IRPropertyProvider provider | provider.shouldPrintOperand(operand)) +} + private string getAdditionalInstructionProperty(Instruction instr, string key) { exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key)) } @@ -84,7 +92,9 @@ private string getOperandPropertyString(Operand operand) { private newtype TPrintableIRNode = TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or - TPrintableInstruction(Instruction instr) { shouldPrintFunction(instr.getEnclosingFunction()) } + TPrintableInstruction(Instruction instr) { + shouldPrintInstruction(instr) and shouldPrintFunction(instr.getEnclosingFunction()) + } /** * A node to be emitted in the IR graph. @@ -252,7 +262,8 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio private string getOperandsString() { result = concat(Operand operand | - operand = instr.getAnOperand() + operand = instr.getAnOperand() and + shouldPrintOperand(operand) | operand.getDumpString() + getOperandPropertyString(operand), ", " order by diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IR.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IR.qll index c96783fe6e8..79873d8366e 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IR.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IR.qll @@ -77,4 +77,16 @@ class IRPropertyProvider extends TIRPropertyProvider { * Gets the value of the property named `key` for the specified operand. */ string getOperandProperty(Operand operand, string key) { none() } + + /** + * Holds if the instruction `instr` should be included when printing + * the IR instructions. + */ + predicate shouldPrintInstruction(Instruction instr) { any() } + + /** + * Holds if the operand `operand` should be included when printing the an + * instruction's operand list. + */ + predicate shouldPrintOperand(Operand operand) { any() } } diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll index 78008a6c69b..4de4279b54c 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll @@ -255,14 +255,28 @@ private module Cached { cached newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) } - /** Holds if `i` is the `index`th instruction the block starting with `first`. */ - private Instruction getInstructionFromFirst(Instruction first, int index) = - shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index) + /** Gets the index of `i` in its `IRBlock`. */ + private int getMemberIndex(Instruction i) { + startsBasicBlock(i) and + result = 0 + or + exists(Instruction iPrev | + adjacentInBlock(iPrev, i) and + result = getMemberIndex(iPrev) + 1 + ) + } + + private module BlockAdjacency = QlBuiltins::EquivalenceRelation; /** Holds if `i` is the `index`th instruction in `block`. */ cached Instruction getInstruction(TIRBlock block, int index) { - result = getInstructionFromFirst(getFirstInstruction(block), index) + exists(Instruction first | block = MkIRBlock(first) | + first = result and index = 0 + or + index = getMemberIndex(result) and + BlockAdjacency::getEquivalenceClass(first) = BlockAdjacency::getEquivalenceClass(result) + ) } cached diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/PrintIR.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/PrintIR.qll index 2ababa6199a..b9106a7bfc7 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/PrintIR.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/PrintIR.qll @@ -42,6 +42,14 @@ private predicate shouldPrintFunction(Language::Declaration decl) { exists(PrintIRConfiguration config | config.shouldPrintFunction(decl)) } +private predicate shouldPrintInstruction(Instruction i) { + exists(IRPropertyProvider provider | provider.shouldPrintInstruction(i)) +} + +private predicate shouldPrintOperand(Operand operand) { + exists(IRPropertyProvider provider | provider.shouldPrintOperand(operand)) +} + private string getAdditionalInstructionProperty(Instruction instr, string key) { exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key)) } @@ -84,7 +92,9 @@ private string getOperandPropertyString(Operand operand) { private newtype TPrintableIRNode = TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or - TPrintableInstruction(Instruction instr) { shouldPrintFunction(instr.getEnclosingFunction()) } + TPrintableInstruction(Instruction instr) { + shouldPrintInstruction(instr) and shouldPrintFunction(instr.getEnclosingFunction()) + } /** * A node to be emitted in the IR graph. @@ -252,7 +262,8 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio private string getOperandsString() { result = concat(Operand operand | - operand = instr.getAnOperand() + operand = instr.getAnOperand() and + shouldPrintOperand(operand) | operand.getDumpString() + getOperandPropertyString(operand), ", " order by diff --git a/csharp/ql/test/library-tests/dataflow/external-models/sinks.expected b/csharp/ql/test/library-tests/dataflow/external-models/sinks.expected index c9b9406a10a..3a4489dcb91 100644 --- a/csharp/ql/test/library-tests/dataflow/external-models/sinks.expected +++ b/csharp/ql/test/library-tests/dataflow/external-models/sinks.expected @@ -1,8 +1,8 @@ invalidModelRow #select -| Sinks.cs:8:19:8:22 | access to local variable arg1 | code | -| Sinks.cs:11:13:11:41 | this access | remote | -| Sinks.cs:11:30:11:40 | access to local variable argToTagged | remote | -| Sinks.cs:14:27:14:36 | access to local variable fieldWrite | sql | -| Sinks.cs:20:20:20:22 | access to local variable res | xss | -| Sinks.cs:27:20:27:25 | access to local variable resTag | html | +| Sinks.cs:8:19:8:22 | access to local variable arg1 | code-injection | +| Sinks.cs:11:13:11:41 | this access | file-content-store | +| Sinks.cs:11:30:11:40 | access to local variable argToTagged | file-content-store | +| Sinks.cs:14:27:14:36 | access to local variable fieldWrite | sql-injection | +| Sinks.cs:20:20:20:22 | access to local variable res | js-injection | +| Sinks.cs:27:20:27:25 | access to local variable resTag | html-injection | diff --git a/csharp/ql/test/library-tests/dataflow/external-models/sinks.ext.yml b/csharp/ql/test/library-tests/dataflow/external-models/sinks.ext.yml index 3198057f42c..c44c1b4fd36 100644 --- a/csharp/ql/test/library-tests/dataflow/external-models/sinks.ext.yml +++ b/csharp/ql/test/library-tests/dataflow/external-models/sinks.ext.yml @@ -4,8 +4,8 @@ extensions: extensible: sinkModel data: # "namespace", "type", "overrides", "name", "signature", "ext", "spec", "kind", "provenance" - - ["My.Qltest", "B", false, "Sink1", "(System.Object)", "", "Argument[0]", "code", "manual"] - - ["My.Qltest", "B", false, "SinkMethod", "()", "", "ReturnValue", "xss", "manual"] - - ["My.Qltest", "SinkAttribute", false, "", "", "Attribute", "ReturnValue", "html", "manual"] - - ["My.Qltest", "SinkAttribute", false, "", "", "Attribute", "Argument", "remote", "manual"] - - ["My.Qltest", "SinkAttribute", false, "", "", "Attribute", "", "sql", "manual"] + - ["My.Qltest", "B", false, "Sink1", "(System.Object)", "", "Argument[0]", "code-injection", "manual"] + - ["My.Qltest", "B", false, "SinkMethod", "()", "", "ReturnValue", "js-injection", "manual"] + - ["My.Qltest", "SinkAttribute", false, "", "", "Attribute", "ReturnValue", "html-injection", "manual"] + - ["My.Qltest", "SinkAttribute", false, "", "", "Attribute", "Argument", "file-content-store", "manual"] + - ["My.Qltest", "SinkAttribute", false, "", "", "Attribute", "", "sql-injection", "manual"] diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected index 18a0db6fe43..46defadf531 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected @@ -209,6 +209,20 @@ summary | Microsoft.CSharp.RuntimeBinder;Binder;false;SetMember;(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.String,System.Type,System.Collections.Generic.IEnumerable);;Argument[3].Element;ReturnValue;taint;df-generated | | Microsoft.CSharp.RuntimeBinder;Binder;false;UnaryOperation;(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Linq.Expressions.ExpressionType,System.Type,System.Collections.Generic.IEnumerable);;Argument[2];ReturnValue;taint;df-generated | | Microsoft.CSharp.RuntimeBinder;Binder;false;UnaryOperation;(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Linq.Expressions.ExpressionType,System.Type,System.Collections.Generic.IEnumerable);;Argument[3].Element;ReturnValue;taint;df-generated | +| Microsoft.EntityFrameworkCore;DbSet<>;false;Add;(TEntity);;Argument[0];Argument[this].Element;value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;AddAsync;(TEntity,System.Threading.CancellationToken);;Argument[0];Argument[this].Element;value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;AddRange;(System.Collections.Generic.IEnumerable);;Argument[0].WithElement;Argument[this];value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;AddRange;(TEntity[]);;Argument[0].WithElement;Argument[this];value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;AddRangeAsync;(System.Collections.Generic.IEnumerable,System.Threading.CancellationToken);;Argument[0].WithElement;Argument[this];value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;AddRangeAsync;(TEntity[]);;Argument[0].WithElement;Argument[this];value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;Attach;(TEntity);;Argument[0];Argument[this].Element;value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;AttachRange;(System.Collections.Generic.IEnumerable);;Argument[0].WithElement;Argument[this];value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;AttachRange;(TEntity[]);;Argument[0].WithElement;Argument[this];value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current];value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;Update;(TEntity);;Argument[0];Argument[this].Element;value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;UpdateRange;(System.Collections.Generic.IEnumerable);;Argument[0].WithElement;Argument[this];value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;UpdateRange;(TEntity[]);;Argument[0].WithElement;Argument[this];value;manual | | Microsoft.Extensions.Caching.Distributed;DistributedCacheEntryExtensions;false;SetAbsoluteExpiration;(Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions,System.DateTimeOffset);;Argument[0];ReturnValue;taint;df-generated | | Microsoft.Extensions.Caching.Distributed;DistributedCacheEntryExtensions;false;SetAbsoluteExpiration;(Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions,System.DateTimeOffset);;Argument[1];Argument[0];taint;df-generated | | Microsoft.Extensions.Caching.Distributed;DistributedCacheEntryExtensions;false;SetAbsoluteExpiration;(Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions,System.DateTimeOffset);;Argument[1];ReturnValue;taint;df-generated | @@ -2671,6 +2685,13 @@ summary | System.Data.Common;RowUpdatingEventArgs;false;set_BaseCommand;(System.Data.IDbCommand);;Argument[0];Argument[this];taint;df-generated | | System.Data.Common;RowUpdatingEventArgs;false;set_Command;(System.Data.IDbCommand);;Argument[0];Argument[this];taint;df-generated | | System.Data.Common;RowUpdatingEventArgs;false;set_Errors;(System.Exception);;Argument[0];Argument[this];taint;df-generated | +| System.Data.Entity.Infrastructure;DbRawSqlQuery<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current];value;manual | +| System.Data.Entity.Infrastructure;DbRawSqlQuery<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | +| System.Data.Entity;DbSet<>;false;Add;(TEntity);;Argument[0];Argument[this].Element;value;manual | +| System.Data.Entity;DbSet<>;false;AddRange;(System.Collections.Generic.IEnumerable);;Argument[0].WithElement;Argument[this];value;manual | +| System.Data.Entity;DbSet<>;false;Attach;(TEntity);;Argument[0];Argument[this].Element;value;manual | +| System.Data.Entity;DbSet<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current];value;manual | +| System.Data.Entity;DbSet<>;false;GetEnumerator;();;Argument[this].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Data.SqlTypes;SqlBinary;false;Add;(System.Data.SqlTypes.SqlBinary,System.Data.SqlTypes.SqlBinary);;Argument[0];ReturnValue;taint;df-generated | | System.Data.SqlTypes;SqlBinary;false;Add;(System.Data.SqlTypes.SqlBinary,System.Data.SqlTypes.SqlBinary);;Argument[1];ReturnValue;taint;df-generated | | System.Data.SqlTypes;SqlBinary;false;Concat;(System.Data.SqlTypes.SqlBinary,System.Data.SqlTypes.SqlBinary);;Argument[0];ReturnValue;taint;df-generated | diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected index 6f3c8e933d5..4ae26655169 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected @@ -18,6 +18,18 @@ summary | Microsoft.CSharp.RuntimeBinder;Binder;false;SetMember;(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.String,System.Type,System.Collections.Generic.IEnumerable);;Argument[3].Element;ReturnValue;taint;df-generated | | Microsoft.CSharp.RuntimeBinder;Binder;false;UnaryOperation;(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Linq.Expressions.ExpressionType,System.Type,System.Collections.Generic.IEnumerable);;Argument[2];ReturnValue;taint;df-generated | | Microsoft.CSharp.RuntimeBinder;Binder;false;UnaryOperation;(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Linq.Expressions.ExpressionType,System.Type,System.Collections.Generic.IEnumerable);;Argument[3].Element;ReturnValue;taint;df-generated | +| Microsoft.EntityFrameworkCore;DbSet<>;false;Add;(TEntity);;Argument[0];Argument[this].Element;value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;AddAsync;(TEntity,System.Threading.CancellationToken);;Argument[0];Argument[this].Element;value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;AddRange;(System.Collections.Generic.IEnumerable);;Argument[0].WithElement;Argument[this];value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;AddRange;(TEntity[]);;Argument[0].WithElement;Argument[this];value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;AddRangeAsync;(System.Collections.Generic.IEnumerable,System.Threading.CancellationToken);;Argument[0].WithElement;Argument[this];value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;AddRangeAsync;(TEntity[]);;Argument[0].WithElement;Argument[this];value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;Attach;(TEntity);;Argument[0];Argument[this].Element;value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;AttachRange;(System.Collections.Generic.IEnumerable);;Argument[0].WithElement;Argument[this];value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;AttachRange;(TEntity[]);;Argument[0].WithElement;Argument[this];value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;Update;(TEntity);;Argument[0];Argument[this].Element;value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;UpdateRange;(System.Collections.Generic.IEnumerable);;Argument[0].WithElement;Argument[this];value;manual | +| Microsoft.EntityFrameworkCore;DbSet<>;false;UpdateRange;(TEntity[]);;Argument[0].WithElement;Argument[this];value;manual | | Microsoft.Extensions.Caching.Distributed;DistributedCacheEntryExtensions;false;SetAbsoluteExpiration;(Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions,System.DateTimeOffset);;Argument[0];ReturnValue;taint;df-generated | | Microsoft.Extensions.Caching.Distributed;DistributedCacheEntryExtensions;false;SetAbsoluteExpiration;(Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions,System.DateTimeOffset);;Argument[1];Argument[0];taint;df-generated | | Microsoft.Extensions.Caching.Distributed;DistributedCacheEntryExtensions;false;SetAbsoluteExpiration;(Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions,System.DateTimeOffset);;Argument[1];ReturnValue;taint;df-generated | @@ -1858,6 +1870,9 @@ summary | System.Data.Common;RowUpdatingEventArgs;false;set_BaseCommand;(System.Data.IDbCommand);;Argument[0];Argument[this];taint;df-generated | | System.Data.Common;RowUpdatingEventArgs;false;set_Command;(System.Data.IDbCommand);;Argument[0];Argument[this];taint;df-generated | | System.Data.Common;RowUpdatingEventArgs;false;set_Errors;(System.Exception);;Argument[0];Argument[this];taint;df-generated | +| System.Data.Entity;DbSet<>;false;Add;(TEntity);;Argument[0];Argument[this].Element;value;manual | +| System.Data.Entity;DbSet<>;false;AddRange;(System.Collections.Generic.IEnumerable);;Argument[0].WithElement;Argument[this];value;manual | +| System.Data.Entity;DbSet<>;false;Attach;(TEntity);;Argument[0];Argument[this].Element;value;manual | | System.Data.SqlTypes;SqlBinary;false;Add;(System.Data.SqlTypes.SqlBinary,System.Data.SqlTypes.SqlBinary);;Argument[0];ReturnValue;taint;df-generated | | System.Data.SqlTypes;SqlBinary;false;Add;(System.Data.SqlTypes.SqlBinary,System.Data.SqlTypes.SqlBinary);;Argument[1];ReturnValue;taint;df-generated | | System.Data.SqlTypes;SqlBinary;false;Concat;(System.Data.SqlTypes.SqlBinary,System.Data.SqlTypes.SqlBinary);;Argument[0];ReturnValue;taint;df-generated | diff --git a/csharp/ql/test/library-tests/dataflow/library/options b/csharp/ql/test/library-tests/dataflow/library/options index c5ce92614ab..db937e0e642 100644 --- a/csharp/ql/test/library-tests/dataflow/library/options +++ b/csharp/ql/test/library-tests/dataflow/library/options @@ -2,3 +2,4 @@ semmle-extractor-options: /nostdlib /noconfig semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/Newtonsoft.Json/13.0.1/Newtonsoft.Json.csproj semmle-extractor-options: --load-sources-from-project:../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Web.cs +semmle-extractor-options: ${testdir}/../../../resources/stubs/EntityFramework.cs diff --git a/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected b/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected index 2d5a35839fb..4698be24b8c 100644 --- a/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected @@ -57,14 +57,6 @@ summary | Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Id];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Id];value;manual | | Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];ReturnValue[jump to get_PersonAddresses].Element.Property[EFCoreTests.PersonAddressMap.Person].Property[EFCoreTests.Person.Name];value;manual | | Microsoft.EntityFrameworkCore;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFCoreTests.MyContext.Persons].Element.Property[EFCoreTests.Person.Name];ReturnValue[jump to get_Persons].Element.Property[EFCoreTests.Person.Name];value;manual | -| Microsoft.EntityFrameworkCore;DbSet<>;false;Add;(T);;Argument[0];Argument[this].Element;value;manual | -| Microsoft.EntityFrameworkCore;DbSet<>;false;AddAsync;(T);;Argument[0];Argument[this].Element;value;manual | -| Microsoft.EntityFrameworkCore;DbSet<>;false;AddRange;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[this].Element;value;manual | -| Microsoft.EntityFrameworkCore;DbSet<>;false;AddRangeAsync;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[this].Element;value;manual | -| Microsoft.EntityFrameworkCore;DbSet<>;false;Attach;(T);;Argument[0];Argument[this].Element;value;manual | -| Microsoft.EntityFrameworkCore;DbSet<>;false;AttachRange;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[this].Element;value;manual | -| Microsoft.EntityFrameworkCore;DbSet<>;false;Update;(T);;Argument[0];Argument[this].Element;value;manual | -| Microsoft.EntityFrameworkCore;DbSet<>;false;UpdateRange;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[this].Element;value;manual | | System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];ReturnValue[jump to get_Addresses].Element.Property[EFTests.Address.Id];value;manual | | System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Address].Property[EFTests.Address.Id];value;manual | | System.Data.Entity;DbContext;false;SaveChanges;();;Argument[this].Property[EFTests.MyContext.Addresses].Element.Property[EFTests.Address.Id];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Addresses].Element.Property[EFTests.Address.Id];value;manual | @@ -123,20 +115,12 @@ summary | System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Id];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Id];value;manual | | System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];ReturnValue[jump to get_PersonAddresses].Element.Property[EFTests.PersonAddressMap.Person].Property[EFTests.Person.Name];value;manual | | System.Data.Entity;DbContext;false;SaveChangesAsync;();;Argument[this].Property[EFTests.MyContext.Persons].Element.Property[EFTests.Person.Name];ReturnValue[jump to get_Persons].Element.Property[EFTests.Person.Name];value;manual | -| System.Data.Entity;DbSet<>;false;Add;(T);;Argument[0];Argument[this].Element;value;manual | -| System.Data.Entity;DbSet<>;false;AddAsync;(T);;Argument[0];Argument[this].Element;value;manual | -| System.Data.Entity;DbSet<>;false;AddRange;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[this].Element;value;manual | -| System.Data.Entity;DbSet<>;false;AddRangeAsync;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[this].Element;value;manual | -| System.Data.Entity;DbSet<>;false;Attach;(T);;Argument[0];Argument[this].Element;value;manual | -| System.Data.Entity;DbSet<>;false;AttachRange;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[this].Element;value;manual | -| System.Data.Entity;DbSet<>;false;Update;(T);;Argument[0];Argument[this].Element;value;manual | -| System.Data.Entity;DbSet<>;false;UpdateRange;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[this].Element;value;manual | neutral sourceNode sinkNode -| EntityFrameworkCore.cs:72:36:72:40 | "sql" | sql | -| EntityFrameworkCore.cs:73:40:73:44 | "sql" | sql | -| EntityFrameworkCore.cs:74:40:74:44 | "sql" | sql | -| EntityFrameworkCore.cs:75:51:75:55 | "sql" | sql | -| EntityFrameworkCore.cs:76:51:76:55 | "sql" | sql | -| EntityFrameworkCore.cs:77:51:77:55 | "sql" | sql | +| EntityFrameworkCore.cs:72:36:72:40 | "sql" | sql-injection | +| EntityFrameworkCore.cs:73:40:73:44 | "sql" | sql-injection | +| EntityFrameworkCore.cs:74:40:74:44 | "sql" | sql-injection | +| EntityFrameworkCore.cs:75:51:75:55 | "sql" | sql-injection | +| EntityFrameworkCore.cs:76:51:76:55 | "sql" | sql-injection | +| EntityFrameworkCore.cs:77:51:77:55 | "sql" | sql-injection | diff --git a/csharp/ql/test/library-tests/frameworks/sql/Sql1.ql b/csharp/ql/test/library-tests/frameworks/sql/Sql1.ql index 9f25014662f..944d4180992 100644 --- a/csharp/ql/test/library-tests/frameworks/sql/Sql1.ql +++ b/csharp/ql/test/library-tests/frameworks/sql/Sql1.ql @@ -7,7 +7,7 @@ query predicate sqlExpressions(SqlExpr se, Expr e) { se.getSql() = e } query predicate sqlCsvSinks(Element p, Expr e) { p = e.getParent() and exists(Node n | - sinkNode(n, "sql") and + sinkNode(n, "sql-injection") and n.asExpr() = e ) } diff --git a/csharp/ql/test/library-tests/parameters/Parameters.cs b/csharp/ql/test/library-tests/parameters/Parameters.cs index b7cc3b001a9..ebe17322bad 100644 --- a/csharp/ql/test/library-tests/parameters/Parameters.cs +++ b/csharp/ql/test/library-tests/parameters/Parameters.cs @@ -1,3 +1,7 @@ +using System; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; + public class Parameters { public void M1(int a, object b, string c) => throw null; @@ -12,6 +16,16 @@ public class Parameters public void M9(T t = default) where T : struct => throw null; public void M10(T t = default) where T : class => throw null; + public void M11(int arg1 = 3) => throw null; + public void M12(DateTime arg2 = default) => throw null; + public void M13(DateTime? arg3 = null) => throw null; + public void M14([Optional, DateTimeConstant(14L)] DateTime arg4) => throw null; + public void M15([Optional, DateTimeConstant(10001L)] DateTime? arg5) => throw null; + public void M16([Optional, DefaultParameterValue(6L)] long arg6) => throw null; + public void M17([Optional, DefaultParameterValue(null)] object arg7) => throw null; + public void M18([Optional, DefaultParameterValue(3)] int? arg8) => throw null; + public void M19([Optional, DecimalConstant(1, 0, 0, 0, 103)] decimal arg9) => throw null; + public struct MyStruct { } public enum MyEnum { A = 1, B = 2 } } \ No newline at end of file diff --git a/csharp/ql/test/library-tests/parameters/Parameters.cs_ b/csharp/ql/test/library-tests/parameters/Parameters.cs_ index 062c4b98b18..8fce6f198c3 100644 --- a/csharp/ql/test/library-tests/parameters/Parameters.cs_ +++ b/csharp/ql/test/library-tests/parameters/Parameters.cs_ @@ -1,3 +1,7 @@ +using System; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; + public class ParametersDll { public void M1(int a, object b, string c) => throw null; @@ -12,6 +16,16 @@ public class ParametersDll public void M9(T t = default) where T : struct => throw null; public void M10(T t = default) where T : class => throw null; + public void M11(int arg1 = 3) => throw null; + public void M12(DateTime arg2 = default) => throw null; + public void M13(DateTime? arg3 = null) => throw null; + public void M14([Optional, DateTimeConstant(14L)] DateTime arg4) => throw null; + public void M15([Optional, DateTimeConstant(10001L)] DateTime? arg5) => throw null; + public void M16([Optional, DefaultParameterValue(6L)] long arg6) => throw null; + public void M17([Optional, DefaultParameterValue(null)] object arg7) => throw null; + public void M18([Optional, DefaultParameterValue(3)] int? arg8) => throw null; + public void M19([Optional, DecimalConstant(1, 0, 0, 0, 103)] decimal arg9) => throw null; + public struct MyStruct { } public enum MyEnum { A = 1, B = 2 } } \ No newline at end of file diff --git a/csharp/ql/test/library-tests/parameters/Parameters.dll b/csharp/ql/test/library-tests/parameters/Parameters.dll index cd48ebef015..b40c91369cb 100644 Binary files a/csharp/ql/test/library-tests/parameters/Parameters.dll and b/csharp/ql/test/library-tests/parameters/Parameters.dll differ diff --git a/csharp/ql/test/library-tests/parameters/Parameters.expected b/csharp/ql/test/library-tests/parameters/Parameters.expected index 0ffc1feb4a7..4ac08438d3a 100644 --- a/csharp/ql/test/library-tests/parameters/Parameters.expected +++ b/csharp/ql/test/library-tests/parameters/Parameters.expected @@ -1,10 +1,10 @@ noDefaultValue -| Parameters.cs:3:17:3:18 | M1 | Parameters.cs:3:24:3:24 | a | 0 | -| Parameters.cs:3:17:3:18 | M1 | Parameters.cs:3:34:3:34 | b | 1 | -| Parameters.cs:3:17:3:18 | M1 | Parameters.cs:3:44:3:44 | c | 2 | -| Parameters.cs:4:17:4:18 | M2 | Parameters.cs:4:24:4:24 | a | 0 | -| Parameters.cs:8:17:8:18 | M6 | Parameters.cs:8:29:8:30 | s1 | 0 | -| Parameters.cs:9:17:9:18 | M7 | Parameters.cs:9:27:9:28 | e1 | 0 | +| Parameters.cs:7:17:7:18 | M1 | Parameters.cs:7:24:7:24 | a | 0 | +| Parameters.cs:7:17:7:18 | M1 | Parameters.cs:7:34:7:34 | b | 1 | +| Parameters.cs:7:17:7:18 | M1 | Parameters.cs:7:44:7:44 | c | 2 | +| Parameters.cs:8:17:8:18 | M2 | Parameters.cs:8:24:8:24 | a | 0 | +| Parameters.cs:12:17:12:18 | M6 | Parameters.cs:12:29:12:30 | s1 | 0 | +| Parameters.cs:13:17:13:18 | M7 | Parameters.cs:13:27:13:28 | e1 | 0 | | Parameters.dll:0:0:0:0 | M1 | Parameters.dll:0:0:0:0 | a | 0 | | Parameters.dll:0:0:0:0 | M1 | Parameters.dll:0:0:0:0 | b | 1 | | Parameters.dll:0:0:0:0 | M1 | Parameters.dll:0:0:0:0 | c | 2 | @@ -12,24 +12,33 @@ noDefaultValue | Parameters.dll:0:0:0:0 | M6 | Parameters.dll:0:0:0:0 | s1 | 0 | | Parameters.dll:0:0:0:0 | M7 | Parameters.dll:0:0:0:0 | e1 | 0 | withDefaultValue -| Parameters.cs:4:17:4:18 | M2 | Parameters.cs:4:34:4:34 | b | 1 | Parameters.cs:4:38:4:41 | null | null | -| Parameters.cs:4:17:4:18 | M2 | Parameters.cs:4:51:4:51 | c | 2 | Parameters.cs:4:55:4:70 | "default string" | default string | -| Parameters.cs:5:17:5:18 | M3 | Parameters.cs:5:24:5:24 | a | 0 | Parameters.cs:5:28:5:28 | 1 | 1 | -| Parameters.cs:5:17:5:18 | M3 | Parameters.cs:5:38:5:38 | b | 1 | Parameters.cs:5:42:5:45 | null | null | -| Parameters.cs:5:17:5:18 | M3 | Parameters.cs:5:55:5:55 | c | 2 | Parameters.cs:5:59:5:64 | "null" | null | -| Parameters.cs:6:17:6:18 | M4 | Parameters.cs:6:24:6:24 | a | 0 | Parameters.cs:6:28:6:34 | (...) ... | 0 | -| Parameters.cs:6:17:6:18 | M4 | Parameters.cs:6:44:6:44 | b | 1 | Parameters.cs:6:48:6:54 | default | null | -| Parameters.cs:7:17:7:18 | M5 | Parameters.cs:7:24:7:24 | a | 0 | Parameters.cs:7:28:7:36 | object creation of type Int32 | 0 | -| Parameters.cs:7:17:7:18 | M5 | Parameters.cs:7:46:7:46 | b | 1 | Parameters.cs:7:50:7:56 | default | null | -| Parameters.cs:8:17:8:18 | M6 | Parameters.cs:8:42:8:43 | s2 | 1 | Parameters.cs:8:47:8:63 | default(...) | - | -| Parameters.cs:8:17:8:18 | M6 | Parameters.cs:8:75:8:76 | s3 | 2 | Parameters.cs:8:80:8:93 | object creation of type MyStruct | - | -| Parameters.cs:9:17:9:18 | M7 | Parameters.cs:9:38:9:39 | e2 | 1 | Parameters.cs:9:43:9:57 | default(...) | 0 | -| Parameters.cs:9:17:9:18 | M7 | Parameters.cs:9:67:9:68 | e3 | 2 | Parameters.cs:9:72:9:83 | object creation of type MyEnum | 0 | -| Parameters.cs:9:17:9:18 | M7 | Parameters.cs:9:93:9:94 | e4 | 3 | Parameters.cs:9:98:9:105 | access to constant A | 1 | -| Parameters.cs:9:17:9:18 | M7 | Parameters.cs:9:115:9:116 | e5 | 4 | Parameters.cs:9:120:9:128 | (...) ... | 5 | -| Parameters.cs:11:17:11:21 | M8<> | Parameters.cs:11:25:11:25 | t | 0 | Parameters.cs:11:29:11:35 | (...) ... | - | -| Parameters.cs:12:17:12:21 | M9<> | Parameters.cs:12:25:12:25 | t | 0 | Parameters.cs:12:29:12:35 | (...) ... | - | -| Parameters.cs:13:17:13:22 | M10<> | Parameters.cs:13:26:13:26 | t | 0 | Parameters.cs:13:30:13:36 | (...) ... | null | +| Parameters.cs:8:17:8:18 | M2 | Parameters.cs:8:34:8:34 | b | 1 | Parameters.cs:8:38:8:41 | null | null | +| Parameters.cs:8:17:8:18 | M2 | Parameters.cs:8:51:8:51 | c | 2 | Parameters.cs:8:55:8:70 | "default string" | default string | +| Parameters.cs:9:17:9:18 | M3 | Parameters.cs:9:24:9:24 | a | 0 | Parameters.cs:9:28:9:28 | 1 | 1 | +| Parameters.cs:9:17:9:18 | M3 | Parameters.cs:9:38:9:38 | b | 1 | Parameters.cs:9:42:9:45 | null | null | +| Parameters.cs:9:17:9:18 | M3 | Parameters.cs:9:55:9:55 | c | 2 | Parameters.cs:9:59:9:64 | "null" | null | +| Parameters.cs:10:17:10:18 | M4 | Parameters.cs:10:24:10:24 | a | 0 | Parameters.cs:10:28:10:34 | (...) ... | 0 | +| Parameters.cs:10:17:10:18 | M4 | Parameters.cs:10:44:10:44 | b | 1 | Parameters.cs:10:48:10:54 | default | null | +| Parameters.cs:11:17:11:18 | M5 | Parameters.cs:11:24:11:24 | a | 0 | Parameters.cs:11:28:11:36 | object creation of type Int32 | 0 | +| Parameters.cs:11:17:11:18 | M5 | Parameters.cs:11:46:11:46 | b | 1 | Parameters.cs:11:50:11:56 | default | null | +| Parameters.cs:12:17:12:18 | M6 | Parameters.cs:12:42:12:43 | s2 | 1 | Parameters.cs:12:47:12:63 | default(...) | - | +| Parameters.cs:12:17:12:18 | M6 | Parameters.cs:12:75:12:76 | s3 | 2 | Parameters.cs:12:80:12:93 | object creation of type MyStruct | - | +| Parameters.cs:13:17:13:18 | M7 | Parameters.cs:13:38:13:39 | e2 | 1 | Parameters.cs:13:43:13:57 | default(...) | 0 | +| Parameters.cs:13:17:13:18 | M7 | Parameters.cs:13:67:13:68 | e3 | 2 | Parameters.cs:13:72:13:83 | object creation of type MyEnum | 0 | +| Parameters.cs:13:17:13:18 | M7 | Parameters.cs:13:93:13:94 | e4 | 3 | Parameters.cs:13:98:13:105 | access to constant A | 1 | +| Parameters.cs:13:17:13:18 | M7 | Parameters.cs:13:115:13:116 | e5 | 4 | Parameters.cs:13:120:13:128 | (...) ... | 5 | +| Parameters.cs:15:17:15:21 | M8<> | Parameters.cs:15:25:15:25 | t | 0 | Parameters.cs:15:29:15:35 | (...) ... | - | +| Parameters.cs:16:17:16:21 | M9<> | Parameters.cs:16:25:16:25 | t | 0 | Parameters.cs:16:29:16:35 | (...) ... | - | +| Parameters.cs:17:17:17:22 | M10<> | Parameters.cs:17:26:17:26 | t | 0 | Parameters.cs:17:30:17:36 | (...) ... | null | +| Parameters.cs:19:17:19:19 | M11 | Parameters.cs:19:25:19:28 | arg1 | 0 | Parameters.cs:19:32:19:32 | 3 | 3 | +| Parameters.cs:20:17:20:19 | M12 | Parameters.cs:20:30:20:33 | arg2 | 0 | Parameters.cs:20:37:20:43 | (...) ... | - | +| Parameters.cs:21:17:21:19 | M13 | Parameters.cs:21:31:21:34 | arg3 | 0 | Parameters.cs:21:38:21:41 | null | null | +| Parameters.cs:22:17:22:19 | M14 | Parameters.cs:22:64:22:67 | arg4 | 0 | Parameters.cs:22:21:22:67 | object creation of type DateTime | - | +| Parameters.cs:23:17:23:19 | M15 | Parameters.cs:23:68:23:71 | arg5 | 0 | Parameters.cs:23:21:23:71 | object creation of type DateTime | - | +| Parameters.cs:24:17:24:19 | M16 | Parameters.cs:24:64:24:67 | arg6 | 0 | Parameters.cs:24:21:24:67 | 6 | 6 | +| Parameters.cs:25:17:25:19 | M17 | Parameters.cs:25:68:25:71 | arg7 | 0 | Parameters.cs:25:21:25:71 | default | null | +| Parameters.cs:26:17:26:19 | M18 | Parameters.cs:26:63:26:66 | arg8 | 0 | Parameters.cs:26:21:26:66 | 3 | 3 | +| Parameters.cs:27:17:27:19 | M19 | Parameters.cs:27:74:27:77 | arg9 | 0 | Parameters.cs:27:21:27:77 | 10.3 | 10.3 | | Parameters.dll:0:0:0:0 | M2 | Parameters.dll:0:0:0:0 | b | 1 | Parameters.dll:0:0:0:0 | default | null | | Parameters.dll:0:0:0:0 | M2 | Parameters.dll:0:0:0:0 | c | 2 | Parameters.dll:0:0:0:0 | "default string" | default string | | Parameters.dll:0:0:0:0 | M3 | Parameters.dll:0:0:0:0 | a | 0 | Parameters.dll:0:0:0:0 | 1 | 1 | @@ -48,3 +57,17 @@ withDefaultValue | Parameters.dll:0:0:0:0 | M8<> | Parameters.dll:0:0:0:0 | t | 0 | Parameters.dll:0:0:0:0 | default | - | | Parameters.dll:0:0:0:0 | M9<> | Parameters.dll:0:0:0:0 | t | 0 | Parameters.dll:0:0:0:0 | default | - | | Parameters.dll:0:0:0:0 | M10<> | Parameters.dll:0:0:0:0 | t | 0 | Parameters.dll:0:0:0:0 | default | null | +| Parameters.dll:0:0:0:0 | M11 | Parameters.dll:0:0:0:0 | arg1 | 0 | Parameters.dll:0:0:0:0 | 3 | 3 | +| Parameters.dll:0:0:0:0 | M12 | Parameters.dll:0:0:0:0 | arg2 | 0 | Parameters.dll:0:0:0:0 | default | - | +| Parameters.dll:0:0:0:0 | M13 | Parameters.dll:0:0:0:0 | arg3 | 0 | Parameters.dll:0:0:0:0 | default | - | +| Parameters.dll:0:0:0:0 | M14 | Parameters.dll:0:0:0:0 | arg4 | 0 | Parameters.dll:0:0:0:0 | object creation of type DateTime | - | +| Parameters.dll:0:0:0:0 | M15 | Parameters.dll:0:0:0:0 | arg5 | 0 | Parameters.dll:0:0:0:0 | object creation of type DateTime | - | +| Parameters.dll:0:0:0:0 | M16 | Parameters.dll:0:0:0:0 | arg6 | 0 | Parameters.dll:0:0:0:0 | 6 | 6 | +| Parameters.dll:0:0:0:0 | M17 | Parameters.dll:0:0:0:0 | arg7 | 0 | Parameters.dll:0:0:0:0 | default | null | +| Parameters.dll:0:0:0:0 | M18 | Parameters.dll:0:0:0:0 | arg8 | 0 | Parameters.dll:0:0:0:0 | 3 | 3 | +| Parameters.dll:0:0:0:0 | M19 | Parameters.dll:0:0:0:0 | arg9 | 0 | Parameters.dll:0:0:0:0 | 10.3 | 10.3 | +dateTimeDefaults +| Parameters.cs:22:17:22:19 | M14 | Parameters.cs:22:64:22:67 | arg4 | Parameters.cs:22:21:22:67 | object creation of type DateTime | DateTime(long) | 14 | +| Parameters.cs:23:17:23:19 | M15 | Parameters.cs:23:68:23:71 | arg5 | Parameters.cs:23:21:23:71 | object creation of type DateTime | DateTime(long) | 10001 | +| Parameters.dll:0:0:0:0 | M14 | Parameters.dll:0:0:0:0 | arg4 | Parameters.dll:0:0:0:0 | object creation of type DateTime | DateTime(long) | 14 | +| Parameters.dll:0:0:0:0 | M15 | Parameters.dll:0:0:0:0 | arg5 | Parameters.dll:0:0:0:0 | object creation of type DateTime | DateTime(long) | 10001 | diff --git a/csharp/ql/test/library-tests/parameters/Parameters.ql b/csharp/ql/test/library-tests/parameters/Parameters.ql index dca5c2d9006..09eadc693f0 100644 --- a/csharp/ql/test/library-tests/parameters/Parameters.ql +++ b/csharp/ql/test/library-tests/parameters/Parameters.ql @@ -4,10 +4,16 @@ private predicate fromTestLocation(Element e) { e.fromSource() or e.getFile().getStem() = "Parameters" } +private predicate compilerGeneratedAttribute(Parameterizable container) { + container.getDeclaringType().getAnAttribute().getType().toStringWithTypes() = + "CompilerGeneratedAttribute" +} + query predicate noDefaultValue(Parameterizable container, Parameter p, int i) { fromTestLocation(container) and not p.hasDefaultValue() and - container.getParameter(i) = p + container.getParameter(i) = p and + not compilerGeneratedAttribute(container) } query predicate withDefaultValue(Parameterizable container, Parameter p, int i, Expr e, string value) { @@ -15,5 +21,18 @@ query predicate withDefaultValue(Parameterizable container, Parameter p, int i, p.hasDefaultValue() and container.getParameter(i) = p and p.getDefaultValue() = e and - if exists(e.getValue()) then value = e.getValue() else value = "-" + (if exists(e.getValue()) then value = e.getValue() else value = "-") and + not compilerGeneratedAttribute(container) +} + +query predicate dateTimeDefaults( + Parameterizable container, Parameter p, ObjectCreation o, string constructor, string value +) { + fromTestLocation(container) and + p.hasDefaultValue() and + container.getAParameter() = p and + p.getDefaultValue() = o and + o.getTarget().toStringWithTypes() = constructor and + o.getAnArgument().getValue() = value and + not compilerGeneratedAttribute(container) } diff --git a/csharp/ql/test/resources/stubs/EntityFramework.cs b/csharp/ql/test/resources/stubs/EntityFramework.cs index 4612349a923..dca9c1685cb 100644 --- a/csharp/ql/test/resources/stubs/EntityFramework.cs +++ b/csharp/ql/test/resources/stubs/EntityFramework.cs @@ -10,17 +10,12 @@ namespace System.Data.Entity { } - public class DbSet : IEnumerable + public class DbSet : IEnumerable { - public void Add(T t) { } - public System.Threading.Tasks.Task AddAsync(T t) => null; - public void AddRange(IEnumerable t) { } - public System.Threading.Tasks.Task AddRangeAsync(IEnumerable t) => null; - public void Attach(T t) { } - public void AttachRange(IEnumerable t) { } - public void Update(T t) { } - public void UpdateRange(IEnumerable t) { } - IEnumerator IEnumerable.GetEnumerator() => null; + public void Add(TEntity t) { } + public void AddRange(IEnumerable t) { } + public void Attach(TEntity t) { } + IEnumerator IEnumerable.GetEnumerator() => null; IEnumerator IEnumerable.GetEnumerator() => null; } @@ -59,17 +54,22 @@ namespace System.Data.Entity.Infrastructure namespace Microsoft.EntityFrameworkCore { - public class DbSet : IEnumerable + public class DbSet : IEnumerable { - public void Add(T t) { } - public System.Threading.Tasks.Task AddAsync(T t) => null; - public void AddRange(IEnumerable t) { } - public System.Threading.Tasks.Task AddRangeAsync(IEnumerable t) => null; - public void Attach(T t) { } - public void AttachRange(IEnumerable t) { } - public void Update(T t) { } - public void UpdateRange(IEnumerable t) { } - IEnumerator IEnumerable.GetEnumerator() => null; + public void Add(TEntity t) { } + public System.Threading.Tasks.Task AddAsync(TEntity t, System.Threading.CancellationToken ct = default) => null; + public void AddRange(IEnumerable t) { } + public void AddRange(TEntity[] t) { } + public System.Threading.Tasks.Task AddRangeAsync(IEnumerable t, System.Threading.CancellationToken ct = default) => null; + public System.Threading.Tasks.Task AddRangeAsync(TEntity[] t) => null; + public void Attach(TEntity t) { } + public void AttachRange(IEnumerable t) { } + public void AttachRange(TEntity[] t) { } + public void Update(TEntity t) { } + public void UpdateRange(IEnumerable t) { } + public void UpdateRange(TEntity[] t) { } + + IEnumerator IEnumerable.GetEnumerator() => null; IEnumerator IEnumerable.GetEnumerator() => null; } diff --git a/csharp/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.expected b/csharp/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.expected index e65a2ae7d4a..4a11cff39af 100644 --- a/csharp/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.expected +++ b/csharp/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.expected @@ -1,4 +1,4 @@ -| Sinks;NewSinks;false;WrapFieldResponseWriteFile;();;Argument[this];html;df-generated | -| Sinks;NewSinks;false;WrapPropResponseWriteFile;();;Argument[this];html;df-generated | -| Sinks;NewSinks;false;WrapResponseWrite;(System.Object);;Argument[0];html;df-generated | -| Sinks;NewSinks;false;WrapResponseWriteFile;(System.String);;Argument[0];html;df-generated | +| Sinks;NewSinks;false;WrapFieldResponseWriteFile;();;Argument[this];html-injection;df-generated | +| Sinks;NewSinks;false;WrapPropResponseWriteFile;();;Argument[this];html-injection;df-generated | +| Sinks;NewSinks;false;WrapResponseWrite;(System.Object);;Argument[0];html-injection;df-generated | +| Sinks;NewSinks;false;WrapResponseWriteFile;(System.String);;Argument[0];html-injection;df-generated | diff --git a/csharp/tools/tracing-config.lua b/csharp/tools/tracing-config.lua index 2db04d83524..79b2ea2ca1c 100644 --- a/csharp/tools/tracing-config.lua +++ b/csharp/tools/tracing-config.lua @@ -63,7 +63,7 @@ function RegisterExtractorPack(id) end end if match then - local injections = { '-p:UseSharedCompilation=false' } + local injections = { '-p:UseSharedCompilation=false', '-p:EmitCompilerGeneratedFiles=true' } if dotnetRunNeedsSeparator then table.insert(injections, '--') end @@ -118,7 +118,8 @@ function RegisterExtractorPack(id) compilerArguments, nil, { '/p:UseSharedCompilation=false', - '/p:MvcBuildViews=true' + '/p:MvcBuildViews=true', + '/p:EmitCompilerGeneratedFiles=true', }) } @@ -154,7 +155,7 @@ function RegisterExtractorPack(id) if seenCompilerCall then return { - order = ORDER_BEFORE, + order = ORDER_AFTER, invocation = { path = AbsolutifyExtractorPath(id, extractor), arguments = { @@ -194,7 +195,7 @@ function RegisterExtractorPack(id) if seenCompilerCall then return { - order = ORDER_BEFORE, + order = ORDER_AFTER, invocation = { path = AbsolutifyExtractorPath(id, extractor), arguments = { diff --git a/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst index 597ce491463..8625d637366 100644 --- a/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst +++ b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst @@ -70,18 +70,22 @@ For example, we would like to flag this code: .. code-block:: javascript - var data = JSON.parse(str); - if (data.length > 0) { // problematic: `data` may be `null` - ... + function test(str) { + var data = JSON.parse(str); + if (data.length > 0) { // problematic: `data` may be `null` + ... + } } This code, on the other hand, should not be flagged: .. code-block:: javascript - var data = JSON.parse(str); - if (data && data.length > 0) { // unproblematic: `data` is first checked for nullness - ... + function test(str) { + var data = JSON.parse(str); + if (data && data.length > 0) { // unproblematic: `data` is first checked for nullness + ... + } } We will first try to write a query to find this kind of problem without flow labels, and use the @@ -168,11 +172,13 @@ checked for null-guardedness: .. code-block:: javascript - var root = JSON.parse(str); - if (root) { - var payload = root.data; // unproblematic: `root` cannot be `null` here - if (payload.length > 0) { // problematic: `payload` may be `null` here - ... + function test(str) { + var root = JSON.parse(str); + if (root) { + var payload = root.data; // unproblematic: `root` cannot be `null` here + if (payload.length > 0) { // problematic: `payload` may be `null` here + ... + } } } diff --git a/docs/codeql/ql-language-reference/annotations.rst b/docs/codeql/ql-language-reference/annotations.rst index 7b860e39719..70e4321667f 100644 --- a/docs/codeql/ql-language-reference/annotations.rst +++ b/docs/codeql/ql-language-reference/annotations.rst @@ -292,7 +292,7 @@ at the places where it is called. ``pragma[inline_late]`` ----------------------- -**Available for**: |non-member predicates| +**Available for**: |characteristic predicates|, |member predicates|, |non-member predicates| The ``pragma[inline_late]`` annotation must be used in conjunction with a ``bindingset[...]`` pragma. Together, they tell the QL optimiser to use the diff --git a/docs/codeql/ql-language-reference/ql-language-specification.rst b/docs/codeql/ql-language-reference/ql-language-specification.rst index c1575b3d6e5..71dcbdce571 100644 --- a/docs/codeql/ql-language-reference/ql-language-specification.rst +++ b/docs/codeql/ql-language-reference/ql-language-specification.rst @@ -186,21 +186,21 @@ A QL module definition has the following syntax: A module definition extends the current module's declared module environment with a mapping from the module name to the module definition. -QL files consist of simply a module body without a name and surrounding braces: +QL files and QLL files consist of simply a module body without a name and surrounding braces: :: ql ::= moduleBody -QL files define a module corresponding to the file, whose name is the same as the filename. +QL files and QLL files define a module corresponding to the file, whose name is the same as the filename. Kinds of modules ~~~~~~~~~~~~~~~~ A module may be: -- A *file module*, if it is defined implicitly by a QL file. -- A *query module*, if it is defined by a QL file. +- A *file module*, if it is defined implicitly by a QL file or a QLL file. +- A *query module*, if it is defined implicitly by a QL file. - A *library module*, if it is not a query module. A query module must contain one or more queries. @@ -334,40 +334,6 @@ Active types In a QL program, the *active* types are those defined in active modules. In the remainder of this specification, any reference to the types in the program refers only to the active types. - -Signatures ----------- - -Signature definitions -~~~~~~~~~~~~~~~~~~~~~ - -A QL signature definition has the following syntax: - -:: - - signature ::= predicateSignature | typeSignature | moduleSignature - - predicateSignature ::= qldoc? annotations "signature" head ";" - - typeSignature ::= qldoc? annotations "signature" "class" classname ("extends" type ("," type)*)? (";" | "{" signaturePredicate* "}") - - moduleSignature ::= qldoc? annotation* "signature" "module" moduleSignatureName parameters? "{" moduleSignatureBody "}" - - moduleSignatureBody ::= (signaturePredicate | defaultPredicate | signatureType)* - - signaturePredicate ::= qldoc? annotations head ";" - - defaultPredicate ::= qldoc? annotations "default" head "{" formula "}" - - signatureType ::= qldoc? annotations "class" classname ("extends" type ("," type)*)? "{" signaturePredicate* "}" - - -A predicate signature definition extends the current module's declared predicate signature environment with a mapping from the predicate signature name and arity to the predicate signature definition. - -A type signature definition extends the current module's declared type signature environment with a mapping from the type signature name to the type signature definition. - -A module signature definition extends the current module's declared module signature environment with a mapping from the module signature name to the module signature definition. - Values ------ @@ -704,12 +670,14 @@ Various kinds of syntax can have *annotations* applied to them. Annotations are simpleAnnotation ::= "abstract" | "cached" | "external" + | "extensible" | "final" | "transient" | "library" | "private" | "deprecated" | "override" + | "additional" | "query" argsAnnotation ::= "pragma" "[" ("inline" | "inline_late" | "noinline" | "nomagic" | "noopt" | "assume_small_delta") "]" @@ -725,31 +693,36 @@ Simple annotations The following table summarizes the syntactic constructs which can be marked with each annotation in a valid program; for example, an ``abstract`` annotation preceding a character is invalid. -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+ -| Annotation | Classes | Characters | Member predicates | Non-member predicates | Imports | Fields | Modules | Aliases | -+================+=========+============+===================+=======================+=========+========+=========+=========+ -| ``abstract`` | yes | | yes | | | | | | -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+ -| ``cached`` | yes | yes | yes | yes | | | yes | | -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+ -| ``external`` | | | | yes | | | | | -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+ -| ``final`` | yes | | yes | | | yes | | yes | -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+ -| ``transient`` | | | | yes | | | | | -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+ -| ``library`` | yes | | | | | | | | -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+ -| ``private`` | yes | | yes | yes | yes | yes | yes | yes | -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+ -| ``deprecated`` | yes | | yes | yes | | yes | yes | yes | -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+ -| ``override`` | | | yes | | | yes | | | -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+ -| ``query`` | | | | yes | | | | yes | -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+ ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| Annotation | Classes | Characters | Member predicates | Non-member predicates | Imports | Fields | Modules | Aliases | Signatures | ++================+=========+============+===================+=======================+=========+========+=========+=========+============+ +| ``abstract`` | yes | | yes | | | | | | | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| ``cached`` | yes | yes | yes | yes | | | yes | | | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| ``external`` | | | | yes | | | | | | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| ``extensible`` | | | | yes | | | | | | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| ``final`` | yes | | yes | | | yes | | (yes) | | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| ``transient`` | | | | yes | | | | | | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| ``library`` | (yes) | | | | | | | | | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| ``private`` | yes | | yes | yes | yes | yes | yes | yes | yes | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| ``deprecated`` | yes | | yes | yes | | yes | yes | yes | yes | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| ``override`` | | | yes | | | yes | | | | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| ``additional`` | yes | | | yes | | | yes | yes | yes | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| ``query`` | | | | yes | | | | yes | | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ The ``library`` annotation is only usable within a QLL file, not a QL file. +The ``final`` annotation is usable on type aliases, but not on module aliases and predicate aliases. Annotations on aliases apply to the name introduced by the alias. An alias may, for example, have different privacy to the name it aliases. @@ -765,7 +738,7 @@ The parameterized annotation ``pragma`` supplies compiler pragmas, and may be ap +===========================+=========+============+===================+=======================+=========+========+=========+=========+ | ``inline`` | | yes | yes | yes | | | | | +---------------------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+ -| ``inline_late`` | | | | yes | | | | | +| ``inline_late`` | | yes | yes | yes | | | | | +---------------------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+ | ``noinline`` | | yes | yes | yes | | | | | +---------------------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+ @@ -799,11 +772,13 @@ Binding sets are checked by the QL compiler in the following way: A predicate may have several different binding sets, which can be stated by using multiple ``bindingset`` annotations on the same predicate. -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+ -| Pragma | Classes | Characters | Member predicates | Non-member predicates | Imports | Fields | Modules | Aliases | -+================+=========+============+===================+=======================+=========+========+=========+=========+ -| ``bindingset`` | | yes | yes | yes | | | | | -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+ ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| Annotation | Classes | Characters | Member predicates | Non-member predicates | Imports | Fields | Modules | Aliases | Signatures | ++================+=========+============+===================+=======================+=========+========+=========+=========+============+ +| ``bindingset`` | | yes | yes | yes | | | | | (yes) | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ + +The ``bindingset`` pragma is usable with type signatures and predicate signatures, but not with module signatures. QLDoc ----- @@ -850,7 +825,7 @@ If the query file starts with whitespace followed by a QLDoc comment, then the t Top-level entities ------------------ -Modules include five kinds of top-level entity: predicates, classes, modules, aliases, and select clauses. +Modules include five kinds of top-level entity: predicates, classes, modules, aliases, signatures, and select clauses. Non-member predicates ~~~~~~~~~~~~~~~~~~~~~ @@ -1004,6 +979,37 @@ A valid field must override another field if it is annotated ``override``. When field ``f`` overrides field ``g`` the type of ``f`` must be a subtype of the type of ``g``. ``f`` may not be a final field. + +Signatures +~~~~~~~~~~ + +A signature definition has the following syntax: + +:: + + signature ::= predicateSignature | typeSignature | moduleSignature + + predicateSignature ::= qldoc? annotations "signature" head ";" + + typeSignature ::= qldoc? annotations "signature" "class" classname ("extends" type ("," type)*)? (";" | "{" signaturePredicate* "}") + + moduleSignature ::= qldoc? annotation* "signature" "module" moduleSignatureName parameters? "{" moduleSignatureBody "}" + + moduleSignatureBody ::= (signaturePredicate | defaultPredicate | signatureType)* + + signaturePredicate ::= qldoc? annotations head ";" + + defaultPredicate ::= qldoc? annotations "default" head "{" formula "}" + + signatureType ::= qldoc? annotations "class" classname ("extends" type ("," type)*)? "{" signaturePredicate* "}" + + +A predicate signature definition extends the current module's declared predicate signature environment with a mapping from the predicate signature name and arity to the predicate signature definition. + +A type signature definition extends the current module's declared type signature environment with a mapping from the type signature name to the type signature definition. + +A module signature definition extends the current module's declared module signature environment with a mapping from the module signature name to the module signature definition. + Select clauses ~~~~~~~~~~~~~~ @@ -2159,12 +2165,14 @@ The complete grammar for QL is as follows: simpleAnnotation ::= "abstract" | "cached" | "external" + | "extensible" | "final" | "transient" | "library" | "private" | "deprecated" | "override" + | "additional" | "query" argsAnnotation ::= "pragma" "[" ("inline" | "inline_late" | "noinline" | "nomagic" | "noopt" | "assume_small_delta") "]" diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index 227bbaa65c3..48f5dd8ae41 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -32,6 +32,7 @@ flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 freemarker.cache,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, freemarker.template,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,, groovy.lang,26,,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +groovy.text,1,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, groovy.util,5,,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, hudson,44,,16,,19,,,,,,,,,,,,,6,,17,,,,,,,,,,,,2,,,,,,,,16, io.jsonwebtoken,,2,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,4, @@ -53,7 +54,7 @@ java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, java.io,44,,45,,18,,,,,,,,,,,,,,,4,,,,,,,,,,,,22,,,,,,,,43,2 java.lang,18,,92,,,,,,,,,,,,8,,,,,5,,4,,,1,,,,,,,,,,,,,,,56,36 java.net,13,3,20,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,3,20, -java.nio,36,,31,,21,,,,,,,,,,,,,,,12,,,,,,,,,,,,3,,,,,,,,31, +java.nio,38,,31,,22,,,,,,,,,,,,,,,13,,,,,,,,,,,,3,,,,,,,,31, java.sql,13,,3,,,,,,,,4,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,2,1 java.util,44,,484,,,,,,,,,,,,34,,,,,,,,5,2,,1,2,,,,,,,,,,,,,44,440 javafx.scene.web,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index 2aa38591d6f..d89fce45524 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -18,10 +18,10 @@ Java framework & library support `Google Guava `_,``com.google.common.*``,,730,41,2,,,,, JBoss Logging,``org.jboss.logging``,,,324,,,,,, `JSON-java `_,``org.json``,,236,,,,,,, - Java Standard Library,``java.*``,3,679,168,39,,9,,,13 + Java Standard Library,``java.*``,3,679,170,40,,9,,,13 Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,1,4,,1,1,2 Kotlin Standard Library,``kotlin*``,,1843,16,11,,,,,2 `Spring `_,``org.springframework.*``,29,483,113,2,,28,14,,29 - Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.hubspot.jinjava``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",89,827,515,26,,18,18,,181 - Totals,,246,9119,1966,174,10,122,33,1,361 + Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.hubspot.jinjava``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",89,827,516,26,,18,18,,181 + Totals,,246,9119,1969,175,10,122,33,1,361 diff --git a/java/ql/lib/change-notes/2023-05-17-change-hostnamesanitizingprefix-regex.md b/java/ql/lib/change-notes/2023-05-17-change-hostnamesanitizingprefix-regex.md new file mode 100644 index 00000000000..8d81c97d9e3 --- /dev/null +++ b/java/ql/lib/change-notes/2023-05-17-change-hostnamesanitizingprefix-regex.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Updated the regular expression in the `HostnameSanitizer` sanitizer in the `semmle.code.java.security.RequestForgery` library to better detect strings prefixed with a hostname. + diff --git a/java/ql/lib/change-notes/2023-05-22-inputstreamwrapper-transitive.md b/java/ql/lib/change-notes/2023-05-22-inputstreamwrapper-transitive.md new file mode 100644 index 00000000000..bba77d98d89 --- /dev/null +++ b/java/ql/lib/change-notes/2023-05-22-inputstreamwrapper-transitive.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Dataflow analysis has a new flow step through constructors of transitive subtypes of `java.io.InputStream` that wrap an underlying data source. Previously, the step only existed for direct subtypes of `java.io.InputStream`. diff --git a/java/ql/lib/change-notes/2023-05-23-java-nio-file-files-copy-models-tweak.md b/java/ql/lib/change-notes/2023-05-23-java-nio-file-files-copy-models-tweak.md new file mode 100644 index 00000000000..85fc9b89197 --- /dev/null +++ b/java/ql/lib/change-notes/2023-05-23-java-nio-file-files-copy-models-tweak.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +Modified the models related to `java.nio.file.Files.copy` so that generic `[Input|Output]Stream` arguments are not considered file-related sinks. diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index ae792106180..42ae8b9052b 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -3,9 +3,11 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - - ["java.nio.file", "Files", False, "copy", "", "", "Argument[0]", "read-file", "manual"] + - ["java.nio.file", "Files", False, "copy", "(Path,OutputStream)", "", "Argument[0]", "read-file", "manual"] + - ["java.nio.file", "Files", False, "copy", "(Path,Path,CopyOption[])", "", "Argument[0]", "read-file", "manual"] + - ["java.nio.file", "Files", False, "copy", "(Path,Path,CopyOption[])", "", "Argument[1]", "create-file", "manual"] - ["java.nio.file", "Files", False, "copy", "(InputStream,Path,CopyOption[])", "", "Argument[0]", "write-file", "manual"] - - ["java.nio.file", "Files", False, "copy", "", "", "Argument[1]", "create-file", "manual"] + - ["java.nio.file", "Files", False, "copy", "(InputStream,Path,CopyOption[])", "", "Argument[1]", "create-file", "manual"] - ["java.nio.file", "Files", False, "createDirectories", "", "", "Argument[0]", "create-file", "manual"] - ["java.nio.file", "Files", False, "createDirectory", "", "", "Argument[0]", "create-file", "manual"] - ["java.nio.file", "Files", False, "createFile", "", "", "Argument[0]", "create-file", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.core5.http.impl.bootstrap.model.yml b/java/ql/lib/ext/org.apache.hc.core5.http.impl.bootstrap.model.yml index a2789520908..c9515372645 100644 --- a/java/ql/lib/ext/org.apache.hc.core5.http.impl.bootstrap.model.yml +++ b/java/ql/lib/ext/org.apache.hc.core5.http.impl.bootstrap.model.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: sinkModel data: - ["org.apache.hc.core5.http.impl.bootstrap", "HttpAsyncRequester", True, "connect", "(HttpHost,Timeout)", "", "Argument[0]", "open-url", "hq-manual"] diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index 874c08bdaba..af8f2273cbe 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -255,8 +255,9 @@ private class BulkData extends RefType { * status of its argument. */ private predicate inputStreamWrapper(Constructor c, int argi) { + not c.fromSource() and c.getParameterType(argi) instanceof BulkData and - c.getDeclaringType().getASourceSupertype().hasQualifiedName("java.io", "InputStream") + c.getDeclaringType().getASourceSupertype+().hasQualifiedName("java.io", "InputStream") } /** An object construction that preserves the data flow status of any of its arguments. */ diff --git a/java/ql/lib/semmle/code/java/security/RequestForgery.qll b/java/ql/lib/semmle/code/java/security/RequestForgery.qll index c454da5f035..f9b98490dfa 100644 --- a/java/ql/lib/semmle/code/java/security/RequestForgery.qll +++ b/java/ql/lib/semmle/code/java/security/RequestForgery.qll @@ -79,10 +79,7 @@ private class HostnameSanitizingPrefix extends InterestingPrefix { // the host or entity addressed: for example, anything containing `?` or `#`, or a slash that // doesn't appear to be a protocol specifier (e.g. `http://` is not sanitizing), or specifically // the string "/". - exists( - this.getStringValue() - .regexpFind(".*([?#]|[^?#:/\\\\][/\\\\]).*|[/\\\\][^/\\\\].*|^/$", 0, offset) - ) + exists(this.getStringValue().regexpFind("([?#]|[^?#:/\\\\][/\\\\])|^/$", 0, offset)) } override int getOffset() { result = offset } diff --git a/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.qhelp b/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.qhelp index dbb1f4c37f5..5a56343420a 100644 --- a/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.qhelp +++ b/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.qhelp @@ -15,8 +15,7 @@

- Pattern.compile("^\\s+|\\s+$").matcher(text).replaceAll("") // BAD - +Pattern.compile("^\\s+|\\s+$").matcher(text).replaceAll("") // BAD

@@ -71,8 +70,7 @@

- "^0\\.\\d+E?\\d+$"" - +"^0\\.\\d+E?\\d+$""

@@ -103,6 +101,33 @@ + +

+ Sometimes it is unclear how a regular expression can be rewritten to + avoid the problem. In such cases, it often suffices to limit the + length of the input string. For instance, the following + regular expression is used to match numbers, and on some non-number + inputs it can have quadratic time complexity: +

+ + +Pattern.matches("^(\\+|-)?(\\d+|(\\d*\\.\\d*))?(E|e)?([-+])?(\\d+)?$", str); + +

+ It is not immediately obvious how to rewrite this regular expression + to avoid the problem. However, you can mitigate performance issues by limiting the length + to 1000 characters, which will always finish in a reasonable amount + of time. +

+ + +if (str.length() > 1000) { + throw new IllegalArgumentException("Input too long"); +} + +Pattern.matches("^(\\+|-)?(\\d+|(\\d*\\.\\d*))?(E|e)?([-+])?(\\d+)?$", str); + + diff --git a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py index 5e35ca52dd1..1cc943a78ec 100755 --- a/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py +++ b/java/ql/src/utils/flowtestcasegenerator/GenerateFlowTestCase.py @@ -18,7 +18,7 @@ GenerateFlowTestCase.py specsToTest projectPom.xml outdir [--force] This generates test cases exercising function model specifications found in specsToTest producing files Test.java, test.ql, test.ext.yml and test.expected in outdir. -specsToTest should either be a .csv file, a .yml file, or a directory of .yml files, containing the +specsToTest should either be a .csv file, a .yml file, or a directory of .yml files, containing the model specifications to test. projectPom.xml should be a Maven pom sufficient to resolve the classes named in specsToTest.csv. @@ -276,7 +276,7 @@ if len(supportModelRows) != 0: modelSpecRow[0].strip() for modelSpecRow in supportModelRows) dataextensions = f"""extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: {models} diff --git a/java/ql/src/utils/stub-generator/Stubs.qll b/java/ql/src/utils/stub-generator/Stubs.qll index 785f621cba0..889bc6b466c 100644 --- a/java/ql/src/utils/stub-generator/Stubs.qll +++ b/java/ql/src/utils/stub-generator/Stubs.qll @@ -285,15 +285,25 @@ private string stubQualifier(RefType t) { else result = "" } +pragma[nomagic] +private predicate needsPackageNameHelper(RefType t, GeneratedTopLevel top, string name) { + t.getSourceDeclaration() = + pragma[only_bind_out]([getAReferencedType(top), top].getSourceDeclaration()) and + name = t.getName() +} + +pragma[nomagic] +private predicate describesMultipleTypes(GeneratedTopLevel top, string name) { + 2 <= strictcount(RefType t | needsPackageNameHelper(t, top, name)) +} + /** * Holds if `t` may clash with another type of the same name, so should be referred to using the fully qualified name */ private predicate needsPackageName(RefType t) { - exists(GeneratedTopLevel top, RefType other | - t.getSourceDeclaration() = [getAReferencedType(top), top].getSourceDeclaration() and - other.getSourceDeclaration() = [getAReferencedType(top), top].getSourceDeclaration() and - t.getName() = other.getName() and - t != other + exists(GeneratedTopLevel top, string name | + needsPackageNameHelper(t, top, name) and + describesMultipleTypes(top, name) ) } diff --git a/java/ql/test/ext/TestModels/test.ext.yml b/java/ql/test/ext/TestModels/test.ext.yml index 4fff7d575a3..c5873214f71 100644 --- a/java/ql/test/ext/TestModels/test.ext.yml +++ b/java/ql/test/ext/TestModels/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "newWithMapValueDefault", "(Object)", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ext.yml b/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ext.yml index 589c787bf9a..700f3f51e6f 100644 --- a/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ext.yml +++ b/java/ql/test/kotlin/library-tests/dataflow/notnullexpr/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["", "Uri", False, "getQueryParameter", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ext.yml b/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ext.yml index 589c787bf9a..700f3f51e6f 100644 --- a/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ext.yml +++ b/java/ql/test/kotlin/library-tests/dataflow/whenexpr/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["", "Uri", False, "getQueryParameter", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/test/library-tests/dataflow/callback-dispatch/test.ext.yml b/java/ql/test/library-tests/dataflow/callback-dispatch/test.ext.yml index 5f35c923ad0..a153e39a0e0 100644 --- a/java/ql/test/library-tests/dataflow/callback-dispatch/test.ext.yml +++ b/java/ql/test/library-tests/dataflow/callback-dispatch/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["my.callback.qltest", "A", False, "applyConsumer1", "(Object,Consumer1)", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] @@ -15,4 +15,3 @@ extensions: - ["my.callback.qltest", "A", False, "produceConsume", "(Producer1,Consumer3)", "", "Argument[1].Parameter[0]", "ReturnValue", "value", "manual"] - ["my.callback.qltest", "A", False, "applyConverter1", "(Object,Converter1)", "", "Argument[0]", "Argument[1].Parameter[0]", "value", "manual"] - ["my.callback.qltest", "A", False, "applyConverter1", "(Object,Converter1)", "", "Argument[1].ReturnValue", "ReturnValue", "value", "manual"] - diff --git a/java/ql/test/library-tests/dataflow/collections/containerflow.ext.yml b/java/ql/test/library-tests/dataflow/collections/containerflow.ext.yml index ebe7e3b6ea5..c12a0156d0c 100644 --- a/java/ql/test/library-tests/dataflow/collections/containerflow.ext.yml +++ b/java/ql/test/library-tests/dataflow/collections/containerflow.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["", "B", False, "readElement", "(Spliterator)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/library-tests/dataflow/external-models/sinks.ext.yml b/java/ql/test/library-tests/dataflow/external-models/sinks.ext.yml index 55a76b79b21..d469a2de0dc 100644 --- a/java/ql/test/library-tests/dataflow/external-models/sinks.ext.yml +++ b/java/ql/test/library-tests/dataflow/external-models/sinks.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: sinkModel data: - ["my.qltest", "B", False, "sink1", "(Object)", "", "Argument[0]", "qltest", "manual"] diff --git a/java/ql/test/library-tests/dataflow/external-models/srcs.ext.yml b/java/ql/test/library-tests/dataflow/external-models/srcs.ext.yml index 7730d41e549..9693152f1c0 100644 --- a/java/ql/test/library-tests/dataflow/external-models/srcs.ext.yml +++ b/java/ql/test/library-tests/dataflow/external-models/srcs.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: sourceModel data: - ["my.qltest", "A", False, "src1", "()", "", "ReturnValue", "qltest", "manual"] diff --git a/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml b/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml index 41d26cf815a..c6a1fb69d6d 100644 --- a/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml +++ b/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["my.qltest", "C", False, "stepArgRes", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/test/library-tests/dataflow/synth-global/test.ext.yml b/java/ql/test/library-tests/dataflow/synth-global/test.ext.yml index 3d3bbe9fd47..58b4d2ecc24 100644 --- a/java/ql/test/library-tests/dataflow/synth-global/test.ext.yml +++ b/java/ql/test/library-tests/dataflow/synth-global/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["my.qltest.synth", "A", False, "storeInArray", "(String)", "", "Argument[0]", "SyntheticGlobal[db1].ArrayElement", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ext.yml b/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ext.yml index cf5c80bc456..06781456552 100644 --- a/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ext.yml +++ b/java/ql/test/library-tests/frameworks/android/content-provider-summaries/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "newWithMapValueDefault", "(Object)", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/android/intent/test.ext.yml b/java/ql/test/library-tests/frameworks/android/intent/test.ext.yml index 31321102a46..0a3ce554bc7 100644 --- a/java/ql/test/library-tests/frameworks/android/intent/test.ext.yml +++ b/java/ql/test/library-tests/frameworks/android/intent/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "newBundleWithMapValue", "(Object)", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/android/notification/test.ext.yml b/java/ql/test/library-tests/frameworks/android/notification/test.ext.yml index bd5c804fddc..69b416a5b72 100644 --- a/java/ql/test/library-tests/frameworks/android/notification/test.ext.yml +++ b/java/ql/test/library-tests/frameworks/android/notification/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "getMapKeyDefault", "(Bundle)", "", "Argument[0].MapKey", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/apache-collections/test.ext.yml b/java/ql/test/library-tests/frameworks/apache-collections/test.ext.yml index a5d1cc8e1ab..60531154074 100644 --- a/java/ql/test/library-tests/frameworks/apache-collections/test.ext.yml +++ b/java/ql/test/library-tests/frameworks/apache-collections/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "newRBWithMapValue", "", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/apache-http/flow.ext.yml b/java/ql/test/library-tests/frameworks/apache-http/flow.ext.yml index ff32ab78646..6e41b8a4e24 100644 --- a/java/ql/test/library-tests/frameworks/apache-http/flow.ext.yml +++ b/java/ql/test/library-tests/frameworks/apache-http/flow.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Client", False, "getURIBuilder_pathDefault", "(Object)", "", "Argument[0].SyntheticField[org.apache.http.client.utils.URIBuilder.path]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ext.yml b/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ext.yml index 153b649a3e6..e711fa15ecc 100644 --- a/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ext.yml +++ b/java/ql/test/library-tests/frameworks/guava/generated/collect/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "newWithElementDefault", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/jdk/java.io/test.ext.yml b/java/ql/test/library-tests/frameworks/jdk/java.io/test.ext.yml index 35050f48ec0..230733b3ebc 100644 --- a/java/ql/test/library-tests/frameworks/jdk/java.io/test.ext.yml +++ b/java/ql/test/library-tests/frameworks/jdk/java.io/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "getThrowable_messageDefault", "(Object)", "", "Argument[0].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/netty/generated/test.ext.yml b/java/ql/test/library-tests/frameworks/netty/generated/test.ext.yml index f6b69f08632..47a199c75f1 100644 --- a/java/ql/test/library-tests/frameworks/netty/generated/test.ext.yml +++ b/java/ql/test/library-tests/frameworks/netty/generated/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "newWithMapValueDefault", "(Object)", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] diff --git a/java/ql/test/library-tests/frameworks/stream/test.ext.yml b/java/ql/test/library-tests/frameworks/stream/test.ext.yml index 4f1cc3e38ac..a304f9542a4 100644 --- a/java/ql/test/library-tests/frameworks/stream/test.ext.yml +++ b/java/ql/test/library-tests/frameworks/stream/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "getElementSpliterator", "(Spliterator)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/library-tests/optional/test.ext.yml b/java/ql/test/library-tests/optional/test.ext.yml index 2aebf3bdb97..24842526782 100644 --- a/java/ql/test/library-tests/optional/test.ext.yml +++ b/java/ql/test/library-tests/optional/test.ext.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/java-tests + pack: codeql/java-all extensible: summaryModel data: - ["generatedtest", "Test", False, "getStreamElement", "", "", "Argument[0].Element", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.expected b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.expected index 95a492fcd12..86f20972e2e 100644 --- a/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.expected +++ b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.expected @@ -23,10 +23,8 @@ edges | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:46:31:46:38 | source(...) : String | | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:48:33:48:40 | source(...) : String | | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:50:27:50:34 | source(...) : String | -| mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:51:27:51:34 | source(...) : String | -| mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:52:34:52:41 | source(...) : String | +| mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:52:27:52:34 | source(...) : String | | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:54:40:54:47 | source(...) : String | -| mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:55:48:55:55 | source(...) : String | | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:56:47:56:54 | source(...) : String | | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:58:40:58:47 | source(...) : String | | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:60:38:60:45 | source(...) : String | @@ -77,10 +75,8 @@ edges | mad/Test.java:46:31:46:38 | source(...) : String | mad/Test.java:46:24:46:38 | (...)... | | mad/Test.java:48:33:48:40 | source(...) : String | mad/Test.java:48:24:48:40 | (...)... | | mad/Test.java:50:27:50:34 | source(...) : String | mad/Test.java:50:20:50:34 | (...)... | -| mad/Test.java:51:27:51:34 | source(...) : String | mad/Test.java:51:20:51:34 | (...)... | -| mad/Test.java:52:34:52:41 | source(...) : String | mad/Test.java:52:20:52:41 | (...)... | +| mad/Test.java:52:27:52:34 | source(...) : String | mad/Test.java:52:20:52:34 | (...)... | | mad/Test.java:54:40:54:47 | source(...) : String | mad/Test.java:54:33:54:47 | (...)... | -| mad/Test.java:55:48:55:55 | source(...) : String | mad/Test.java:55:33:55:55 | (...)... | | mad/Test.java:56:47:56:54 | source(...) : String | mad/Test.java:56:40:56:54 | (...)... | | mad/Test.java:58:40:58:47 | source(...) : String | mad/Test.java:58:33:58:47 | (...)... | | mad/Test.java:60:38:60:45 | source(...) : String | mad/Test.java:60:31:60:45 | (...)... | @@ -161,14 +157,10 @@ nodes | mad/Test.java:48:33:48:40 | source(...) : String | semmle.label | source(...) : String | | mad/Test.java:50:20:50:34 | (...)... | semmle.label | (...)... | | mad/Test.java:50:27:50:34 | source(...) : String | semmle.label | source(...) : String | -| mad/Test.java:51:20:51:34 | (...)... | semmle.label | (...)... | -| mad/Test.java:51:27:51:34 | source(...) : String | semmle.label | source(...) : String | -| mad/Test.java:52:20:52:41 | (...)... | semmle.label | (...)... | -| mad/Test.java:52:34:52:41 | source(...) : String | semmle.label | source(...) : String | +| mad/Test.java:52:20:52:34 | (...)... | semmle.label | (...)... | +| mad/Test.java:52:27:52:34 | source(...) : String | semmle.label | source(...) : String | | mad/Test.java:54:33:54:47 | (...)... | semmle.label | (...)... | | mad/Test.java:54:40:54:47 | source(...) : String | semmle.label | source(...) : String | -| mad/Test.java:55:33:55:55 | (...)... | semmle.label | (...)... | -| mad/Test.java:55:48:55:55 | source(...) : String | semmle.label | source(...) : String | | mad/Test.java:56:40:56:54 | (...)... | semmle.label | (...)... | | mad/Test.java:56:47:56:54 | source(...) : String | semmle.label | source(...) : String | | mad/Test.java:58:33:58:47 | (...)... | semmle.label | (...)... | @@ -273,10 +265,8 @@ subpaths | mad/Test.java:46:24:46:38 | (...)... | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:46:24:46:38 | (...)... | This path depends on a $@. | mad/Test.java:29:16:29:36 | getHostName(...) | user-provided value | | mad/Test.java:48:9:48:41 | new FileReader(...) | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:48:24:48:40 | (...)... | This path depends on a $@. | mad/Test.java:29:16:29:36 | getHostName(...) | user-provided value | | mad/Test.java:50:20:50:34 | (...)... | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:50:20:50:34 | (...)... | This path depends on a $@. | mad/Test.java:29:16:29:36 | getHostName(...) | user-provided value | -| mad/Test.java:51:20:51:34 | (...)... | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:51:20:51:34 | (...)... | This path depends on a $@. | mad/Test.java:29:16:29:36 | getHostName(...) | user-provided value | -| mad/Test.java:52:20:52:41 | (...)... | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:52:20:52:41 | (...)... | This path depends on a $@. | mad/Test.java:29:16:29:36 | getHostName(...) | user-provided value | +| mad/Test.java:52:20:52:34 | (...)... | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:52:20:52:34 | (...)... | This path depends on a $@. | mad/Test.java:29:16:29:36 | getHostName(...) | user-provided value | | mad/Test.java:54:33:54:47 | (...)... | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:54:33:54:47 | (...)... | This path depends on a $@. | mad/Test.java:29:16:29:36 | getHostName(...) | user-provided value | -| mad/Test.java:55:33:55:55 | (...)... | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:55:33:55:55 | (...)... | This path depends on a $@. | mad/Test.java:29:16:29:36 | getHostName(...) | user-provided value | | mad/Test.java:56:40:56:54 | (...)... | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:56:40:56:54 | (...)... | This path depends on a $@. | mad/Test.java:29:16:29:36 | getHostName(...) | user-provided value | | mad/Test.java:58:33:58:47 | (...)... | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:58:33:58:47 | (...)... | This path depends on a $@. | mad/Test.java:29:16:29:36 | getHostName(...) | user-provided value | | mad/Test.java:60:31:60:45 | (...)... | mad/Test.java:29:16:29:36 | getHostName(...) : String | mad/Test.java:60:31:60:45 | (...)... | This path depends on a $@. | mad/Test.java:29:16:29:36 | getHostName(...) | user-provided value | diff --git a/java/ql/test/query-tests/security/CWE-022/semmle/tests/mad/Test.java b/java/ql/test/query-tests/security/CWE-022/semmle/tests/mad/Test.java index daa82c43a04..d936309e7b8 100644 --- a/java/ql/test/query-tests/security/CWE-022/semmle/tests/mad/Test.java +++ b/java/ql/test/query-tests/security/CWE-022/semmle/tests/mad/Test.java @@ -46,13 +46,13 @@ public class Test { new FileReader((File) source()); // "java.io;FileReader;true;FileReader;(String);;Argument[0];read-file;ai-generated" new FileReader((String) source()); - // "java.nio.file;Files;false;copy;;;Argument[0];read-file;manual" - Files.copy((Path) source(), (Path) null); + // "java.nio.file;Files;false;copy;(Path,OutputStream);;Argument[0];read-file;manual" Files.copy((Path) source(), (OutputStream) null); - Files.copy((InputStream) source(), null); - // "java.nio.file;Files;false;copy;;;Argument[1];create-file;manual" + // "java.nio.file;Files;false;copy;(Path,Path,CopyOption[]);;Argument[0];read-file;manual" + Files.copy((Path) source(), (Path) null); + // "java.nio.file;Files;false;copy;(Path,Path,CopyOption[]);;Argument[1];create-file;manual" Files.copy((Path) null, (Path) source()); - Files.copy((Path) null, (OutputStream) source()); + // "java.nio.file;Files;false;copy;(InputStream,Path,CopyOption[]);;Argument[1];create-file;manual" Files.copy((InputStream) null, (Path) source()); // "java.nio.file;Files;false;createDirectories;;;Argument[0];create-file;manual" Files.createDirectories((Path) source()); diff --git a/java/ql/test/query-tests/security/CWE-918/SanitizationTests.java b/java/ql/test/query-tests/security/CWE-918/SanitizationTests.java index 9a65374024c..6a99c619ff3 100644 --- a/java/ql/test/query-tests/security/CWE-918/SanitizationTests.java +++ b/java/ql/test/query-tests/security/CWE-918/SanitizationTests.java @@ -116,6 +116,9 @@ public class SanitizationTests extends HttpServlet { HttpRequest unsafer9 = HttpRequest.newBuilder(new URI(unsafeUri9)).build(); // $ SSRF client.send(unsafer9, null); + String unsafeUri10 = String.format("%s://%s:%s%s", "http", "myserver.com", "80", request.getParameter("baduri10")); + HttpRequest unsafer10 = HttpRequest.newBuilder(new URI(unsafeUri10)).build(); // $ SSRF + client.send(unsafer10, null); } catch (Exception e) { // TODO: handle exception } diff --git a/javascript/downgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/old.dbscheme b/javascript/downgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/old.dbscheme new file mode 100644 index 00000000000..8accf0f930b --- /dev/null +++ b/javascript/downgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/old.dbscheme @@ -0,0 +1,1189 @@ +/*** Standard fragments ***/ + +/*- Files and folders -*/ + +/** + * The location of an element. + * 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( + 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 +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Lines of code -*/ + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +/*- External data -*/ + +/** + * 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 +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- JavaScript-specific part -*/ + +@location = @location_default + +@sourceline = @locatable; + +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 +| 121 = @satisfies_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; + +@type_keyword_operand = @import_declaration | @export_declaration | @import_specifier; + +@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: @type_keyword_operand 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 | @external_module_declaration; + +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 | @add_expr; + +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); + +@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property; + +@optionalchainable = @call_expr | @propaccess; + +isOptionalChaining(int id: @optionalchainable ref); + +/** + * 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 +) + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string 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, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string 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, + 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/javascript/downgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/semmlecode.javascript.dbscheme b/javascript/downgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/semmlecode.javascript.dbscheme new file mode 100644 index 00000000000..4d00210ca57 --- /dev/null +++ b/javascript/downgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/semmlecode.javascript.dbscheme @@ -0,0 +1,1218 @@ +/*** 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 +| 121 = @satisfies_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; + +@type_keyword_operand = @import_declaration | @export_declaration | @import_specifier; + +@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: @type_keyword_operand 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 | @external_module_declaration; + +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 | @add_expr; + +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/downgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/upgrade.properties b/javascript/downgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/upgrade.properties new file mode 100644 index 00000000000..7b75d5de56a --- /dev/null +++ b/javascript/downgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/upgrade.properties @@ -0,0 +1,2 @@ +description: Sync dbscheme fragments +compatibility: full diff --git a/javascript/ql/lib/change-notes/2023-04-30-npm-submodule.md b/javascript/ql/lib/change-notes/2023-04-30-npm-submodule.md new file mode 100644 index 00000000000..5ef95cf7d58 --- /dev/null +++ b/javascript/ql/lib/change-notes/2023-04-30-npm-submodule.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- + +- Added a support of sub modules in `node_modules`. diff --git a/javascript/ql/lib/semmle/javascript/NPM.qll b/javascript/ql/lib/semmle/javascript/NPM.qll index d05045784a6..e1059d94930 100644 --- a/javascript/ql/lib/semmle/javascript/NPM.qll +++ b/javascript/ql/lib/semmle/javascript/NPM.qll @@ -12,8 +12,26 @@ class PackageJson extends JsonObject { this.isTopLevel() } - /** Gets the name of this package. */ - string getPackageName() { result = this.getPropStringValue("name") } + /** + * Gets the name of this package. + * If the package is located under the package `pkg1` and its relative path is `foo/bar`, then the resulting package name will be `pkg1/foo/bar`. + */ + string getPackageName() { + result = this.getPropStringValue("name") + or + exists( + PackageJson parentPkg, Container currentDir, Container parentDir, string parentPkgName, + string pkgNameDiff + | + currentDir = this.getJsonFile().getParentContainer() and + parentDir = parentPkg.getJsonFile().getParentContainer() and + parentPkgName = parentPkg.getPropStringValue("name") and + parentDir.getAChildContainer+() = currentDir and + pkgNameDiff = currentDir.getAbsolutePath().suffix(parentDir.getAbsolutePath().length()) and + not exists(pkgNameDiff.indexOf("/node_modules/")) and + result = parentPkgName + pkgNameDiff + ) + } /** Gets the version of this package. */ string getVersion() { result = this.getPropStringValue("version") } diff --git a/javascript/ql/lib/semmlecode.javascript.dbscheme b/javascript/ql/lib/semmlecode.javascript.dbscheme index 4d00210ca57..8accf0f930b 100644 --- a/javascript/ql/lib/semmlecode.javascript.dbscheme +++ b/javascript/ql/lib/semmlecode.javascript.dbscheme @@ -1,103 +1,75 @@ /*** Standard fragments ***/ -/** Files and folders **/ +/*- Files and folders -*/ -@location = @location_default; +/** + * The location of an element. + * 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( + 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_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 - ); +files( + unique int id: @file, + string name: string ref +); -@sourceline = @locatable; +folders( + unique int id: @folder, + string name: string ref +); -numlines(int element_id: @sourceline ref, - int num_lines: int ref, - int num_code: int ref, - int num_comment: int ref - ); +@container = @file | @folder -files(unique int id: @file, - varchar(900) name: string ref); +containerparent( + int parent: @container ref, + unique int child: @container ref +); -folders(unique int id: @folder, - varchar(900) name: string ref); +/*- Lines of code -*/ +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int 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 **/ +/*- External data -*/ +/** + * 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, - varchar(900) path : string ref, + string path : string ref, int column: int ref, - varchar(900) value : string ref + string value : string ref ); -snapshotDate(unique date snapshotDate : date ref); +/*- Source location prefix -*/ -sourceLocationPrefix(varchar(900) prefix : string ref); +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); -/** Version control data **/ +/*- JavaScript-specific part -*/ -svnentries( - int id : @svnentry, - varchar(500) revision : string ref, - varchar(500) author : string ref, - date revisionDate : date ref, - int changeSize : int ref -); +@location = @location_default -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 ***/ +@sourceline = @locatable; filetype( int file: @file ref, @@ -1046,14 +1018,50 @@ jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref); jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref); -// YAML +@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property; + +@optionalchainable = @call_expr | @propaccess; + +isOptionalChaining(int id: @optionalchainable ref); + +/** + * 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 +) + +/*- 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); + string tag: string ref, + string tostring: string ref); case @yaml_node.kind of 0 = @yaml_scalar_node @@ -1067,41 +1075,41 @@ case @yaml_node.kind of @yaml_node_parent = @yaml_collection_node | @file; yaml_anchors (unique int node: @yaml_node ref, - varchar(900) anchor: string ref); + string anchor: string ref); yaml_aliases (unique int alias: @yaml_alias_node ref, - varchar(900) target: string ref); + string target: string ref); yaml_scalars (unique int scalar: @yaml_scalar_node ref, int style: int ref, - varchar(900) value: string ref); + string value: string ref); yaml_errors (unique int id: @yaml_error, - varchar(900) message: string ref); + string message: string ref); yaml_locations(unique int locatable: @yaml_locatable ref, int location: @location_default ref); @yaml_locatable = @yaml_node | @yaml_error; -/* XML Files */ +/*- XML Files -*/ xmlEncoding( unique int id: @file ref, - varchar(900) encoding: string ref + string encoding: string ref ); xmlDTDs( unique int id: @xmldtd, - varchar(900) root: string ref, - varchar(900) publicId: string ref, - varchar(900) systemId: string ref, + string root: string ref, + string publicId: string ref, + string systemId: string ref, int fileid: @file ref ); xmlElements( unique int id: @xmlelement, - varchar(900) name: string ref, + string name: string ref, int parentid: @xmlparent ref, int idx: int ref, int fileid: @file ref @@ -1110,16 +1118,16 @@ xmlElements( xmlAttrs( unique int id: @xmlattribute, int elementid: @xmlelement ref, - varchar(900) name: string ref, - varchar(3600) value: string ref, + string name: string ref, + string 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, + string prefixName: string ref, + string URI: string ref, int fileid: @file ref ); @@ -1131,14 +1139,14 @@ xmlHasNs( xmlComments( unique int id: @xmlcomment, - varchar(3600) text: string ref, + string text: string ref, int parentid: @xmlparent ref, int fileid: @file ref ); xmlChars( unique int id: @xmlcharacters, - varchar(3600) text: string ref, + string text: string ref, int parentid: @xmlparent ref, int idx: int ref, int isCDATA: int ref, @@ -1155,15 +1163,7 @@ xmllocations( @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 - */ +/*- Configuration files with key value pairs -*/ configs( unique int id: @config @@ -1187,32 +1187,3 @@ configLocations( ); @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/ql/lib/semmlecode.javascript.dbscheme.stats b/javascript/ql/lib/semmlecode.javascript.dbscheme.stats index 7e0b98ea867..c198daf9e67 100644 --- a/javascript/ql/lib/semmlecode.javascript.dbscheme.stats +++ b/javascript/ql/lib/semmlecode.javascript.dbscheme.stats @@ -1,9 +1,5 @@ - -@svnentry -575525 - @location_default @@ -18,14 +14,6 @@ 1590 -@duplication -6210 - - -@similarity -21595 - - @externalDataElement 950 @@ -1507,1214 +1495,6 @@ - -svnentries -575525 - - -id -575525 - - -revision -575525 - - -author -19539 - - -revisionDate -547759 - - -changeSize -1 - - - - -id -revision - - -12 - - -1 -2 -575525 - - - - - - -id -author - - -12 - - -1 -2 -575525 - - - - - - -id -revisionDate - - -12 - - -1 -2 -575525 - - - - - - -id -changeSize - - -12 - - -1 -2 -575525 - - - - - - -revision -id - - -12 - - -1 -2 -575525 - - - - - - -revision -author - - -12 - - -1 -2 -575525 - - - - - - -revision -revisionDate - - -12 - - -1 -2 -575525 - - - - - - -revision -changeSize - - -12 - - -1 -2 -575525 - - - - - - -author -id - - -12 - - -1 -2 -7913 - - -2 -3 -2531 - - -3 -4 -1388 - - -4 -6 -1523 - - -6 -10 -1529 - - -10 -20 -1509 - - -20 -52 -1488 - - -52 -568 -1466 - - -569 -16582 -192 - - - - - - -author -revision - - -12 - - -1 -2 -7913 - - -2 -3 -2531 - - -3 -4 -1388 - - -4 -6 -1523 - - -6 -10 -1529 - - -10 -20 -1509 - - -20 -52 -1488 - - -52 -568 -1466 - - -569 -16582 -192 - - - - - - -author -revisionDate - - -12 - - -1 -2 -7996 - - -2 -3 -2509 - - -3 -4 -1379 - - -4 -6 -1520 - - -6 -10 -1529 - - -10 -20 -1507 - - -20 -52 -1474 - - -52 -662 -1466 - - -663 -16573 -159 - - - - - - -author -changeSize - - -12 - - -1 -2 -19539 - - - - - - -revisionDate -id - - -12 - - -1 -2 -531878 - - -2 -100 -15881 - - - - - - -revisionDate -revision - - -12 - - -1 -2 -531878 - - -2 -100 -15881 - - - - - - -revisionDate -author - - -12 - - -1 -2 -542505 - - -2 -17 -5254 - - - - - - -revisionDate -changeSize - - -12 - - -1 -2 -547759 - - - - - - -changeSize -id - - -12 - - -575525 -575526 -1 - - - - - - -changeSize -revision - - -12 - - -575525 -575526 -1 - - - - - - -changeSize -author - - -12 - - -19539 -19540 -1 - - - - - - -changeSize -revisionDate - - -12 - - -547759 -547760 -1 - - - - - - - - -svnaffectedfiles -1314068 - - -id -531628 - - -file -90924 - - -action -1 - - - - -id -file - - -12 - - -1 -2 -337698 - - -2 -3 -77525 - - -3 -4 -43024 - - -4 -7 -46689 - - -7 -16635 -26692 - - - - - - -id -action - - -12 - - -1 -2 -531628 - - - - - - -file -id - - -12 - - -1 -2 -11819 - - -2 -3 -18230 - - -3 -4 -9501 - - -4 -5 -6656 - - -5 -6 -5012 - - -6 -8 -7103 - - -8 -11 -6788 - - -11 -16 -6996 - - -16 -26 -7180 - - -26 -54 -6824 - - -54 -3572 -4815 - - - - - - -file -action - - -12 - - -1 -2 -90924 - - - - - - -action -id - - -12 - - -531628 -531629 -1 - - - - - - -action -file - - -12 - - -90924 -90925 -1 - - - - - - - - -svnentrymsg -575525 - - -id -575525 - - -message -568305 - - - - -id -message - - -12 - - -1 -2 -575525 - - - - - - -message -id - - -12 - - -1 -2 -565381 - - -2 -142 -2924 - - - - - - - - -svnchurn -46790 - - -commit -22361 - - -file -16124 - - -addedLines -910 - - -deletedLines -787 - - - - -commit -file - - -12 - - -1 -2 -15208 - - -2 -3 -3101 - - -3 -4 -1746 - - -4 -8 -1774 - - -8 -246 -532 - - - - - - -commit -addedLines - - -12 - - -1 -2 -16074 - - -2 -3 -3323 - - -3 -4 -1561 - - -4 -118 -1403 - - - - - - -commit -deletedLines - - -12 - - -1 -2 -16799 - - -2 -3 -3286 - - -3 -5 -1763 - - -5 -113 -513 - - - - - - -file -commit - - -12 - - -1 -2 -8618 - - -2 -3 -2956 - - -3 -4 -1426 - - -4 -6 -1364 - - -6 -12 -1210 - - -12 -448 -550 - - - - - - -file -addedLines - - -12 - - -1 -2 -9240 - - -2 -3 -3129 - - -3 -4 -1393 - - -4 -6 -1239 - - -6 -59 -1123 - - - - - - -file -deletedLines - - -12 - - -1 -2 -9525 - - -2 -3 -3192 - - -3 -4 -1401 - - -4 -7 -1387 - - -7 -70 -619 - - - - - - -addedLines -commit - - -12 - - -1 -2 -446 - - -2 -3 -133 - - -3 -4 -70 - - -4 -6 -68 - - -6 -12 -70 - - -12 -57 -69 - - -57 -6874 -54 - - - - - - -addedLines -file - - -12 - - -1 -2 -445 - - -2 -3 -132 - - -3 -4 -69 - - -4 -6 -68 - - -6 -12 -73 - - -12 -58 -69 - - -58 -6663 -54 - - - - - - -addedLines -deletedLines - - -12 - - -1 -2 -621 - - -2 -3 -96 - - -3 -7 -81 - - -7 -34 -70 - - -34 -727 -42 - - - - - - -deletedLines -commit - - -12 - - -1 -2 -439 - - -2 -3 -116 - - -3 -4 -48 - - -4 -8 -67 - - -8 -28 -60 - - -28 -6794 -57 - - - - - - -deletedLines -file - - -12 - - -1 -2 -437 - - -2 -3 -113 - - -3 -4 -49 - - -4 -7 -61 - - -7 -19 -60 - - -19 -770 -60 - - -985 -7318 -7 - - - - - - -deletedLines -addedLines - - -12 - - -1 -2 -545 - - -2 -3 -72 - - -3 -7 -69 - - -7 -30 -60 - - -30 -871 -41 - - - - - - - locations_default @@ -5018,2042 +3798,6 @@ -duplicateCode -id -6210 - - -id -6210 - - -relativePath -932 - - -equivClass -2355 - - - - -id -relativePath - - -12 - - -1 -2 -6210 - - - - - - -id -equivClass - - -12 - - -1 -2 -6210 - - - - - - -relativePath -id - - -12 - - -1 -2 -377 - - -2 -3 -182 - - -3 -4 -92 - - -4 -5 -78 - - -5 -9 -84 - - -9 -18 -70 - - -18 -914 -49 - - - - - - -relativePath -equivClass - - -12 - - -1 -2 -439 - - -2 -3 -147 - - -3 -4 -105 - - -4 -6 -85 - - -6 -10 -75 - - -10 -60 -70 - - -63 -355 -11 - - - - - - -equivClass -id - - -12 - - -1 -2 -6 - - -2 -3 -1669 - - -3 -4 -311 - - -4 -5 -166 - - -5 -9 -183 - - -9 -11 -20 - - - - - - -equivClass -relativePath - - -12 - - -1 -2 -825 - - -2 -3 -1111 - - -3 -4 -202 - - -4 -7 -177 - - -7 -11 -40 - - - - - - - - -similarCode -id -21595 - - -id -21595 - - -relativePath -1742 - - -equivClass -7221 - - - - -id -relativePath - - -12 - - -1 -2 -21595 - - - - - - -id -equivClass - - -12 - - -1 -2 -21595 - - - - - - -relativePath -id - - -12 - - -1 -2 -454 - - -2 -3 -351 - - -3 -4 -143 - - -4 -5 -141 - - -5 -6 -115 - - -6 -8 -126 - - -8 -12 -147 - - -12 -23 -139 - - -23 -5898 -126 - - - - - - -relativePath -equivClass - - -12 - - -1 -2 -632 - - -2 -3 -276 - - -3 -4 -200 - - -4 -5 -144 - - -5 -6 -94 - - -6 -9 -158 - - -9 -15 -139 - - -15 -1799 -99 - - - - - - -equivClass -id - - -12 - - -1 -2 -54 - - -2 -3 -4290 - - -3 -4 -1200 - - -4 -5 -662 - - -5 -7 -583 - - -7 -11 -432 - - - - - - -equivClass -relativePath - - -12 - - -1 -2 -4536 - - -2 -3 -1858 - - -3 -5 -611 - - -5 -11 -216 - - - - - - - - -tokens -5806732 - - -id -27805 - - -offset -56799 - - -beginLine -167308 - - -beginColumn -1853 - - -endLine -167308 - - -endColumn -1875 - - - - -id -offset - - -12 - - -100 -101 -2031 - - -101 -102 -1683 - - -102 -103 -1387 - - -103 -105 -2060 - - -105 -108 -2278 - - -108 -111 -2079 - - -111 -116 -2106 - - -116 -124 -2280 - - -124 -135 -2235 - - -135 -152 -2091 - - -152 -180 -2104 - - -180 -221 -2095 - - -221 -380 -2088 - - -381 -56800 -1288 - - - - - - -id -beginLine - - -12 - - -2 -10 -2063 - - -10 -12 -1754 - - -12 -14 -2423 - - -14 -15 -1299 - - -15 -16 -1542 - - -16 -17 -1745 - - -17 -18 -1470 - - -18 -19 -1471 - - -19 -21 -2512 - - -21 -23 -2101 - - -23 -26 -2365 - - -26 -30 -2157 - - -30 -39 -2231 - - -39 -102 -2089 - - -102 -11362 -583 - - - - - - -id -beginColumn - - -12 - - -4 -20 -2045 - - -20 -23 -2118 - - -23 -27 -2074 - - -27 -32 -2493 - - -32 -37 -2166 - - -37 -42 -2474 - - -42 -46 -2394 - - -46 -49 -2000 - - -49 -52 -2047 - - -52 -56 -2169 - - -56 -62 -2317 - - -62 -73 -2113 - - -73 -528 -1395 - - - - - - -id -endLine - - -12 - - -2 -10 -2059 - - -10 -12 -1756 - - -12 -14 -2425 - - -14 -15 -1299 - - -15 -16 -1519 - - -16 -17 -1758 - - -17 -18 -1476 - - -18 -19 -1472 - - -19 -21 -2515 - - -21 -23 -2101 - - -23 -26 -2362 - - -26 -30 -2158 - - -30 -39 -2225 - - -39 -101 -2089 - - -101 -11362 -591 - - - - - - -id -endColumn - - -12 - - -4 -21 -2155 - - -21 -24 -2138 - - -24 -30 -2470 - - -30 -35 -2169 - - -35 -41 -2390 - - -41 -45 -2025 - - -45 -49 -2451 - - -49 -52 -2070 - - -52 -55 -2094 - - -55 -59 -2200 - - -59 -65 -2223 - - -65 -76 -2124 - - -76 -528 -1296 - - - - - - -offset -id - - -12 - - -4 -13 -2042 - - -16 -17 -37935 - - -18 -19 -3184 - - -20 -21 -3634 - - -22 -31 -4534 - - -32 -276 -4265 - - -277 -27806 -1205 - - - - - - -offset -beginLine - - -12 - - -4 -5 -2040 - - -8 -9 -37937 - - -10 -11 -3184 - - -12 -13 -3634 - - -13 -18 -4342 - - -18 -131 -4269 - - -131 -10163 -1393 - - - - - - -offset -beginColumn - - -12 - - -1 -2 -40044 - - -2 -3 -4434 - - -3 -4 -3310 - - -4 -11 -4641 - - -11 -152 -4260 - - -152 -317 -110 - - - - - - -offset -endLine - - -12 - - -4 -5 -2040 - - -8 -9 -37937 - - -10 -11 -3184 - - -12 -13 -3634 - - -13 -18 -4342 - - -18 -131 -4269 - - -131 -10163 -1393 - - - - - - -offset -endColumn - - -12 - - -1 -2 -40085 - - -2 -3 -3591 - - -3 -4 -3628 - - -4 -9 -4339 - - -9 -62 -4261 - - -62 -326 -895 - - - - - - -beginLine -id - - -12 - - -1 -2 -15579 - - -2 -3 -110688 - - -3 -4 -8065 - - -4 -6 -13975 - - -6 -13 -12842 - - -13 -1717 -6159 - - - - - - -beginLine -offset - - -12 - - -1 -5 -9257 - - -5 -6 -90442 - - -6 -9 -13474 - - -9 -12 -11463 - - -12 -19 -13584 - - -19 -33 -13154 - - -33 -89 -12558 - - -89 -646 -3376 - - - - - - -beginLine -beginColumn - - -12 - - -1 -4 -12049 - - -4 -5 -4348 - - -5 -6 -101350 - - -6 -9 -13619 - - -9 -11 -8078 - - -11 -15 -13132 - - -15 -50 -12597 - - -50 -581 -2135 - - - - - - -beginLine -endLine - - -12 - - -1 -2 -167235 - - -2 -5 -73 - - - - - - -beginLine -endColumn - - -12 - - -1 -4 -12051 - - -4 -5 -4298 - - -5 -6 -101396 - - -6 -9 -13614 - - -9 -11 -8126 - - -11 -15 -13109 - - -15 -51 -12592 - - -51 -589 -2122 - - - - - - -beginColumn -id - - -12 - - -1 -2 -588 - - -2 -3 -318 - - -3 -6 -151 - - -6 -12 -143 - - -12 -24 -145 - - -24 -36 -142 - - -36 -86 -139 - - -87 -1324 -139 - - -1373 -23504 -88 - - - - - - -beginColumn -offset - - -12 - - -1 -2 -590 - - -2 -3 -319 - - -3 -5 -144 - - -5 -9 -139 - - -9 -13 -155 - - -13 -21 -145 - - -21 -59 -142 - - -59 -458 -139 - - -546 -15972 -80 - - - - - - -beginColumn -beginLine - - -12 - - -1 -2 -1018 - - -2 -3 -119 - - -3 -6 -157 - - -6 -13 -146 - - -13 -24 -139 - - -24 -141 -140 - - -145 -127333 -134 - - - - - - -beginColumn -endLine - - -12 - - -1 -2 -1018 - - -2 -3 -119 - - -3 -6 -157 - - -6 -13 -146 - - -13 -24 -139 - - -24 -141 -140 - - -145 -127333 -134 - - - - - - -beginColumn -endColumn - - -12 - - -1 -2 -1101 - - -2 -3 -190 - - -3 -4 -146 - - -4 -7 -164 - - -7 -19 -151 - - -19 -169 -101 - - - - - - -endLine -id - - -12 - - -1 -2 -15579 - - -2 -3 -110688 - - -3 -4 -8065 - - -4 -6 -13975 - - -6 -13 -12842 - - -13 -1717 -6159 - - - - - - -endLine -offset - - -12 - - -1 -5 -9257 - - -5 -6 -90442 - - -6 -9 -13474 - - -9 -12 -11463 - - -12 -19 -13584 - - -19 -33 -13154 - - -33 -89 -12558 - - -89 -646 -3376 - - - - - - -endLine -beginLine - - -12 - - -1 -2 -167235 - - -2 -5 -73 - - - - - - -endLine -beginColumn - - -12 - - -1 -4 -12049 - - -4 -5 -4348 - - -5 -6 -101350 - - -6 -9 -13619 - - -9 -11 -8078 - - -11 -15 -13132 - - -15 -50 -12597 - - -50 -581 -2135 - - - - - - -endLine -endColumn - - -12 - - -1 -4 -12051 - - -4 -5 -4298 - - -5 -6 -101396 - - -6 -9 -13614 - - -9 -11 -8126 - - -11 -15 -13111 - - -15 -51 -12590 - - -51 -589 -2122 - - - - - - -endColumn -id - - -12 - - -1 -2 -594 - - -2 -3 -327 - - -3 -6 -150 - - -6 -12 -141 - - -12 -23 -144 - - -23 -36 -142 - - -36 -81 -142 - - -83 -1013 -141 - - -1068 -22526 -94 - - - - - - -endColumn -offset - - -12 - - -1 -2 -594 - - -2 -3 -331 - - -3 -5 -148 - - -5 -9 -147 - - -9 -14 -161 - - -14 -23 -151 - - -23 -72 -143 - - -72 -1221 -141 - - -1224 -16225 -59 - - - - - - -endColumn -beginLine - - -12 - - -1 -2 -1020 - - -2 -3 -140 - - -3 -6 -151 - - -6 -13 -146 - - -13 -25 -143 - - -25 -158 -142 - - -160 -129820 -133 - - - - - - -endColumn -beginColumn - - -12 - - -1 -2 -1097 - - -2 -3 -214 - - -3 -4 -119 - - -4 -6 -146 - - -6 -14 -141 - - -14 -56 -141 - - -57 -66 -17 - - - - - - -endColumn -endLine - - -12 - - -1 -2 -1020 - - -2 -3 -140 - - -3 -6 -151 - - -6 -13 -146 - - -13 -25 -143 - - -25 -158 -142 - - -160 -129820 -133 - - - - - - - - externalData 5684 @@ -7370,18 +4114,6 @@ -snapshotDate -snapshotDate -1 - - -snapshotDate -1 - - - - - sourceLocationPrefix 1 diff --git a/javascript/ql/lib/upgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/old.dbscheme b/javascript/ql/lib/upgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/old.dbscheme new file mode 100644 index 00000000000..4d00210ca57 --- /dev/null +++ b/javascript/ql/lib/upgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/old.dbscheme @@ -0,0 +1,1218 @@ +/*** 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 +| 121 = @satisfies_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; + +@type_keyword_operand = @import_declaration | @export_declaration | @import_specifier; + +@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: @type_keyword_operand 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 | @external_module_declaration; + +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 | @add_expr; + +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/ql/lib/upgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/semmlecode.javascript.dbscheme b/javascript/ql/lib/upgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/semmlecode.javascript.dbscheme new file mode 100644 index 00000000000..8accf0f930b --- /dev/null +++ b/javascript/ql/lib/upgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/semmlecode.javascript.dbscheme @@ -0,0 +1,1189 @@ +/*** Standard fragments ***/ + +/*- Files and folders -*/ + +/** + * The location of an element. + * 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( + 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 +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Lines of code -*/ + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +/*- External data -*/ + +/** + * 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 +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- JavaScript-specific part -*/ + +@location = @location_default + +@sourceline = @locatable; + +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 +| 121 = @satisfies_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; + +@type_keyword_operand = @import_declaration | @export_declaration | @import_specifier; + +@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: @type_keyword_operand 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 | @external_module_declaration; + +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 | @add_expr; + +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); + +@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property; + +@optionalchainable = @call_expr | @propaccess; + +isOptionalChaining(int id: @optionalchainable ref); + +/** + * 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 +) + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string 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, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string 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, + 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/javascript/ql/lib/upgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/upgrade.properties b/javascript/ql/lib/upgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/upgrade.properties new file mode 100644 index 00000000000..7e07865bedc --- /dev/null +++ b/javascript/ql/lib/upgrades/4d00210ca570d55c4833af11d3372b774dbc63f2/upgrade.properties @@ -0,0 +1,11 @@ +description: Sync dbscheme fragments +compatibility: full + +duplicateCode.rel: delete +similarCode.rel: delete +tokens.rel: delete +snapshotDate.rel: delete +svnentries.rel: delete +svnaffectedfiles.rel: delete +svnentrymsg.rel: delete +svnchurn.rel: delete diff --git a/javascript/ql/src/Performance/PolynomialReDoS.qhelp b/javascript/ql/src/Performance/PolynomialReDoS.qhelp index 210a4a8a84b..2a96c60edd8 100644 --- a/javascript/ql/src/Performance/PolynomialReDoS.qhelp +++ b/javascript/ql/src/Performance/PolynomialReDoS.qhelp @@ -15,8 +15,7 @@

- text.replace(/^\s+|\s+$/g, ''); // BAD - +text.replace(/^\s+|\s+$/g, ''); // BAD

@@ -71,8 +70,7 @@

- /^0\.\d+E?\d+$/.test(str) // BAD - +/^0\.\d+E?\d+$/.test(str) // BAD

@@ -103,6 +101,33 @@ + +

+ Sometimes it is unclear how a regular expression can be rewritten to + avoid the problem. In such cases, it often suffices to limit the + length of the input string. For instance, the following + regular expression is used to match numbers, and on some non-number + inputs it can have quadratic time complexity: +

+ + +/^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/.test(str) // BAD + +

+ It is not immediately obvious how to rewrite this regular expression + to avoid the problem. However, you can mitigate performance issues by limiting the length + to 1000 characters, which will always finish in a reasonable amount + of time. +

+ + +if (str.length > 1000) { + throw new Error("Input too long"); +} + +/^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/.test(str) + + diff --git a/javascript/ql/test/library-tests/NPM/src/node_modules/parent-module/main.js b/javascript/ql/test/library-tests/NPM/src/node_modules/parent-module/main.js new file mode 100644 index 00000000000..8871fb179ac --- /dev/null +++ b/javascript/ql/test/library-tests/NPM/src/node_modules/parent-module/main.js @@ -0,0 +1 @@ +module.exports = "parent"; diff --git a/javascript/ql/test/library-tests/NPM/src/node_modules/parent-module/package.json b/javascript/ql/test/library-tests/NPM/src/node_modules/parent-module/package.json new file mode 100644 index 00000000000..44481e79cba --- /dev/null +++ b/javascript/ql/test/library-tests/NPM/src/node_modules/parent-module/package.json @@ -0,0 +1,4 @@ +{ + "name": "parent-module", + "main": "main.js" +} \ No newline at end of file diff --git a/javascript/ql/test/library-tests/NPM/src/node_modules/parent-module/sub-module/main.js b/javascript/ql/test/library-tests/NPM/src/node_modules/parent-module/sub-module/main.js new file mode 100644 index 00000000000..0bf6641bb0a --- /dev/null +++ b/javascript/ql/test/library-tests/NPM/src/node_modules/parent-module/sub-module/main.js @@ -0,0 +1 @@ +module.exports = "sub"; diff --git a/javascript/ql/test/library-tests/NPM/src/node_modules/parent-module/sub-module/package.json b/javascript/ql/test/library-tests/NPM/src/node_modules/parent-module/sub-module/package.json new file mode 100644 index 00000000000..a60376465b8 --- /dev/null +++ b/javascript/ql/test/library-tests/NPM/src/node_modules/parent-module/sub-module/package.json @@ -0,0 +1,3 @@ +{ + "main": "main.js" +} \ No newline at end of file diff --git a/javascript/ql/test/library-tests/NPM/src/test-submodule.js b/javascript/ql/test/library-tests/NPM/src/test-submodule.js new file mode 100644 index 00000000000..f40d70a3aa1 --- /dev/null +++ b/javascript/ql/test/library-tests/NPM/src/test-submodule.js @@ -0,0 +1,2 @@ +require("parent-module"); +require("parent-module/sub-module"); diff --git a/javascript/ql/test/library-tests/NPM/tests.expected b/javascript/ql/test/library-tests/NPM/tests.expected index 48691fe0117..a75c705be26 100644 --- a/javascript/ql/test/library-tests/NPM/tests.expected +++ b/javascript/ql/test/library-tests/NPM/tests.expected @@ -8,6 +8,8 @@ importedFile | src/node_modules/nested/tst3.js:1:1:1:29 | require ... odule') | src/node_modules/third-party-module/fancy.js:0:0:0:0 | src/node_modules/third-party-module/fancy.js | | src/node_modules/nested/tst3.js:2:1:2:12 | require('a') | src/node_modules/nested/node_modules/a/index.js:0:0:0:0 | src/node_modules/nested/node_modules/a/index.js | | src/node_modules/tst2.js:1:1:1:38 | require ... cy.js') | src/node_modules/third-party-module/fancy.js:0:0:0:0 | src/node_modules/third-party-module/fancy.js | +| src/test-submodule.js:1:1:1:24 | require ... odule") | src/node_modules/parent-module/main.js:0:0:0:0 | src/node_modules/parent-module/main.js | +| src/test-submodule.js:2:1:2:35 | require ... odule") | src/node_modules/parent-module/sub-module/main.js:0:0:0:0 | src/node_modules/parent-module/sub-module/main.js | | src/tst2.js:1:1:1:12 | require(".") | src/index.js:0:0:0:0 | src/index.js | | src/tst.js:1:1:1:38 | require ... cy.js') | src/node_modules/third-party-module/fancy.js:0:0:0:0 | src/node_modules/third-party-module/fancy.js | | src/tst.js:2:1:2:37 | require ... ckage') | src/node_modules/third-party-module/package.json:0:0:0:0 | src/node_modules/third-party-module/package.json | @@ -16,18 +18,24 @@ importedModule | src/node_modules/nested/tst3.js:1:1:1:29 | require ... odule') | src/node_modules/third-party-module/fancy.js:1:1:4:0 | | | src/node_modules/nested/tst3.js:2:1:2:12 | require('a') | src/node_modules/nested/node_modules/a/index.js:1:1:1:25 | | | src/node_modules/tst2.js:1:1:1:38 | require ... cy.js') | src/node_modules/third-party-module/fancy.js:1:1:4:0 | | +| src/test-submodule.js:1:1:1:24 | require ... odule") | src/node_modules/parent-module/main.js:1:1:2:0 | | +| src/test-submodule.js:2:1:2:35 | require ... odule") | src/node_modules/parent-module/sub-module/main.js:1:1:2:0 | | | src/tst2.js:1:1:1:12 | require(".") | src/index.js:1:1:4:0 | | | src/tst.js:1:1:1:38 | require ... cy.js') | src/node_modules/third-party-module/fancy.js:1:1:4:0 | | modules | src | test-package | src/index.js:1:1:4:0 | | | src | test-package | src/lib/tst2.js:1:1:1:14 | | | src | test-package | src/lib/tst.js:1:1:4:0 | | +| src | test-package | src/test-submodule.js:1:1:3:0 | | | src | test-package | src/tst2.js:1:1:1:13 | | | src | test-package | src/tst.js:1:1:2:38 | | | src/node_modules/b | b | src/node_modules/b/lib/index.js:1:1:2:0 | | | src/node_modules/b | b | src/node_modules/b/lib/util.ts:1:1:2:0 | | | src/node_modules/c | c | src/node_modules/c/src/index.js:1:1:2:0 | | | src/node_modules/d | d | src/node_modules/d/main.js:1:1:2:0 | | +| src/node_modules/parent-module | parent-module | src/node_modules/parent-module/main.js:1:1:2:0 | | +| src/node_modules/parent-module | parent-module | src/node_modules/parent-module/sub-module/main.js:1:1:2:0 | | +| src/node_modules/parent-module/sub-module | parent-module/sub-module | src/node_modules/parent-module/sub-module/main.js:1:1:2:0 | | | src/node_modules/third-party-module | third-party-module | src/node_modules/third-party-module/fancy.js:1:1:4:0 | | npm | src/node_modules/third-party-module/package.json:1:1:5:1 | {\\n "na ... y.js"\\n} | third-party-module | 23.4.0 | @@ -36,12 +44,16 @@ getMainModule | src/node_modules/b/package.json:1:1:4:1 | {\\n "na ... "lib"\\n} | b | src/node_modules/b/lib/index.js:1:1:2:0 | | | src/node_modules/c/package.json:1:1:4:1 | {\\n "na ... src/"\\n} | c | src/node_modules/c/src/index.js:1:1:2:0 | | | src/node_modules/d/package.json:1:1:4:1 | {\\n "na ... main"\\n} | d | src/node_modules/d/main.js:1:1:2:0 | | +| src/node_modules/parent-module/package.json:1:1:4:1 | {\\n "na ... n.js"\\n} | parent-module | src/node_modules/parent-module/main.js:1:1:2:0 | | +| src/node_modules/parent-module/sub-module/package.json:1:1:3:1 | {\\n "ma ... n.js"\\n} | parent-module/sub-module | src/node_modules/parent-module/sub-module/main.js:1:1:2:0 | | | src/node_modules/third-party-module/package.json:1:1:5:1 | {\\n "na ... y.js"\\n} | third-party-module | src/node_modules/third-party-module/fancy.js:1:1:4:0 | | | src/package.json:1:1:20:1 | {\\n "na ... "\\n }\\n} | test-package | src/index.js:1:1:4:0 | | packageJson | src/node_modules/b/package.json:1:1:4:1 | {\\n "na ... "lib"\\n} | | src/node_modules/c/package.json:1:1:4:1 | {\\n "na ... src/"\\n} | | src/node_modules/d/package.json:1:1:4:1 | {\\n "na ... main"\\n} | +| src/node_modules/parent-module/package.json:1:1:4:1 | {\\n "na ... n.js"\\n} | +| src/node_modules/parent-module/sub-module/package.json:1:1:3:1 | {\\n "ma ... n.js"\\n} | | src/node_modules/third-party-module/package.json:1:1:5:1 | {\\n "na ... y.js"\\n} | | src/package.json:1:1:20:1 | {\\n "na ... "\\n }\\n} | dependencyInfo @@ -53,5 +65,6 @@ dependencyInfo | src/package.json:11:20:11:37 | "1.2.3-alpha.beta" | something | unknown | | src/package.json:12:14:12:57 | "! garb ... arse %" | foo | unknown | | src/package.json:15:16:15:20 | "1.0" | mocha | 1.0 | +| src/test-submodule.js:1:1:3:0 | | test-package | 0.1.0 | | src/tst2.js:1:1:1:13 | | test-package | 0.1.0 | | src/tst.js:1:1:2:38 | | test-package | 0.1.0 | diff --git a/javascript/ql/test/tutorials/Introducing the JavaScript libraries/query12.qll b/javascript/ql/test/tutorials/Introducing the JavaScript libraries/query12.qll index 7f99c4e3674..d39a812e5bb 100644 --- a/javascript/ql/test/tutorials/Introducing the JavaScript libraries/query12.qll +++ b/javascript/ql/test/tutorials/Introducing the JavaScript libraries/query12.qll @@ -4,7 +4,7 @@ query predicate test_query12(MethodCallExpr send) { exists(SimpleParameter res, DataFlow::Node resNode | res.getName() = "res" and resNode = DataFlow::parameterNode(res) and - resNode.getASuccessor() = DataFlow::valueNode(send.getReceiver()) and + resNode.getASuccessor+() = DataFlow::valueNode(send.getReceiver()) and send.getMethodName() = "send" | any() diff --git a/javascript/ql/test/tutorials/Introducing the JavaScript libraries/tests.expected b/javascript/ql/test/tutorials/Introducing the JavaScript libraries/tests.expected index bbec34be602..1eb7f5897cc 100644 --- a/javascript/ql/test/tutorials/Introducing the JavaScript libraries/tests.expected +++ b/javascript/ql/test/tutorials/Introducing the JavaScript libraries/tests.expected @@ -21,6 +21,7 @@ test_query11 | tst.js:31:18:31:18 | x | Dead store of local variable. | | tst.js:38:7:38:23 | password = "blah" | Dead store of local variable. | test_query12 +| tst.js:42:3:42:12 | res.send() | test_query20 test_query3 | tst.js:27:1:27:4 |