diff --git a/change-notes/1.26/analysis-cpp.md b/change-notes/1.26/analysis-cpp.md index 8659230aaa0..82d74e5d6b4 100644 --- a/change-notes/1.26/analysis-cpp.md +++ b/change-notes/1.26/analysis-cpp.md @@ -20,8 +20,10 @@ The following changes in version 1.26 affect C/C++ analysis in all applications. ## Changes to libraries +* The QL class `Block`, denoting the `{ ... }` statement, is renamed to `BlockStmt`. * The models library now models many taint flows through `std::array`, `std::vector`, `std::deque`, `std::list` and `std::forward_list`. * The models library now models many more taint flows through `std::string`. +* The models library now models some taint flows through `std::ostream`. * The models library now models some taint flows through `std::shared_ptr`, `std::unique_ptr`, `std::make_shared` and `std::make_unique`. * The `SimpleRangeAnalysis` library now supports multiplications of the form `e1 * e2` and `x *= e2` when `e1` and `e2` are unsigned or constant. diff --git a/change-notes/1.26/analysis-java.md b/change-notes/1.26/analysis-java.md new file mode 100644 index 00000000000..cf87be2d8b8 --- /dev/null +++ b/change-notes/1.26/analysis-java.md @@ -0,0 +1,21 @@ +# Improvements to Java analysis + +The following changes in version 1.26 affect Java analysis in all applications. + +## General improvements + +## New queries + +| **Query** | **Tags** | **Purpose** | +|-----------------------------|-----------|--------------------------------------------------------------------| + + +## Changes to existing queries + +| **Query** | **Expected impact** | **Change** | +|------------------------------|------------------------|-----------------------------------| + + +## Changes to libraries + +* The QL class `Block`, denoting the `{ ... }` statement, is renamed to `BlockStmt`. diff --git a/change-notes/1.26/analysis-javascript.md b/change-notes/1.26/analysis-javascript.md index 09aba390abb..06c8b5dc5e5 100644 --- a/change-notes/1.26/analysis-javascript.md +++ b/change-notes/1.26/analysis-javascript.md @@ -30,6 +30,7 @@ | Incomplete URL substring sanitization (`js/incomplete-url-substring-sanitization`) | More results | This query now recognizes additional URLs when the substring check is an inclusion check. | | Ambiguous HTML id attribute (`js/duplicate-html-id`) | Results no longer shown | Precision tag reduced to "low". The query is no longer run by default. | | Unused loop iteration variable (`js/unused-loop-variable`) | Fewer results | This query no longer flags variables in a destructuring array assignment that are not the last variable in the destructed array. | +| Unsafe shell command constructed from library input (`js/shell-command-constructed-from-input`) | More results | This query now recognizes more commands where colon, dash, and underscore are used. | | Unsafe jQuery plugin (`js/unsafe-jquery-plugin`) | More results | This query now detects more unsafe uses of nested option properties. | diff --git a/cpp/ql/examples/snippets/emptyblock.ql b/cpp/ql/examples/snippets/emptyblock.ql index 2f1e198fc59..46ee35a6864 100644 --- a/cpp/ql/examples/snippets/emptyblock.ql +++ b/cpp/ql/examples/snippets/emptyblock.ql @@ -9,6 +9,6 @@ import cpp -from Block blk +from BlockStmt blk where blk.getNumStmt() = 0 select blk diff --git a/cpp/ql/examples/snippets/emptythen.ql b/cpp/ql/examples/snippets/emptythen.ql index 0ae060838d2..7e31ac7e4e1 100644 --- a/cpp/ql/examples/snippets/emptythen.ql +++ b/cpp/ql/examples/snippets/emptythen.ql @@ -13,5 +13,5 @@ import cpp from IfStmt i -where i.getThen().(Block).getNumStmt() = 0 +where i.getThen().(BlockStmt).getNumStmt() = 0 select i diff --git a/cpp/ql/examples/snippets/singletonblock.ql b/cpp/ql/examples/snippets/singletonblock.ql index a265d84a0da..265bc85927c 100644 --- a/cpp/ql/examples/snippets/singletonblock.ql +++ b/cpp/ql/examples/snippets/singletonblock.ql @@ -8,6 +8,6 @@ import cpp -from Block b +from BlockStmt b where b.getNumStmt() = 1 select b diff --git a/cpp/ql/src/Best Practices/BlockWithTooManyStatements.ql b/cpp/ql/src/Best Practices/BlockWithTooManyStatements.ql index cfa19710934..97481bc8b03 100644 --- a/cpp/ql/src/Best Practices/BlockWithTooManyStatements.ql +++ b/cpp/ql/src/Best Practices/BlockWithTooManyStatements.ql @@ -14,7 +14,7 @@ import cpp class ComplexStmt extends Stmt { ComplexStmt() { - exists(Block body | + exists(BlockStmt body | body = this.(Loop).getStmt() or body = this.(SwitchStmt).getStmt() | @@ -24,7 +24,7 @@ class ComplexStmt extends Stmt { } } -from Block b, int n, ComplexStmt complexStmt +from BlockStmt b, int n, ComplexStmt complexStmt where n = strictcount(ComplexStmt s | s = b.getAStmt()) and n > 3 and diff --git a/cpp/ql/src/Best Practices/Hiding/DeclarationHidesVariable.ql b/cpp/ql/src/Best Practices/Hiding/DeclarationHidesVariable.ql index 675fd7178d8..d10d346c513 100644 --- a/cpp/ql/src/Best Practices/Hiding/DeclarationHidesVariable.ql +++ b/cpp/ql/src/Best Practices/Hiding/DeclarationHidesVariable.ql @@ -17,7 +17,7 @@ where shadowing(lv1, lv2) and not lv1.isCompilerGenerated() and not lv2.isCompilerGenerated() and - not lv1.getParentScope().(Block).isInMacroExpansion() and - not lv2.getParentScope().(Block).isInMacroExpansion() + not lv1.getParentScope().(BlockStmt).isInMacroExpansion() and + not lv2.getParentScope().(BlockStmt).isInMacroExpansion() select lv1, "Variable " + lv1.getName() + " hides another variable of the same name (on $@).", lv2, "line " + lv2.getLocation().getStartLine().toString() diff --git a/cpp/ql/src/Best Practices/Likely Errors/EmptyBlock.ql b/cpp/ql/src/Best Practices/Likely Errors/EmptyBlock.ql index 9880a3ae2a0..9fa8c4e5e3f 100644 --- a/cpp/ql/src/Best Practices/Likely Errors/EmptyBlock.ql +++ b/cpp/ql/src/Best Practices/Likely Errors/EmptyBlock.ql @@ -14,7 +14,7 @@ import cpp -predicate emptyBlock(ControlStructure s, Block b) { +predicate emptyBlock(ControlStructure s, BlockStmt b) { b = s.getAChild() and not exists(b.getAChild()) and not b.isInMacroExpansion() and @@ -23,7 +23,7 @@ predicate emptyBlock(ControlStructure s, Block b) { class AffectedFile extends File { AffectedFile() { - exists(Block b | + exists(BlockStmt b | emptyBlock(_, b) and this = b.getFile() ) @@ -37,7 +37,7 @@ class AffectedFile extends File { class BlockOrNonChild extends Element { BlockOrNonChild() { ( - this instanceof Block + this instanceof BlockStmt or this instanceof Comment or @@ -78,7 +78,7 @@ class BlockOrNonChild extends Element { /** * A block that contains a non-child element. */ -predicate emptyBlockContainsNonchild(Block b) { +predicate emptyBlockContainsNonchild(BlockStmt b) { emptyBlock(_, b) and exists(BlockOrNonChild c, AffectedFile file | c.(BlockOrNonChild).getStartRankIn(file) = 1 + b.(BlockOrNonChild).getStartRankIn(file) and @@ -91,7 +91,7 @@ predicate emptyBlockContainsNonchild(Block b) { * A block that is entirely on one line, which also contains a comment. Chances * are the comment is intended to refer to the block. */ -predicate lineComment(Block b) { +predicate lineComment(BlockStmt b) { emptyBlock(_, b) and exists(Location bLocation, File f, int line | bLocation = b.getLocation() and @@ -106,7 +106,7 @@ predicate lineComment(Block b) { ) } -from ControlStructure s, Block eb +from ControlStructure s, BlockStmt eb where emptyBlock(s, eb) and not emptyBlockContainsNonchild(eb) and diff --git a/cpp/ql/src/Critical/DeadCodeGoto.ql b/cpp/ql/src/Critical/DeadCodeGoto.ql index 4e16325f943..a2f8db771b0 100644 --- a/cpp/ql/src/Critical/DeadCodeGoto.ql +++ b/cpp/ql/src/Critical/DeadCodeGoto.ql @@ -12,7 +12,7 @@ import cpp import semmle.code.cpp.commons.Exclusions -Stmt getNextRealStmt(Block b, int i) { +Stmt getNextRealStmt(BlockStmt b, int i) { result = b.getStmt(i + 1) and not result instanceof EmptyStmt or @@ -20,7 +20,7 @@ Stmt getNextRealStmt(Block b, int i) { result = getNextRealStmt(b, i + 1) } -from JumpStmt js, Block b, int i, Stmt s +from JumpStmt js, BlockStmt b, int i, Stmt s where b.getStmt(i) = js and s = getNextRealStmt(b, i) and diff --git a/cpp/ql/src/JPL_C/LOC-4/Rule 21/MacroInBlock.ql b/cpp/ql/src/JPL_C/LOC-4/Rule 21/MacroInBlock.ql index 602be971763..9ed5675e795 100644 --- a/cpp/ql/src/JPL_C/LOC-4/Rule 21/MacroInBlock.ql +++ b/cpp/ql/src/JPL_C/LOC-4/Rule 21/MacroInBlock.ql @@ -12,7 +12,7 @@ import cpp int lineInBlock(File f) { - exists(Block block, Location blockLocation | + exists(BlockStmt block, Location blockLocation | block.getFile() = f and blockLocation = block.getLocation() | result in [blockLocation.getStartLine() .. blockLocation.getEndLine()] diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/FutileConditional.ql b/cpp/ql/src/Likely Bugs/Likely Typos/FutileConditional.ql index 4f23ed50b36..bf724de3d70 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/FutileConditional.ql +++ b/cpp/ql/src/Likely Bugs/Likely Typos/FutileConditional.ql @@ -27,11 +27,11 @@ predicate macroUseLocation(File f, int start, int end) { } pragma[noopt] -predicate emptyIf(IfStmt s, Block b, File f, int start, int end) { +predicate emptyIf(IfStmt s, BlockStmt b, File f, int start, int end) { s instanceof IfStmt and not exists(s.getElse()) and b = s.getThen() and - b instanceof Block and + b instanceof BlockStmt and not exists(b.getAChild()) and f = b.getFile() and exists(Location l | @@ -42,7 +42,7 @@ predicate emptyIf(IfStmt s, Block b, File f, int start, int end) { } pragma[noopt] -predicate query(IfStmt s, Block b) { +predicate query(IfStmt s, BlockStmt b) { exists(File f, int blockStart, int blockEnd | emptyIf(s, b, f, blockStart, blockEnd) and not exists(int macroStart, int macroEnd | @@ -53,7 +53,7 @@ predicate query(IfStmt s, Block b) { ) } -from IfStmt s, Block b +from IfStmt s, BlockStmt b where query(s, b) and not b.isInMacroExpansion() diff --git a/cpp/ql/src/Power of 10/Rule 4/FunctionTooLong.ql b/cpp/ql/src/Power of 10/Rule 4/FunctionTooLong.ql index 2b26a835683..701d56e6ce2 100644 --- a/cpp/ql/src/Power of 10/Rule 4/FunctionTooLong.ql +++ b/cpp/ql/src/Power of 10/Rule 4/FunctionTooLong.ql @@ -27,7 +27,7 @@ int logicalLength(FunctionDeclarationEntry f) { count(Stmt s | s.getEnclosingFunction() = f.getFunction() and s.getFile() = f.getFile() and - not s instanceof Block and + not s instanceof BlockStmt and not s instanceof EmptyStmt and not exists(ForStmt for | s = for.getInitialization()) and not s.isAffectedByMacro() diff --git a/cpp/ql/src/Power of 10/Rule 4/OneStmtPerLine.ql b/cpp/ql/src/Power of 10/Rule 4/OneStmtPerLine.ql index c3936e1ed89..7c66cdd41f4 100644 --- a/cpp/ql/src/Power of 10/Rule 4/OneStmtPerLine.ql +++ b/cpp/ql/src/Power of 10/Rule 4/OneStmtPerLine.ql @@ -14,7 +14,7 @@ import cpp class OneLineStmt extends Stmt { OneLineStmt() { this.getLocation().getStartLine() = this.getLocation().getEndLine() and - not this instanceof Block and + not this instanceof BlockStmt and not exists(ForStmt for | this = for.getInitialization()) and ( // Either this statement is not touched by a macro at all... diff --git a/cpp/ql/src/Power of 10/Rule 5/AssertionDensity.ql b/cpp/ql/src/Power of 10/Rule 5/AssertionDensity.ql index 1fbbaf99b58..3bb926b8a64 100644 --- a/cpp/ql/src/Power of 10/Rule 5/AssertionDensity.ql +++ b/cpp/ql/src/Power of 10/Rule 5/AssertionDensity.ql @@ -27,7 +27,7 @@ int logicalLength(FunctionDeclarationEntry f) { count(Stmt s | s.getEnclosingFunction() = f.getFunction() and s.getFile() = f.getFile() and - not s instanceof Block and + not s instanceof BlockStmt and not s instanceof EmptyStmt and not exists(ForStmt for | s = for.getInitialization()) and not s.isAffectedByMacro() diff --git a/cpp/ql/src/experimental/Likely Bugs/RedundantNullCheckParam.ql b/cpp/ql/src/experimental/Likely Bugs/RedundantNullCheckParam.ql index c67e15aceba..f1a3663bb96 100644 --- a/cpp/ql/src/experimental/Likely Bugs/RedundantNullCheckParam.ql +++ b/cpp/ql/src/experimental/Likely Bugs/RedundantNullCheckParam.ql @@ -13,7 +13,7 @@ import cpp -predicate blockDominates(Block check, Block access) { +predicate blockDominates(BlockStmt check, BlockStmt access) { check.getLocation().getStartLine() <= access.getLocation().getStartLine() and check.getLocation().getEndLine() >= access.getLocation().getEndLine() } diff --git a/cpp/ql/src/external/CodeDuplication.qll b/cpp/ql/src/external/CodeDuplication.qll index 4548e0be85e..8cc56d12e19 100644 --- a/cpp/ql/src/external/CodeDuplication.qll +++ b/cpp/ql/src/external/CodeDuplication.qll @@ -117,7 +117,7 @@ private predicate blockCoversStatement(int equivClass, int first, int last, Stmt private Stmt statementInMethod(FunctionDeclarationEntry m) { result.getParent+() = m.getBlock() and not result.getLocation() instanceof UnknownStmtLocation and - not result instanceof Block + not result instanceof BlockStmt } private predicate duplicateStatement( diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql index 2a5681093c7..63e318125dc 100644 --- a/cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql +++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 59.ql @@ -13,7 +13,7 @@ import cpp from Stmt parent, Stmt child where - not child instanceof Block and + not child instanceof BlockStmt and ( child = parent.(IfStmt).getThen() or diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql index dcfaf06f49b..26a56faab5c 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 85.ql @@ -28,7 +28,7 @@ predicate oppositeOperators(string op1, string op2) { * `!op2(_, _)`. */ predicate implementedAsNegationOf(Operator op1, Operator op2) { - exists(Block b, ReturnStmt r, NotExpr n, Expr o | + exists(BlockStmt b, ReturnStmt r, NotExpr n, Expr o | b = op1.getBlock() and b.getNumStmt() = 1 and r = b.getStmt(0) and diff --git a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 135.ql b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 135.ql index 0b3572af97e..d3e23c9a7f6 100644 --- a/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 135.ql +++ b/cpp/ql/src/jsf/4.15 Declarations and Definitions/AV Rule 135.ql @@ -29,7 +29,7 @@ predicate localShadowsParameter(LocalVariable lv, Parameter p) { from Variable v, Variable shadowed where - not v.getParentScope().(Block).isInMacroExpansion() and + not v.getParentScope().(BlockStmt).isInMacroExpansion() and ( v.(LocalVariableOrParameter).shadowsGlobal(shadowed.(GlobalVariable)) or localShadowsParameter(v, shadowed) or diff --git a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql index 973cb016579..1f7fe79fd77 100644 --- a/cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql +++ b/cpp/ql/src/jsf/4.16 Initialization/AV Rule 143.ql @@ -38,7 +38,7 @@ predicate noDefUsePath(LocalVariable lv, ControlFlowNode n) { } predicate neighbouringStmts(Stmt s1, Stmt s2) { - exists(Block b, int i | + exists(BlockStmt b, int i | i in [0 .. b.getNumStmt() - 2] and s1 = b.getStmt(i) and s2 = b.getStmt(i + 1) diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql index 7a8919faf89..5893f3f35a3 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 187.ql @@ -22,6 +22,6 @@ where not s instanceof ControlStructure and // Exclude blocks; if a child of the block violates the rule that will still // be picked up so there is no point in blaming the block as well - not s instanceof Block and + not s instanceof BlockStmt and s.isPure() select s, "AV Rule 187: All non-null statements shall potentially have a side-effect." diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql index 579a615c27f..2e730b66654 100644 --- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql +++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 191.ql @@ -18,7 +18,7 @@ import cpp // whether t is the last statement of s, possibly peeling off blocks predicate isTerminatingStmt(Stmt s, Stmt t) { - s = t or isTerminatingStmt(s.(Block).getLastStmt(), t) + s = t or isTerminatingStmt(s.(BlockStmt).getLastStmt(), t) } from BreakStmt s diff --git a/cpp/ql/src/semmle/code/cpp/Element.qll b/cpp/ql/src/semmle/code/cpp/Element.qll index 8076f62583a..c7cc4a65b36 100644 --- a/cpp/ql/src/semmle/code/cpp/Element.qll +++ b/cpp/ql/src/semmle/code/cpp/Element.qll @@ -128,7 +128,7 @@ class Element extends ElementBase { /** * Gets the parent scope of this `Element`, if any. - * A scope is a `Type` (`Class` / `Enum`), a `Namespace`, a `Block`, a `Function`, + * A scope is a `Type` (`Class` / `Enum`), a `Namespace`, a `BlockStmt`, a `Function`, * or certain kinds of `Statement`. */ Element getParentScope() { @@ -161,7 +161,7 @@ class Element extends ElementBase { exists(EnumConstant e | this = e and result = e.getDeclaringEnum()) or // result instanceof block|function - exists(Block b | this = b and blockscope(unresolveElement(b), unresolveElement(result))) + exists(BlockStmt b | this = b and blockscope(unresolveElement(b), unresolveElement(result))) or exists(TemplateFunction tf | this = tf.getATemplateArgument() and result = tf) or diff --git a/cpp/ql/src/semmle/code/cpp/Function.qll b/cpp/ql/src/semmle/code/cpp/Function.qll index 0a63da4a174..2c45fa184cf 100644 --- a/cpp/ql/src/semmle/code/cpp/Function.qll +++ b/cpp/ql/src/semmle/code/cpp/Function.qll @@ -268,7 +268,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function { * block, this gives the block guarded by the try statement. See * `FunctionTryStmt` for further information. */ - Block getBlock() { result.getParentScope() = this } + BlockStmt getBlock() { result.getParentScope() = this } /** Holds if this function has an entry point. */ predicate hasEntryPoint() { exists(getEntryPoint()) } @@ -276,7 +276,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function { /** * Gets the first node in this function's control flow graph. * - * For most functions, this first node will be the `Block` returned by + * For most functions, this first node will be the `BlockStmt` returned by * `getBlock`. However in C++, the first node can also be a * `FunctionTryStmt`. */ @@ -564,7 +564,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl { * If this is a function definition, get the block containing the * function body. */ - Block getBlock() { + BlockStmt getBlock() { this.isDefinition() and result = getFunction().getBlock() and result.getFile() = this.getFile() @@ -576,7 +576,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl { */ pragma[noopt] int getNumberOfLines() { - exists(Block b, Location l, int start, int end, int diff | b = getBlock() | + exists(BlockStmt b, Location l, int start, int end, int diff | b = getBlock() | l = b.getLocation() and start = l.getStartLine() and end = l.getEndLine() and diff --git a/cpp/ql/src/semmle/code/cpp/ObjectiveC.qll b/cpp/ql/src/semmle/code/cpp/ObjectiveC.qll index d4b844c3bf7..17da273d5a7 100644 --- a/cpp/ql/src/semmle/code/cpp/ObjectiveC.qll +++ b/cpp/ql/src/semmle/code/cpp/ObjectiveC.qll @@ -136,7 +136,7 @@ deprecated class ObjcTryStmt extends TryStmt { * DEPRECATED: Objective-C is no longer supported. * An Objective C `@finally` block. */ -deprecated class FinallyBlock extends Block { +deprecated class FinallyBlock extends BlockStmt { FinallyBlock() { none() } /** Gets the try statement corresponding to this finally block. */ diff --git a/cpp/ql/src/semmle/code/cpp/Parameter.qll b/cpp/ql/src/semmle/code/cpp/Parameter.qll index 99ad822e072..040b738591c 100644 --- a/cpp/ql/src/semmle/code/cpp/Parameter.qll +++ b/cpp/ql/src/semmle/code/cpp/Parameter.qll @@ -98,7 +98,7 @@ class Parameter extends LocalScopeVariable, @parameter { * DEPRECATED: this method was used in a previous implementation of * getName, but is no longer in use. */ - deprecated string getNameInBlock(Block b) { + deprecated string getNameInBlock(BlockStmt b) { exists(ParameterDeclarationEntry pde | pde.getFunctionDeclarationEntry().getBlock() = b and this.getFunction().getBlock() = b and @@ -127,7 +127,7 @@ class Parameter extends LocalScopeVariable, @parameter { * Gets the catch block to which this parameter belongs, if it is a catch * block parameter. */ - Block getCatchBlock() { params(underlyingElement(this), unresolveElement(result), _, _) } + BlockStmt getCatchBlock() { params(underlyingElement(this), unresolveElement(result), _, _) } /** * Gets the zero-based index of this parameter. diff --git a/cpp/ql/src/semmle/code/cpp/commons/VoidContext.qll b/cpp/ql/src/semmle/code/cpp/commons/VoidContext.qll index 4b0b1299fd8..0a325442cf5 100644 --- a/cpp/ql/src/semmle/code/cpp/commons/VoidContext.qll +++ b/cpp/ql/src/semmle/code/cpp/commons/VoidContext.qll @@ -25,7 +25,7 @@ private predicate exprInVoidContext(Expr e) { ( exists(ExprStmt s | s = e.getParent() and - not exists(StmtExpr se | s = se.getStmt().(Block).getLastStmt()) + not exists(StmtExpr se | s = se.getStmt().(BlockStmt).getLastStmt()) ) or exists(ConditionalExpr c | c.getThen() = e and c instanceof ExprInVoidContext) diff --git a/cpp/ql/src/semmle/code/cpp/controlflow/internal/CFG.qll b/cpp/ql/src/semmle/code/cpp/controlflow/internal/CFG.qll index 548e9577657..b47618de2e9 100644 --- a/cpp/ql/src/semmle/code/cpp/controlflow/internal/CFG.qll +++ b/cpp/ql/src/semmle/code/cpp/controlflow/internal/CFG.qll @@ -118,7 +118,7 @@ private predicate excludeNodeAndNodesBelow(Expr e) { or // Constructor init lists should be evaluated, and we can change this in // the future, but it would mean that a `Function` entry point is not - // always a `Block` or `FunctionTryStmt`. + // always a `BlockStmt` or `FunctionTryStmt`. e instanceof ConstructorInit or // Destructor field destructions should also be hooked into the CFG @@ -408,10 +408,10 @@ private Node getControlOrderChildSparse(Node n, int i) { // in-line in the block containing their corresponding DeclStmt but should // not be evaluated in the order implied by their position in the block. We // do the following. - // - Block skips all the VlaDeclStmt and VlaDimensionStmt children. + // - BlockStmt skips all the VlaDeclStmt and VlaDimensionStmt children. // - VlaDeclStmt is inserted as a child of DeclStmt // - VlaDimensionStmt is inserted as a child of VlaDeclStmt - result = n.(Block).getChild(i) and + result = n.(BlockStmt).getChild(i) and not result instanceof VlaDeclStmt and not result instanceof VlaDimensionStmt or @@ -557,7 +557,7 @@ private class Spec extends Pos { */ private predicate straightLineSparse(Node scope, int i, Node ni, Spec spec) { scope = - any(Block b | + any(BlockStmt b | i = -1 and ni = b and spec.isAt() or if exists(getLastControlOrderChild(b)) @@ -734,7 +734,7 @@ private predicate straightLineSparse(Node scope, int i, Node ni, Spec spec) { or // If the switch body is not a block then this step is skipped, and the // expression jumps directly to the cases. - i = 1 and ni = s.getStmt().(Block) and spec.isAt() + i = 1 and ni = s.getStmt().(BlockStmt) and spec.isAt() or i = 2 and ni = s.getASwitchCase() and spec.isBefore() or @@ -1010,7 +1010,7 @@ private predicate subEdgeIncludingDestructors(Pos p1, Node n1, Node n2, Pos p2) * The exact placement of that call in the CFG depends on the type of * `node` as follows: * - * - `Block`: after ordinary control flow falls off the end of the block + * - `BlockStmt`: after ordinary control flow falls off the end of the block * without jumps or exceptions. * - `ReturnStmt`: After the statement itself or after its operand (if * present). diff --git a/cpp/ql/src/semmle/code/cpp/controlflow/internal/ConstantExprs.qll b/cpp/ql/src/semmle/code/cpp/controlflow/internal/ConstantExprs.qll index 93720c160e9..face126dad5 100644 --- a/cpp/ql/src/semmle/code/cpp/controlflow/internal/ConstantExprs.qll +++ b/cpp/ql/src/semmle/code/cpp/controlflow/internal/ConstantExprs.qll @@ -182,7 +182,7 @@ private int switchCaseRangeEnd(SwitchCase sc) { * body `switchBlock`. There may be several such expressions: for example, if * the condition is `(x ? y : z)` then the result is {`y`, `z`}. */ -private Node getASwitchExpr(SwitchStmt switch, Block switchBlock) { +private Node getASwitchExpr(SwitchStmt switch, BlockStmt switchBlock) { switch.getStmt() = switchBlock and successors_extended(result, switchBlock) } @@ -192,7 +192,7 @@ private Node getASwitchExpr(SwitchStmt switch, Block switchBlock) { * from `switchBlock` to `sc` is impossible. This considers only non-`default` * switch cases. */ -private predicate impossibleSwitchEdge(Block switchBlock, SwitchCase sc) { +private predicate impossibleSwitchEdge(BlockStmt switchBlock, SwitchCase sc) { not sc instanceof DefaultCase and exists(SwitchStmt switch | switch = sc.getSwitchStmt() and @@ -215,7 +215,7 @@ private predicate impossibleSwitchEdge(Block switchBlock, SwitchCase sc) { * If a switch provably always chooses a non-default case, then the edge to * the default case is impossible. */ -private predicate impossibleDefaultSwitchEdge(Block switchBlock, DefaultCase dc) { +private predicate impossibleDefaultSwitchEdge(BlockStmt switchBlock, DefaultCase dc) { exists(SwitchStmt switch | switch = dc.getSwitchStmt() and switch.getStmt() = switchBlock and diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll index a3f0c435e16..9f580778c3d 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll @@ -33,10 +33,10 @@ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) { } /** - * Holds if `node` should be a barrier in all global taint flow configurations + * Holds if `node` should be a sanitizer in all global taint flow configurations * but not in local taint. */ -predicate defaultTaintBarrier(DataFlow::Node node) { none() } +predicate defaultTaintSanitizer(DataFlow::Node node) { none() } /** * Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding @@ -90,10 +90,17 @@ predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeT exists(TaintFunction f, Call call, FunctionInput inModel, FunctionOutput outModel | call.getTarget() = f and inModel.isReturnValueDeref() and - outModel.isQualifierObject() and - f.hasTaintFlow(inModel, outModel) and nodeFrom.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() = call and - nodeTo.asDefiningArgument() = call.getQualifier() + f.hasTaintFlow(inModel, outModel) and + ( + outModel.isQualifierObject() and + nodeTo.asDefiningArgument() = call.getQualifier() + or + exists(int argOutIndex | + outModel.isParameterDeref(argOutIndex) and + nodeTo.asDefiningArgument() = call.getArgument(argOutIndex) + ) + ) ) } diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll index af0d0fec53a..b509fad9cd2 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration { final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) or - defaultTaintBarrier(node) + defaultTaintSanitizer(node) } - /** Holds if data flow into `node` is prohibited. */ + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) } - /** Holds if data flow out of `node` is prohibited. */ + /** Holds if taint propagation out of `node` is prohibited. */ predicate isSanitizerOut(DataFlow::Node node) { none() } final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) } - /** Holds if data flow through nodes guarded by `guard` is prohibited. */ + /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */ predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() } final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) } diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll index af0d0fec53a..b509fad9cd2 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration { final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) or - defaultTaintBarrier(node) + defaultTaintSanitizer(node) } - /** Holds if data flow into `node` is prohibited. */ + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) } - /** Holds if data flow out of `node` is prohibited. */ + /** Holds if taint propagation out of `node` is prohibited. */ predicate isSanitizerOut(DataFlow::Node node) { none() } final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) } - /** Holds if data flow through nodes guarded by `guard` is prohibited. */ + /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */ predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() } final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) } diff --git a/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll b/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll index a89b2dc60fa..24d9551528a 100644 --- a/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll +++ b/cpp/ql/src/semmle/code/cpp/exprs/Expr.qll @@ -27,7 +27,7 @@ class Expr extends StmtParent, @expr { Function getEnclosingFunction() { result = exprEnclosingElement(this) } /** Gets the nearest enclosing set of curly braces around this expression in the source, if any. */ - Block getEnclosingBlock() { result = getEnclosingStmt().getEnclosingBlock() } + BlockStmt getEnclosingBlock() { result = getEnclosingStmt().getEnclosingBlock() } override Stmt getEnclosingStmt() { result = this.getParent().(Expr).getEnclosingStmt() @@ -1109,7 +1109,7 @@ class StmtExpr extends Expr, @expr_stmt { /** Get the result expression of a statement. (Helper function for StmtExpr.) */ private Expr getStmtResultExpr(Stmt stmt) { result = stmt.(ExprStmt).getExpr() or - result = getStmtResultExpr(stmt.(Block).getLastStmt()) + result = getStmtResultExpr(stmt.(BlockStmt).getLastStmt()) } /** diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll index 2290bab0571..40b3a9d6fb7 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll @@ -100,10 +100,10 @@ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) { } /** - * Holds if `node` should be a barrier in all global taint flow configurations + * Holds if `node` should be a sanitizer in all global taint flow configurations * but not in local taint. */ -predicate defaultTaintBarrier(DataFlow::Node node) { none() } +predicate defaultTaintSanitizer(DataFlow::Node node) { none() } /** * Holds if taint can flow from `instrIn` to `instrOut` through a call to a diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll index af0d0fec53a..b509fad9cd2 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration { final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) or - defaultTaintBarrier(node) + defaultTaintSanitizer(node) } - /** Holds if data flow into `node` is prohibited. */ + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) } - /** Holds if data flow out of `node` is prohibited. */ + /** Holds if taint propagation out of `node` is prohibited. */ predicate isSanitizerOut(DataFlow::Node node) { none() } final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) } - /** Holds if data flow through nodes guarded by `guard` is prohibited. */ + /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */ predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() } final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll index af0d0fec53a..b509fad9cd2 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration { final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) or - defaultTaintBarrier(node) + defaultTaintSanitizer(node) } - /** Holds if data flow into `node` is prohibited. */ + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) } - /** Holds if data flow out of `node` is prohibited. */ + /** Holds if taint propagation out of `node` is prohibited. */ predicate isSanitizerOut(DataFlow::Node node) { none() } final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) } - /** Holds if data flow through nodes guarded by `guard` is prohibited. */ + /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */ predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() } final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index 98bcd1da8b2..6da9193fd58 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -2905,7 +2905,7 @@ predicate exprNeedsCopyIfNotLoaded(Expr expr) { private predicate exprImmediatelyDiscarded(Expr expr) { exists(ExprStmt s | s = expr.getParent() and - not exists(StmtExpr se | s = se.getStmt().(Block).getLastStmt()) + not exists(StmtExpr se | s = se.getStmt().(BlockStmt).getLastStmt()) ) or exists(CommaExpr c | c.getLeftOperand() = expr) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll index 3339046d391..ce08fc9367f 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll @@ -290,7 +290,7 @@ class TranslatedTryStmt extends TranslatedStmt { } class TranslatedBlock extends TranslatedStmt { - override Block stmt; + override BlockStmt stmt; override TranslatedElement getChild(int id) { result = getStmt(id) } diff --git a/cpp/ql/src/semmle/code/cpp/metrics/MetricFunction.qll b/cpp/ql/src/semmle/code/cpp/metrics/MetricFunction.qll index 3dbb290d71a..45036cfddf3 100644 --- a/cpp/ql/src/semmle/code/cpp/metrics/MetricFunction.qll +++ b/cpp/ql/src/semmle/code/cpp/metrics/MetricFunction.qll @@ -334,7 +334,7 @@ private predicate branchingExpr(Expr expr) { * Gets the number of branching statements and expressions in a block. This is * for computing cyclomatic complexity. */ -int cyclomaticComplexityBranches(Block b) { +int cyclomaticComplexityBranches(BlockStmt b) { result = count(Stmt stmt | branchingStmt(stmt) and @@ -373,7 +373,7 @@ private predicate skipParent(Stmt s) { exists(Stmt parent | parent = s.getParentStmt() | s instanceof IfStmt and parent.(IfStmt).getElse() = s or - parent instanceof Block + parent instanceof BlockStmt or exists(File f, int startLine, int startCol | startsAt(s, f, startLine, startCol) and diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll index 8e7cb24be73..8d4fdd8700c 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll @@ -1,7 +1,7 @@ /** - * Provides implementation classes modeling `std::string` and other - * instantiations of `std::basic_string`. See `semmle.code.cpp.models.Models` - * for usage information. + * Provides implementation classes modeling `std::string` (and other + * instantiations of `std::basic_string`) and `std::ostream`. See + * `semmle.code.cpp.models.Models` for usage information. */ import semmle.code.cpp.models.interfaces.Taint @@ -287,3 +287,68 @@ class StdStringAt extends TaintFunction { output.isQualifierObject() } } + +/** + * The `std::basic_ostream` template class. + */ +class StdBasicOStream extends TemplateClass { + StdBasicOStream() { this.hasQualifiedName("std", "basic_ostream") } +} + +/** + * The `std::ostream` function `operator<<` (defined as a member function). + */ +class StdOStreamOut extends DataFlowFunction, TaintFunction { + StdOStreamOut() { this.hasQualifiedName("std", "basic_ostream", "operator<<") } + + override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { + // flow from qualifier to return value + input.isQualifierAddress() and + output.isReturnValue() + } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + // flow from parameter to qualifier + input.isParameter(0) and + output.isQualifierObject() + or + // flow from parameter to return value + input.isParameter(0) and + output.isReturnValueDeref() + or + // reverse flow from returned reference to the qualifier + input.isReturnValueDeref() and + output.isQualifierObject() + } +} + +/** + * The `std::ostream` function `operator<<` (defined as a non-member function). + */ +class StdOStreamOutNonMember extends DataFlowFunction, TaintFunction { + StdOStreamOutNonMember() { + this.hasQualifiedName("std", "operator<<") and + this.getUnspecifiedType().(ReferenceType).getBaseType() = + any(StdBasicOStream s).getAnInstantiation() + } + + override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { + // flow from first parameter to return value + input.isParameter(0) and + output.isReturnValue() + } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + // flow from second parameter to first parameter + input.isParameter(1) and + output.isParameterDeref(0) + or + // flow from second parameter to return value + input.isParameter(1) and + output.isReturnValueDeref() + or + // reverse flow from returned reference to the first parameter + input.isReturnValueDeref() and + output.isParameterDeref(0) + } +} diff --git a/cpp/ql/src/semmle/code/cpp/stmts/Block.qll b/cpp/ql/src/semmle/code/cpp/stmts/Block.qll index 48caa48a803..3bebc660456 100644 --- a/cpp/ql/src/semmle/code/cpp/stmts/Block.qll +++ b/cpp/ql/src/semmle/code/cpp/stmts/Block.qll @@ -17,8 +17,8 @@ import semmle.code.cpp.stmts.Stmt * } * ``` */ -class Block extends Stmt, @stmt_block { - override string getAPrimaryQlClass() { result = "Block" } +class BlockStmt extends Stmt, @stmt_block { + override string getAPrimaryQlClass() { result = "BlockStmt" } /** * Gets a child declaration of this block. @@ -76,8 +76,8 @@ class Block extends Stmt, @stmt_block { * the result is the expression statement `a = b`. */ Stmt getLastStmtIn() { - if getLastStmt() instanceof Block - then result = getLastStmt().(Block).getLastStmtIn() + if getLastStmt() instanceof BlockStmt + then result = getLastStmt().(BlockStmt).getLastStmtIn() else result = getLastStmt() } @@ -126,3 +126,9 @@ class Block extends Stmt, @stmt_block { override predicate mayBeGloballyImpure() { this.getAStmt().mayBeGloballyImpure() } } + +/** + * DEPRECATED: This is now called `BlockStmt` to avoid confusion with + * `BasicBlock`. + */ +deprecated class Block = BlockStmt; diff --git a/cpp/ql/src/semmle/code/cpp/stmts/Stmt.qll b/cpp/ql/src/semmle/code/cpp/stmts/Stmt.qll index cb101cacdff..08840f2c505 100644 --- a/cpp/ql/src/semmle/code/cpp/stmts/Stmt.qll +++ b/cpp/ql/src/semmle/code/cpp/stmts/Stmt.qll @@ -25,10 +25,10 @@ class Stmt extends StmtParent, @stmt { /** * Gets the nearest enclosing block of this statement in the source, if any. */ - Block getEnclosingBlock() { + BlockStmt getEnclosingBlock() { if - getParentStmt() instanceof Block and - not getParentStmt().(Block).getLocation() instanceof UnknownLocation + getParentStmt() instanceof BlockStmt and + not getParentStmt().(BlockStmt).getLocation() instanceof UnknownLocation then result = getParentStmt() else result = getParentStmt().getEnclosingBlock() } @@ -53,7 +53,7 @@ class Stmt extends StmtParent, @stmt { * to trace the flow of control instead. */ Stmt getFollowingStmt() { - exists(Block b, int i | + exists(BlockStmt b, int i | this = b.getStmt(i) and result = b.getStmt(i + 1) ) @@ -240,7 +240,7 @@ class IfStmt extends ConditionalStmt, @stmt_if { * ``` * if (b) { x = 1; } * ``` - * the result is the `Block` `{ x = 1; }`. + * the result is the `BlockStmt` `{ x = 1; }`. */ Stmt getThen() { if_then(underlyingElement(this), unresolveElement(result)) } @@ -251,7 +251,7 @@ class IfStmt extends ConditionalStmt, @stmt_if { * ``` * if (b) { x = 1; } else { x = 2; } * ``` - * the result is the `Block` `{ x = 2; }`, and for + * the result is the `BlockStmt` `{ x = 2; }`, and for * ``` * if (b) { x = 1; } * ``` @@ -326,7 +326,7 @@ class ConstexprIfStmt extends ConditionalStmt, @stmt_constexpr_if { * ``` * if constexpr (b) { x = 1; } * ``` - * the result is the `Block` `{ x = 1; }`. + * the result is the `BlockStmt` `{ x = 1; }`. */ Stmt getThen() { constexpr_if_then(underlyingElement(this), unresolveElement(result)) } @@ -337,7 +337,7 @@ class ConstexprIfStmt extends ConditionalStmt, @stmt_constexpr_if { * ``` * if constexpr (b) { x = 1; } else { x = 2; } * ``` - * the result is the `Block` `{ x = 2; }`, and for + * the result is the `BlockStmt` `{ x = 2; }`, and for * ``` * if constexpr (b) { x = 1; } * ``` @@ -842,7 +842,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for { * ``` * for (int x : xs) { y += x; } * ``` - * the result is the `Block` `{ y += x; }`. + * the result is the `BlockStmt` `{ y += x; }`. */ override Stmt getStmt() { result = this.getChild(5) } @@ -1229,7 +1229,7 @@ class SwitchCase extends Stmt, @stmt_switch_case { * DEPRECATED: use `SwitchCase.getAStmt` or `ControlFlowNode.getASuccessor` * rather than this predicate. * - * Gets the `Block` statement immediately following this 'switch case' + * Gets the `BlockStmt` statement immediately following this 'switch case' * statement, if any. * * For example, for @@ -1250,7 +1250,7 @@ class SwitchCase extends Stmt, @stmt_switch_case { * the `case 7:` has result `{ x = 2; break; }`, `default:` has result * `{ x = 3; }`, and the others have no result. */ - deprecated Block getLabelledStmt() { + deprecated BlockStmt getLabelledStmt() { exists(int i, Stmt parent | this = parent.getChild(i) and result = parent.getChild(i + 1) @@ -1331,7 +1331,7 @@ class SwitchCase extends Stmt, @stmt_switch_case { * `default:` has results `{ x = 3; }, `x = 4;` and `break;`. */ Stmt getAStmt() { - exists(Block b, int i, int j | + exists(BlockStmt b, int i, int j | b.getStmt(i) = this and b.getStmt(j) = result and i < j and @@ -1370,8 +1370,8 @@ class SwitchCase extends Stmt, @stmt_switch_case { exists(Stmt lastStmt | lastStmt = this.getAStmt() and not lastStmt.getFollowingStmt() = this.getAStmt() and - if lastStmt instanceof Block - then result = lastStmt.(Block).getLastStmtIn() + if lastStmt instanceof BlockStmt + then result = lastStmt.(BlockStmt).getLastStmtIn() else result = lastStmt ) } @@ -1528,7 +1528,7 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch { /** * Gets the body statement of this 'switch' statement. * - * In almost all cases the result will be a `Block`, but there are + * In almost all cases the result will be a `BlockStmt`, but there are * other syntactically valid constructions. * * For example, for @@ -1859,7 +1859,7 @@ class FunctionTryStmt extends TryStmt { * } * ``` */ -class CatchBlock extends Block { +class CatchBlock extends BlockStmt { override string getAPrimaryQlClass() { result = "CatchBlock" } CatchBlock() { ishandler(underlyingElement(this)) } @@ -1925,7 +1925,7 @@ class MicrosoftTryExceptStmt extends MicrosoftTryStmt { /** Gets the expression guarding the `__except` statement. */ Expr getCondition() { result = getChild(1) } - /** Gets the `__except` statement (usually a `Block`). */ + /** Gets the `__except` statement (usually a `BlockStmt`). */ Stmt getExcept() { result = getChild(2) } override string getAPrimaryQlClass() { result = "MicrosoftTryExceptStmt" } @@ -1949,7 +1949,7 @@ class MicrosoftTryFinallyStmt extends MicrosoftTryStmt { override string toString() { result = "__try { ... } __finally { ... }" } - /** Gets the `__finally` statement (usually a `Block`). */ + /** Gets the `__finally` statement (usually a `BlockStmt`). */ Stmt getFinally() { result = getChild(1) } override string getAPrimaryQlClass() { result = "MicrosoftTryFinallyStmt" } @@ -2108,7 +2108,7 @@ class VlaDeclStmt extends Stmt, @stmt_vla_decl { * declaration statement. */ int getNumberOfVlaDimensionStmts() { - exists(Block b, int j | + exists(BlockStmt b, int j | this = b.getStmt(j) and result = j - 1 - @@ -2125,7 +2125,7 @@ class VlaDeclStmt extends Stmt, @stmt_vla_decl { */ VlaDimensionStmt getVlaDimensionStmt(int i) { i in [0 .. this.getNumberOfVlaDimensionStmts() - 1] and - exists(Block b, int j | + exists(BlockStmt b, int j | this = b.getStmt(j) and result = b.getStmt(j - this.getNumberOfVlaDimensionStmts() + i) ) diff --git a/cpp/ql/test/examples/expressions/PrintAST.expected b/cpp/ql/test/examples/expressions/PrintAST.expected index 585ebae6ff4..e4037d3503e 100644 --- a/cpp/ql/test/examples/expressions/PrintAST.expected +++ b/cpp/ql/test/examples/expressions/PrintAST.expected @@ -19,7 +19,7 @@ AddressOf.c: # 1| params: # 1| 0: [Parameter] i # 1| Type = [IntType] int -# 1| body: [Block] { ... } +# 1| body: [BlockStmt] { ... } # 2| 0: [DeclStmt] declaration # 2| 0: [VariableDeclarationEntry] definition of j # 2| Type = [IntPointerType] int * @@ -34,7 +34,7 @@ AddressOf.c: ArrayToPointer.c: # 5| [TopLevelFunction] void ArrayToPointer() # 5| params: -# 6| body: [Block] { ... } +# 6| body: [BlockStmt] { ... } # 7| 0: [DeclStmt] declaration # 7| 0: [VariableDeclarationEntry] definition of c # 7| Type = [ArrayType] char[] @@ -70,7 +70,7 @@ Cast.c: # 1| Type = [CharPointerType] char * # 1| 1: [Parameter] v # 1| Type = [VoidPointerType] void * -# 1| body: [Block] { ... } +# 1| body: [BlockStmt] { ... } # 2| 0: [ExprStmt] ExprStmt # 2| 0: [AssignExpr] ... = ... # 2| Type = [CharPointerType] char * @@ -89,7 +89,7 @@ Cast.c: ConditionDecl.cpp: # 1| [TopLevelFunction] void ConditionDecl() # 1| params: -# 1| body: [Block] { ... } +# 1| body: [BlockStmt] { ... } # 2| 0: [DeclStmt] declaration # 2| 0: [VariableDeclarationEntry] definition of j # 2| Type = [IntType] int @@ -109,7 +109,7 @@ ConditionDecl.cpp: # 3| expr: [VariableAccess] k # 3| Type = [IntType] int # 3| ValueCategory = prvalue(load) -# 3| 1: [Block] { ... } +# 3| 1: [BlockStmt] { ... } # 5| 2: [ReturnStmt] return ... ConstructorCall.cpp: # 1| [CopyAssignmentOperator] C& C::operator=(C const&) @@ -133,7 +133,7 @@ ConstructorCall.cpp: # 3| 0: [Parameter] i # 3| Type = [IntType] int # 3| initializations: -# 3| body: [Block] { ... } +# 3| body: [BlockStmt] { ... } # 4| 0: [ReturnStmt] return ... # 7| [CopyAssignmentOperator] D& D::operator=(D const&) # 7| params: @@ -154,7 +154,7 @@ ConstructorCall.cpp: # 9| [Constructor] void D::D() # 9| params: # 9| initializations: -# 9| body: [Block] { ... } +# 9| body: [BlockStmt] { ... } # 10| 0: [ReturnStmt] return ... # 13| [CopyAssignmentOperator] E& E::operator=(E const&) # 13| params: @@ -172,7 +172,7 @@ ConstructorCall.cpp: # 17| Type = [PointerType] D * # 17| 2: [Parameter] e # 17| Type = [PointerType] E * -# 17| body: [Block] { ... } +# 17| body: [BlockStmt] { ... } # 18| 0: [ExprStmt] ExprStmt # 18| 0: [AssignExpr] ... = ... # 18| Type = [PointerType] C * @@ -221,7 +221,7 @@ ConstructorCall.cpp: Conversion1.c: # 1| [TopLevelFunction] void Conversion1() # 1| params: -# 1| body: [Block] { ... } +# 1| body: [BlockStmt] { ... } # 2| 0: [DeclStmt] declaration # 2| 0: [VariableDeclarationEntry] definition of i # 2| Type = [IntType] int @@ -241,7 +241,7 @@ Conversion2.c: # 1| params: # 1| 0: [Parameter] x # 1| Type = [IntType] int -# 1| body: [Block] { ... } +# 1| body: [BlockStmt] { ... } # 2| 0: [ExprStmt] ExprStmt # 2| 0: [AssignExpr] ... = ... # 2| Type = [IntType] int @@ -277,7 +277,7 @@ Conversion3.cpp: # 1| params: # 1| 0: [Parameter] x # 1| Type = [IntType] int -# 1| body: [Block] { ... } +# 1| body: [BlockStmt] { ... } # 2| 0: [ExprStmt] ExprStmt # 2| 0: [AssignExpr] ... = ... # 2| Type = [IntType] int @@ -327,7 +327,7 @@ Conversion4.c: # 1| params: # 1| 0: [Parameter] x # 1| Type = [IntType] int -# 1| body: [Block] { ... } +# 1| body: [BlockStmt] { ... } # 2| 0: [ExprStmt] ExprStmt # 2| 0: [AssignExpr] ... = ... # 2| Type = [IntType] int @@ -352,7 +352,7 @@ Conversion4.c: DestructorCall.cpp: # 3| [Destructor] void C::~C() # 3| params: -# 3| body: [Block] { ... } +# 3| body: [BlockStmt] { ... } # 4| 0: [ReturnStmt] return ... # 3| destructions: # 11| [TopLevelFunction] void DestructorCall(C*, D*) @@ -361,7 +361,7 @@ DestructorCall.cpp: # 11| Type = [PointerType] C * # 11| 1: [Parameter] d # 11| Type = [PointerType] D * -# 11| body: [Block] { ... } +# 11| body: [BlockStmt] { ... } # 12| 0: [ExprStmt] ExprStmt # 12| 0: [DeleteExpr] delete # 12| Type = [VoidType] void @@ -385,7 +385,7 @@ DynamicCast.cpp: # 1| params: #-----| 0: [Parameter] p#0 #-----| Type = [LValueReferenceType] const Base & -#-----| body: [Block] { ... } +#-----| body: [BlockStmt] { ... } #-----| 0: [ReturnStmt] return ... #-----| 0: [ReferenceToExpr] (reference to) #-----| Type = [LValueReferenceType] Base & @@ -412,13 +412,13 @@ DynamicCast.cpp: #-----| Type = [RValueReferenceType] Base && # 2| [VirtualFunction] void Base::f() # 2| params: -# 2| body: [Block] { ... } +# 2| body: [BlockStmt] { ... } # 2| 0: [ReturnStmt] return ... # 4| [CopyAssignmentOperator] Derived& Derived::operator=(Derived const&) # 4| params: #-----| 0: [Parameter] p#0 #-----| Type = [LValueReferenceType] const Derived & -#-----| body: [Block] { ... } +#-----| body: [BlockStmt] { ... } #-----| 0: [ExprStmt] ExprStmt #-----| 0: [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [Class] Base @@ -478,7 +478,7 @@ DynamicCast.cpp: #-----| Type = [RValueReferenceType] Derived && # 5| [VirtualFunction] void Derived::f() # 5| params: -# 5| body: [Block] { ... } +# 5| body: [BlockStmt] { ... } # 5| 0: [ReturnStmt] return ... # 8| [TopLevelFunction] void DynamicCast(Base*, Derived*) # 8| params: @@ -486,7 +486,7 @@ DynamicCast.cpp: # 8| Type = [PointerType] Base * # 8| 1: [Parameter] d # 8| Type = [PointerType] Derived * -# 8| body: [Block] { ... } +# 8| body: [BlockStmt] { ... } # 9| 0: [ExprStmt] ExprStmt # 9| 0: [AssignExpr] ... = ... # 9| Type = [PointerType] Derived * @@ -508,7 +508,7 @@ DynamicCast.cpp: # 12| Type = [LValueReferenceType] Base & # 12| 1: [Parameter] d # 12| Type = [LValueReferenceType] Derived & -# 12| body: [Block] { ... } +# 12| body: [BlockStmt] { ... } # 13| 0: [ExprStmt] ExprStmt # 13| 0: [ReferenceDereferenceExpr] (reference dereference) # 13| Type = [Class] Derived @@ -545,7 +545,7 @@ Parenthesis.c: # 1| params: # 1| 0: [Parameter] i # 1| Type = [IntType] int -# 1| body: [Block] { ... } +# 1| body: [BlockStmt] { ... } # 2| 0: [ExprStmt] ExprStmt # 2| 0: [AssignExpr] ... = ... # 2| Type = [IntType] int @@ -581,7 +581,7 @@ PointerDereference.c: # 1| Type = [IntPointerType] int * # 1| 1: [Parameter] j # 1| Type = [IntType] int -# 1| body: [Block] { ... } +# 1| body: [BlockStmt] { ... } # 2| 0: [ExprStmt] ExprStmt # 2| 0: [AssignExpr] ... = ... # 2| Type = [IntType] int @@ -603,7 +603,7 @@ ReferenceDereference.cpp: # 4| Type = [LValueReferenceType] int & # 4| 1: [Parameter] j # 4| Type = [IntType] int -# 4| body: [Block] { ... } +# 4| body: [BlockStmt] { ... } # 5| 0: [ExprStmt] ExprStmt # 5| 0: [AssignExpr] ... = ... # 5| Type = [IntType] int @@ -623,7 +623,7 @@ ReferenceTo.cpp: # 1| params: # 1| 0: [Parameter] i # 1| Type = [IntPointerType] int * -# 1| body: [Block] { ... } +# 1| body: [BlockStmt] { ... } # 2| 0: [ReturnStmt] return ... # 2| 0: [ReferenceToExpr] (reference to) # 2| Type = [LValueReferenceType] int & @@ -639,7 +639,7 @@ Sizeof.c: # 1| params: # 1| 0: [Parameter] array # 1| Type = [ArrayType] int[] -# 1| body: [Block] { ... } +# 1| body: [BlockStmt] { ... } # 2| 0: [DeclStmt] declaration # 2| 0: [VariableDeclarationEntry] definition of i # 2| Type = [IntType] int @@ -676,7 +676,7 @@ Sizeof.c: StatementExpr.c: # 1| [TopLevelFunction] void StatementExpr() # 1| params: -# 1| body: [Block] { ... } +# 1| body: [BlockStmt] { ... } # 2| 0: [DeclStmt] declaration # 2| 0: [VariableDeclarationEntry] definition of j # 2| Type = [IntType] int @@ -700,7 +700,7 @@ StaticMemberAccess.cpp: # 5| Type = [IntType] int # 5| 1: [Parameter] xref # 5| Type = [LValueReferenceType] X & -# 5| body: [Block] { ... } +# 5| body: [BlockStmt] { ... } # 7| 0: [ExprStmt] ExprStmt # 7| 0: [AssignExpr] ... = ... # 7| Type = [IntType] int @@ -725,7 +725,7 @@ Subscript.c: # 1| Type = [ArrayType] int[] # 1| 1: [Parameter] j # 1| Type = [IntType] int -# 1| body: [Block] { ... } +# 1| body: [BlockStmt] { ... } # 2| 0: [ExprStmt] ExprStmt # 2| 0: [AssignExpr] ... = ... # 2| Type = [IntType] int @@ -762,20 +762,20 @@ Throw.cpp: #-----| 0: [Parameter] p#0 #-----| Type = [RValueReferenceType] F && # 2| initializations: -# 2| body: [Block] { ... } +# 2| body: [BlockStmt] { ... } # 2| 0: [ReturnStmt] return ... # 4| [Constructor] void F::F() # 4| params: # 4| initializations: -# 4| body: [Block] { ... } +# 4| body: [BlockStmt] { ... } # 4| 0: [ReturnStmt] return ... # 6| [TopLevelFunction] void Throw(int) # 6| params: # 6| 0: [Parameter] i # 6| Type = [IntType] int -# 6| body: [Block] { ... } +# 6| body: [BlockStmt] { ... } # 7| 0: [TryStmt] try { ... } -# 7| 0: [Block] { ... } +# 7| 0: [BlockStmt] { ... } # 8| 0: [IfStmt] if (...) ... # 8| 0: [CStyleCast] (bool)... # 8| Conversion = [BoolConversion] conversion to bool @@ -818,13 +818,13 @@ Typeid.cpp: # 7| params: # 13| [VirtualFunction] void Base::v() # 13| params: -# 13| body: [Block] { ... } +# 13| body: [BlockStmt] { ... } # 13| 0: [ReturnStmt] return ... # 18| [TopLevelFunction] void TypeId(Base*) # 18| params: # 18| 0: [Parameter] bp # 18| Type = [PointerType] Base * -# 18| body: [Block] { ... } +# 18| body: [BlockStmt] { ... } # 19| 0: [DeclStmt] declaration # 19| 0: [VariableDeclarationEntry] definition of name # 19| Type = [PointerType] const char * @@ -846,7 +846,7 @@ VacuousDestructorCall.cpp: # 2| Type = [TemplateParameter] T # 2| 1: [Parameter] y # 2| Type = [PointerType] T * -# 2| body: [Block] { ... } +# 2| body: [BlockStmt] { ... } # 3| 0: [ExprStmt] ExprStmt # 3| 0: [ExprCall] call to expression # 3| Type = [UnknownType] unknown @@ -874,7 +874,7 @@ VacuousDestructorCall.cpp: # 2| Type = [IntType] int # 2| 1: [Parameter] y # 2| Type = [IntPointerType] int * -# 2| body: [Block] { ... } +# 2| body: [BlockStmt] { ... } # 3| 0: [ExprStmt] ExprStmt # 3| 0: [VacuousDestructorCall] (vacuous destructor call) # 3| Type = [VoidType] void @@ -894,7 +894,7 @@ VacuousDestructorCall.cpp: # 7| params: # 7| 0: [Parameter] i # 7| Type = [IntType] int -# 7| body: [Block] { ... } +# 7| body: [BlockStmt] { ... } # 10| 0: [ExprStmt] ExprStmt # 10| 0: [FunctionCall] call to CallDestructor # 10| Type = [VoidType] void @@ -914,7 +914,7 @@ Varargs.c: # 8| params: # 8| 0: [Parameter] text # 8| Type = [PointerType] const char * -# 8| body: [Block] { ... } +# 8| body: [BlockStmt] { ... } # 9| 0: [DeclStmt] declaration # 9| 0: [VariableDeclarationEntry] definition of args # 9| Type = [CTypedefType] va_list @@ -947,7 +947,7 @@ macro_etc.c: # 3| params: # 3| 0: [Parameter] i # 3| Type = [IntType] int -# 3| body: [Block] { ... } +# 3| body: [BlockStmt] { ... } # 4| 0: [DeclStmt] declaration # 4| 0: [TypeDeclarationEntry] definition of u # 4| Type = [LocalUnion] u @@ -997,7 +997,7 @@ macro_etc.c: # 10| ValueCategory = prvalue # 22| [TopLevelFunction] int foo() # 22| params: -# 22| body: [Block] { ... } +# 22| body: [BlockStmt] { ... } # 23| 0: [DeclStmt] declaration # 23| 0: [VariableDeclarationEntry] definition of t # 23| Type = [IntType] int @@ -1059,7 +1059,7 @@ macro_etc.c: # 27| 0: [VariableAccess] i # 27| Type = [PlainCharType] char # 27| ValueCategory = lvalue -# 27| 3: [Block] { ... } +# 27| 3: [BlockStmt] { ... } # 27| 0: [ExprStmt] ExprStmt # 27| 0: [AssignAddExpr] ... += ... # 27| Type = [IntType] int @@ -1111,7 +1111,7 @@ macro_etc.c: # 28| 0: [VariableAccess] i # 28| Type = [PlainCharType] char # 28| ValueCategory = lvalue -# 28| 3: [Block] { ... } +# 28| 3: [BlockStmt] { ... } # 28| 0: [ExprStmt] ExprStmt # 28| 0: [AssignAddExpr] ... += ... # 28| Type = [IntType] int @@ -1210,7 +1210,7 @@ union_etc.cpp: # 2| [Constructor] void S::S() # 2| params: # 2| initializations: -# 2| body: [Block] { ... } +# 2| body: [BlockStmt] { ... } # 2| 0: [ReturnStmt] return ... # 2| [CopyConstructor] void S::S(S const&) # 2| params: @@ -1240,7 +1240,7 @@ union_etc.cpp: # 6| params: # 6| 0: [Parameter] val # 6| Type = [IntType] int -# 6| body: [Block] { ... } +# 6| body: [BlockStmt] { ... } # 6| 0: [ExprStmt] ExprStmt # 6| 0: [AssignExpr] ... = ... # 6| Type = [IntType] int @@ -1305,7 +1305,7 @@ union_etc.cpp: #-----| Type = [RValueReferenceType] C && # 22| [TopLevelFunction] int foo() # 22| params: -# 22| body: [Block] { ... } +# 22| body: [BlockStmt] { ... } # 23| 0: [DeclStmt] declaration # 23| 0: [VariableDeclarationEntry] definition of s # 23| Type = [Struct] S @@ -1423,7 +1423,7 @@ union_etc.cpp: # 33| params: # 33| 0: [Parameter] val # 33| Type = [IntType] int -# 33| body: [Block] { ... } +# 33| body: [BlockStmt] { ... } # 33| 0: [ExprStmt] ExprStmt # 33| 0: [AssignExpr] ... = ... # 33| Type = [IntType] int @@ -1440,7 +1440,7 @@ union_etc.cpp: # 33| 1: [ReturnStmt] return ... # 36| [TopLevelFunction] int bar() # 36| params: -# 36| body: [Block] { ... } +# 36| body: [BlockStmt] { ... } # 37| 0: [DeclStmt] declaration # 37| 0: [VariableDeclarationEntry] definition of s # 37| Type = [PointerType] const T * diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/stl.cpp b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/stl.cpp index 3786e31a9ee..3454e6ac947 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/stl.cpp +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/stl.cpp @@ -88,14 +88,14 @@ void test_stringstream() ss5 << t; sink(ss1); - sink(ss2); // tainted [NOT DETECTED] + sink(ss2); // tainted sink(ss3); // tainted [NOT DETECTED] - sink(ss4); // tainted [NOT DETECTED] + sink(ss4); // tainted sink(ss5); // tainted [NOT DETECTED] sink(ss1.str()); - sink(ss2.str()); // tainted [NOT DETECTED] + sink(ss2.str()); // tainted sink(ss3.str()); // tainted [NOT DETECTED] - sink(ss4.str()); // tainted [NOT DETECTED] + sink(ss4.str()); // tainted sink(ss5.str()); // tainted [NOT DETECTED] } diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected index 8c60da2565b..66d5286381c 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected @@ -197,8 +197,10 @@ | globals.cpp:23:15:23:20 | call to getenv | globals.cpp:23:15:23:20 | call to getenv | | stl.cpp:62:25:62:30 | call to getenv | shared.h:5:23:5:31 | sinkparam | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:21:29:21:29 | s | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:43:78:43:104 | p#0 | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:43:114:43:118 | p#1 | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:62:25:62:30 | call to getenv | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:64:36:64:36 | s | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:68:8:68:8 | a | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:68:12:68:17 | call to source | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:70:16:70:21 | call to source | @@ -209,12 +211,31 @@ | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:82:16:82:21 | call to source | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:82:16:82:23 | (const char *)... | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:82:16:82:24 | call to basic_string | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:85:6:85:6 | call to operator<< | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:85:6:85:17 | (reference dereference) | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:85:9:85:14 | call to source | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:85:9:85:16 | (const char *)... | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:86:15:86:15 | call to operator<< | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:86:15:86:26 | (reference dereference) | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:86:18:86:23 | call to source | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:86:18:86:25 | (const char *)... | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:6:87:6 | call to operator<< | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:6:87:19 | (reference dereference) | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:6:87:19 | (reference to) | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:9:87:14 | call to source | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:9:87:16 | (const char *)... | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:18:87:18 | call to operator<< | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:18:87:26 | (reference dereference) | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:91:7:91:9 | (const stringstream)... | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:91:7:91:9 | (reference to) | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:91:7:91:9 | ss2 | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:93:7:93:9 | (const stringstream)... | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:93:7:93:9 | (reference to) | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:93:7:93:9 | ss4 | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:96:7:96:9 | (const basic_stringstream, allocator>)... | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:96:7:96:9 | ss2 | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:98:7:98:9 | (const basic_stringstream, allocator>)... | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:98:7:98:9 | ss4 | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:118:10:118:15 | call to source | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:125:16:125:28 | call to basic_string | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:125:17:125:26 | call to user_input | diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/test_diff.expected b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/test_diff.expected index 88e5173b822..6056b473e7c 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/test_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/test_diff.expected @@ -61,10 +61,31 @@ | defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:210:8:210:23 | ... + ... | IR only | | globals.cpp:13:15:13:20 | call to getenv | globals.cpp:13:5:13:11 | global1 | AST only | | globals.cpp:23:15:23:20 | call to getenv | globals.cpp:23:5:23:11 | global2 | AST only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:43:78:43:104 | p#0 | IR only | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:62:7:62:12 | source | AST only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:64:36:64:36 | s | IR only | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:70:16:70:24 | call to basic_string | IR only | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:82:16:82:24 | call to basic_string | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:85:6:85:6 | call to operator<< | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:85:6:85:17 | (reference dereference) | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:86:15:86:15 | call to operator<< | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:86:15:86:26 | (reference dereference) | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:6:87:6 | call to operator<< | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:6:87:19 | (reference dereference) | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:6:87:19 | (reference to) | IR only | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:9:87:16 | (const char *)... | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:18:87:18 | call to operator<< | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:18:87:26 | (reference dereference) | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:91:7:91:9 | (const stringstream)... | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:91:7:91:9 | (reference to) | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:91:7:91:9 | ss2 | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:93:7:93:9 | (const stringstream)... | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:93:7:93:9 | (reference to) | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:93:7:93:9 | ss4 | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:96:7:96:9 | (const basic_stringstream, allocator>)... | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:96:7:96:9 | ss2 | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:98:7:98:9 | (const basic_stringstream, allocator>)... | IR only | +| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:98:7:98:9 | ss4 | IR only | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:117:7:117:16 | user_input | AST only | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:125:16:125:28 | call to basic_string | IR only | | stl.cpp:62:25:62:30 | call to getenv | stl.cpp:128:9:128:13 | path2 | IR only | 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 801abbe7e35..2152d12ab49 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -501,12 +501,12 @@ | standalone_iterators.cpp:51:37:51:43 | source1 | standalone_iterators.cpp:53:12:53:18 | source1 | | | standalone_iterators.cpp:51:37:51:43 | source1 | standalone_iterators.cpp:54:14:54:20 | source1 | | | standalone_iterators.cpp:53:12:53:18 | ref arg source1 | standalone_iterators.cpp:54:14:54:20 | source1 | | -| stl.h:179:30:179:40 | call to allocator | stl.h:179:21:179:41 | noexcept(...) | TAINT | -| stl.h:179:30:179:40 | call to allocator | stl.h:179:21:179:41 | noexcept(...) | TAINT | -| stl.h:179:30:179:40 | call to allocator | stl.h:179:21:179:41 | noexcept(...) | TAINT | -| stl.h:179:30:179:40 | call to allocator | stl.h:179:21:179:41 | noexcept(...) | TAINT | -| stl.h:179:30:179:40 | call to allocator | stl.h:179:21:179:41 | noexcept(...) | TAINT | -| stl.h:179:53:179:63 | 0 | stl.h:179:46:179:64 | (no string representation) | TAINT | +| stl.h:204:30:204:40 | call to allocator | stl.h:204:21:204:41 | noexcept(...) | TAINT | +| stl.h:204:30:204:40 | call to allocator | stl.h:204:21:204:41 | noexcept(...) | TAINT | +| stl.h:204:30:204:40 | call to allocator | stl.h:204:21:204:41 | noexcept(...) | TAINT | +| stl.h:204:30:204:40 | call to allocator | stl.h:204:21:204:41 | noexcept(...) | TAINT | +| stl.h:204:30:204:40 | call to allocator | stl.h:204:21:204:41 | noexcept(...) | TAINT | +| stl.h:204:53:204:63 | 0 | stl.h:204:46:204:64 | (no string representation) | TAINT | | string.cpp:24:12:24:17 | call to source | string.cpp:28:7:28:7 | a | | | string.cpp:25:16:25:20 | 123 | string.cpp:25:16:25:21 | call to basic_string | TAINT | | string.cpp:25:16:25:21 | call to basic_string | string.cpp:29:7:29:7 | b | | @@ -1396,44 +1396,372 @@ | string.cpp:551:35:551:38 | call to basic_string | string.cpp:551:11:551:16 | ref arg call to assign | TAINT | | string.cpp:551:35:551:38 | call to basic_string | string.cpp:551:28:551:33 | call to assign | TAINT | | string.cpp:551:35:551:38 | ff | string.cpp:551:35:551:38 | call to basic_string | TAINT | -| stringstream.cpp:13:20:13:22 | call to basic_stringstream | stringstream.cpp:16:2:16:4 | ss1 | | -| stringstream.cpp:13:20:13:22 | call to basic_stringstream | stringstream.cpp:22:7:22:9 | ss1 | | -| stringstream.cpp:13:20:13:22 | call to basic_stringstream | stringstream.cpp:27:7:27:9 | ss1 | | -| stringstream.cpp:13:25:13:27 | call to basic_stringstream | stringstream.cpp:17:2:17:4 | ss2 | | -| stringstream.cpp:13:25:13:27 | call to basic_stringstream | stringstream.cpp:23:7:23:9 | ss2 | | -| stringstream.cpp:13:25:13:27 | call to basic_stringstream | stringstream.cpp:28:7:28:9 | ss2 | | -| stringstream.cpp:13:30:13:32 | call to basic_stringstream | stringstream.cpp:18:2:18:4 | ss3 | | -| stringstream.cpp:13:30:13:32 | call to basic_stringstream | stringstream.cpp:24:7:24:9 | ss3 | | -| stringstream.cpp:13:30:13:32 | call to basic_stringstream | stringstream.cpp:29:7:29:9 | ss3 | | -| stringstream.cpp:13:35:13:37 | call to basic_stringstream | stringstream.cpp:19:2:19:4 | ss4 | | -| stringstream.cpp:13:35:13:37 | call to basic_stringstream | stringstream.cpp:25:7:25:9 | ss4 | | -| stringstream.cpp:13:35:13:37 | call to basic_stringstream | stringstream.cpp:30:7:30:9 | ss4 | | -| stringstream.cpp:13:40:13:42 | call to basic_stringstream | stringstream.cpp:20:2:20:4 | ss5 | | -| stringstream.cpp:13:40:13:42 | call to basic_stringstream | stringstream.cpp:26:7:26:9 | ss5 | | -| stringstream.cpp:13:40:13:42 | call to basic_stringstream | stringstream.cpp:31:7:31:9 | ss5 | | -| stringstream.cpp:14:16:14:21 | call to source | stringstream.cpp:14:16:14:24 | call to basic_string | TAINT | -| stringstream.cpp:14:16:14:24 | call to basic_string | stringstream.cpp:20:9:20:9 | t | | -| stringstream.cpp:16:2:16:4 | ref arg ss1 | stringstream.cpp:22:7:22:9 | ss1 | | -| stringstream.cpp:16:2:16:4 | ref arg ss1 | stringstream.cpp:27:7:27:9 | ss1 | | -| stringstream.cpp:17:2:17:4 | ref arg ss2 | stringstream.cpp:23:7:23:9 | ss2 | | -| stringstream.cpp:17:2:17:4 | ref arg ss2 | stringstream.cpp:28:7:28:9 | ss2 | | -| stringstream.cpp:18:2:18:4 | ref arg ss3 | stringstream.cpp:24:7:24:9 | ss3 | | -| stringstream.cpp:18:2:18:4 | ref arg ss3 | stringstream.cpp:29:7:29:9 | ss3 | | -| stringstream.cpp:19:2:19:4 | ref arg ss4 | stringstream.cpp:25:7:25:9 | ss4 | | -| stringstream.cpp:19:2:19:4 | ref arg ss4 | stringstream.cpp:30:7:30:9 | ss4 | | -| stringstream.cpp:20:2:20:4 | ref arg ss5 | stringstream.cpp:26:7:26:9 | ss5 | | -| stringstream.cpp:20:2:20:4 | ref arg ss5 | stringstream.cpp:31:7:31:9 | ss5 | | -| stringstream.cpp:34:32:34:37 | source | stringstream.cpp:39:9:39:14 | source | | -| stringstream.cpp:36:20:36:22 | call to basic_stringstream | stringstream.cpp:38:2:38:4 | ss1 | | -| stringstream.cpp:36:20:36:22 | call to basic_stringstream | stringstream.cpp:41:7:41:9 | ss1 | | -| stringstream.cpp:36:20:36:22 | call to basic_stringstream | stringstream.cpp:43:7:43:9 | ss1 | | -| stringstream.cpp:36:25:36:27 | call to basic_stringstream | stringstream.cpp:39:2:39:4 | ss2 | | -| stringstream.cpp:36:25:36:27 | call to basic_stringstream | stringstream.cpp:42:7:42:9 | ss2 | | -| stringstream.cpp:36:25:36:27 | call to basic_stringstream | stringstream.cpp:44:7:44:9 | ss2 | | -| stringstream.cpp:38:2:38:4 | ref arg ss1 | stringstream.cpp:41:7:41:9 | ss1 | | -| stringstream.cpp:38:2:38:4 | ref arg ss1 | stringstream.cpp:43:7:43:9 | ss1 | | -| stringstream.cpp:39:2:39:4 | ref arg ss2 | stringstream.cpp:42:7:42:9 | ss2 | | -| stringstream.cpp:39:2:39:4 | ref arg ss2 | stringstream.cpp:44:7:44:9 | ss2 | | +| stringstream.cpp:26:35:26:40 | amount | stringstream.cpp:64:46:64:51 | amount | | +| stringstream.cpp:28:20:28:22 | call to basic_stringstream | stringstream.cpp:31:7:31:9 | ss1 | | +| stringstream.cpp:28:20:28:22 | call to basic_stringstream | stringstream.cpp:37:7:37:9 | ss1 | | +| stringstream.cpp:28:20:28:22 | call to basic_stringstream | stringstream.cpp:42:7:42:9 | ss1 | | +| stringstream.cpp:28:25:28:27 | call to basic_stringstream | stringstream.cpp:32:7:32:9 | ss2 | | +| stringstream.cpp:28:25:28:27 | call to basic_stringstream | stringstream.cpp:38:7:38:9 | ss2 | | +| stringstream.cpp:28:25:28:27 | call to basic_stringstream | stringstream.cpp:43:7:43:9 | ss2 | | +| stringstream.cpp:28:30:28:32 | call to basic_stringstream | stringstream.cpp:33:7:33:9 | ss3 | | +| stringstream.cpp:28:30:28:32 | call to basic_stringstream | stringstream.cpp:39:7:39:9 | ss3 | | +| stringstream.cpp:28:30:28:32 | call to basic_stringstream | stringstream.cpp:44:7:44:9 | ss3 | | +| stringstream.cpp:28:35:28:37 | call to basic_stringstream | stringstream.cpp:34:7:34:9 | ss4 | | +| stringstream.cpp:28:35:28:37 | call to basic_stringstream | stringstream.cpp:40:7:40:9 | ss4 | | +| stringstream.cpp:28:35:28:37 | call to basic_stringstream | stringstream.cpp:45:7:45:9 | ss4 | | +| stringstream.cpp:28:40:28:42 | call to basic_stringstream | stringstream.cpp:35:7:35:9 | ss5 | | +| stringstream.cpp:28:40:28:42 | call to basic_stringstream | stringstream.cpp:41:7:41:9 | ss5 | | +| stringstream.cpp:28:40:28:42 | call to basic_stringstream | stringstream.cpp:46:7:46:9 | ss5 | | +| stringstream.cpp:28:45:28:47 | call to basic_stringstream | stringstream.cpp:48:2:48:4 | ss6 | | +| stringstream.cpp:28:45:28:47 | call to basic_stringstream | stringstream.cpp:49:2:49:4 | ss6 | | +| stringstream.cpp:28:45:28:47 | call to basic_stringstream | stringstream.cpp:52:7:52:9 | ss6 | | +| stringstream.cpp:28:50:28:52 | call to basic_stringstream | stringstream.cpp:50:2:50:4 | ss7 | | +| stringstream.cpp:28:50:28:52 | call to basic_stringstream | stringstream.cpp:51:2:51:4 | ss7 | | +| stringstream.cpp:28:50:28:52 | call to basic_stringstream | stringstream.cpp:53:7:53:9 | ss7 | | +| stringstream.cpp:28:55:28:57 | call to basic_stringstream | stringstream.cpp:55:7:55:9 | ss8 | | +| stringstream.cpp:28:55:28:57 | call to basic_stringstream | stringstream.cpp:58:7:58:9 | ss8 | | +| stringstream.cpp:28:60:28:62 | call to basic_stringstream | stringstream.cpp:56:7:56:9 | ss9 | | +| stringstream.cpp:28:60:28:62 | call to basic_stringstream | stringstream.cpp:59:7:59:9 | ss9 | | +| stringstream.cpp:28:65:28:68 | call to basic_stringstream | stringstream.cpp:57:7:57:10 | ss10 | | +| stringstream.cpp:28:65:28:68 | call to basic_stringstream | stringstream.cpp:60:7:60:10 | ss10 | | +| stringstream.cpp:28:71:28:74 | call to basic_stringstream | stringstream.cpp:62:7:62:10 | ss11 | | +| stringstream.cpp:28:71:28:74 | call to basic_stringstream | stringstream.cpp:65:7:65:10 | ss11 | | +| stringstream.cpp:28:77:28:80 | call to basic_stringstream | stringstream.cpp:63:7:63:10 | ss12 | | +| stringstream.cpp:28:77:28:80 | call to basic_stringstream | stringstream.cpp:66:7:66:10 | ss12 | | +| stringstream.cpp:28:83:28:86 | call to basic_stringstream | stringstream.cpp:64:7:64:10 | ss13 | | +| stringstream.cpp:28:83:28:86 | call to basic_stringstream | stringstream.cpp:67:7:67:10 | ss13 | | +| stringstream.cpp:29:16:29:21 | call to source | stringstream.cpp:29:16:29:24 | call to basic_string | TAINT | +| stringstream.cpp:29:16:29:24 | call to basic_string | stringstream.cpp:35:14:35:14 | t | | +| stringstream.cpp:31:7:31:9 | ref arg ss1 | stringstream.cpp:37:7:37:9 | ss1 | | +| stringstream.cpp:31:7:31:9 | ref arg ss1 | stringstream.cpp:42:7:42:9 | ss1 | | +| stringstream.cpp:31:7:31:9 | ss1 | stringstream.cpp:31:11:31:11 | call to operator<< | | +| stringstream.cpp:31:14:31:19 | 1234 | stringstream.cpp:31:7:31:9 | ref arg ss1 | TAINT | +| stringstream.cpp:31:14:31:19 | 1234 | stringstream.cpp:31:11:31:11 | call to operator<< | TAINT | +| stringstream.cpp:32:7:32:9 | ref arg ss2 | stringstream.cpp:38:7:38:9 | ss2 | | +| stringstream.cpp:32:7:32:9 | ref arg ss2 | stringstream.cpp:43:7:43:9 | ss2 | | +| stringstream.cpp:32:7:32:9 | ss2 | stringstream.cpp:32:11:32:11 | call to operator<< | | +| stringstream.cpp:32:14:32:19 | call to source | stringstream.cpp:32:7:32:9 | ref arg ss2 | TAINT | +| stringstream.cpp:32:14:32:19 | call to source | stringstream.cpp:32:11:32:11 | call to operator<< | TAINT | +| stringstream.cpp:33:7:33:9 | ref arg ss3 | stringstream.cpp:39:7:39:9 | ss3 | | +| stringstream.cpp:33:7:33:9 | ref arg ss3 | stringstream.cpp:44:7:44:9 | ss3 | | +| stringstream.cpp:33:7:33:9 | ss3 | stringstream.cpp:33:11:33:11 | call to operator<< | | +| stringstream.cpp:33:11:33:11 | call to operator<< | stringstream.cpp:33:20:33:20 | call to operator<< | | +| stringstream.cpp:33:11:33:11 | ref arg call to operator<< | stringstream.cpp:33:7:33:9 | ref arg ss3 | TAINT | +| stringstream.cpp:33:14:33:18 | 123 | stringstream.cpp:33:7:33:9 | ref arg ss3 | TAINT | +| stringstream.cpp:33:14:33:18 | 123 | stringstream.cpp:33:11:33:11 | call to operator<< | TAINT | +| stringstream.cpp:33:23:33:28 | call to source | stringstream.cpp:33:11:33:11 | ref arg call to operator<< | TAINT | +| stringstream.cpp:33:23:33:28 | call to source | stringstream.cpp:33:20:33:20 | call to operator<< | TAINT | +| stringstream.cpp:34:7:34:9 | ref arg ss4 | stringstream.cpp:40:7:40:9 | ss4 | | +| stringstream.cpp:34:7:34:9 | ref arg ss4 | stringstream.cpp:45:7:45:9 | ss4 | | +| stringstream.cpp:34:7:34:9 | ss4 | stringstream.cpp:34:11:34:11 | call to operator<< | | +| stringstream.cpp:34:11:34:11 | call to operator<< | stringstream.cpp:34:23:34:23 | call to operator<< | | +| stringstream.cpp:34:11:34:11 | ref arg call to operator<< | stringstream.cpp:34:7:34:9 | ref arg ss4 | TAINT | +| stringstream.cpp:34:14:34:19 | call to source | stringstream.cpp:34:7:34:9 | ref arg ss4 | TAINT | +| stringstream.cpp:34:14:34:19 | call to source | stringstream.cpp:34:11:34:11 | call to operator<< | TAINT | +| stringstream.cpp:34:26:34:30 | 456 | stringstream.cpp:34:11:34:11 | ref arg call to operator<< | TAINT | +| stringstream.cpp:34:26:34:30 | 456 | stringstream.cpp:34:23:34:23 | call to operator<< | TAINT | +| stringstream.cpp:35:7:35:9 | ref arg ss5 | stringstream.cpp:41:7:41:9 | ss5 | | +| stringstream.cpp:35:7:35:9 | ref arg ss5 | stringstream.cpp:46:7:46:9 | ss5 | | +| stringstream.cpp:35:7:35:9 | ss5 | stringstream.cpp:35:11:35:11 | call to operator<< | | +| stringstream.cpp:35:14:35:14 | t | stringstream.cpp:35:7:35:9 | ref arg ss5 | TAINT | +| stringstream.cpp:35:14:35:14 | t | stringstream.cpp:35:11:35:11 | call to operator<< | TAINT | +| stringstream.cpp:48:2:48:4 | ref arg ss6 | stringstream.cpp:49:2:49:4 | ss6 | | +| stringstream.cpp:48:2:48:4 | ref arg ss6 | stringstream.cpp:52:7:52:9 | ss6 | | +| stringstream.cpp:48:10:48:14 | abc | stringstream.cpp:48:10:48:14 | call to basic_string | TAINT | +| stringstream.cpp:49:2:49:4 | ref arg ss6 | stringstream.cpp:52:7:52:9 | ss6 | | +| stringstream.cpp:49:10:49:15 | call to source | stringstream.cpp:49:10:49:17 | call to basic_string | TAINT | +| stringstream.cpp:50:2:50:4 | ref arg ss7 | stringstream.cpp:51:2:51:4 | ss7 | | +| stringstream.cpp:50:2:50:4 | ref arg ss7 | stringstream.cpp:53:7:53:9 | ss7 | | +| stringstream.cpp:50:10:50:15 | call to source | stringstream.cpp:50:10:50:17 | call to basic_string | TAINT | +| stringstream.cpp:51:2:51:4 | ref arg ss7 | stringstream.cpp:53:7:53:9 | ss7 | | +| stringstream.cpp:51:10:51:14 | abc | stringstream.cpp:51:10:51:14 | call to basic_string | TAINT | +| stringstream.cpp:55:7:55:9 | ref arg ss8 | stringstream.cpp:58:7:58:9 | ss8 | | +| stringstream.cpp:56:7:56:9 | ref arg ss9 | stringstream.cpp:59:7:59:9 | ss9 | | +| stringstream.cpp:57:7:57:10 | ref arg ss10 | stringstream.cpp:60:7:60:10 | ss10 | | +| stringstream.cpp:62:7:62:10 | ref arg ss11 | stringstream.cpp:65:7:65:10 | ss11 | | +| stringstream.cpp:63:7:63:10 | ref arg ss12 | stringstream.cpp:66:7:66:10 | ss12 | | +| stringstream.cpp:64:7:64:10 | ref arg ss13 | stringstream.cpp:67:7:67:10 | ss13 | | +| stringstream.cpp:70:32:70:37 | source | stringstream.cpp:76:14:76:19 | source | | +| stringstream.cpp:72:20:72:22 | call to basic_stringstream | stringstream.cpp:75:7:75:9 | ss1 | | +| stringstream.cpp:72:20:72:22 | call to basic_stringstream | stringstream.cpp:77:7:77:9 | ss1 | | +| stringstream.cpp:72:20:72:22 | call to basic_stringstream | stringstream.cpp:80:7:80:9 | ss1 | | +| stringstream.cpp:72:20:72:22 | call to basic_stringstream | stringstream.cpp:82:7:82:9 | ss1 | | +| stringstream.cpp:72:25:72:27 | call to basic_stringstream | stringstream.cpp:76:7:76:9 | ss2 | | +| stringstream.cpp:72:25:72:27 | call to basic_stringstream | stringstream.cpp:78:7:78:9 | ss2 | | +| stringstream.cpp:72:25:72:27 | call to basic_stringstream | stringstream.cpp:81:7:81:9 | ss2 | | +| stringstream.cpp:72:25:72:27 | call to basic_stringstream | stringstream.cpp:83:7:83:9 | ss2 | | +| stringstream.cpp:73:10:73:11 | 0 | stringstream.cpp:77:14:77:15 | v1 | | +| stringstream.cpp:73:10:73:11 | 0 | stringstream.cpp:84:7:84:8 | v1 | | +| stringstream.cpp:73:18:73:19 | 0 | stringstream.cpp:78:14:78:15 | v2 | | +| stringstream.cpp:73:18:73:19 | 0 | stringstream.cpp:85:7:85:8 | v2 | | +| stringstream.cpp:75:7:75:9 | ref arg ss1 | stringstream.cpp:77:7:77:9 | ss1 | | +| stringstream.cpp:75:7:75:9 | ref arg ss1 | stringstream.cpp:80:7:80:9 | ss1 | | +| stringstream.cpp:75:7:75:9 | ref arg ss1 | stringstream.cpp:82:7:82:9 | ss1 | | +| stringstream.cpp:75:14:75:17 | 1234 | stringstream.cpp:75:7:75:9 | ref arg ss1 | TAINT | +| stringstream.cpp:75:14:75:17 | 1234 | stringstream.cpp:75:11:75:11 | call to operator<< | TAINT | +| stringstream.cpp:76:7:76:9 | ref arg ss2 | stringstream.cpp:78:7:78:9 | ss2 | | +| stringstream.cpp:76:7:76:9 | ref arg ss2 | stringstream.cpp:81:7:81:9 | ss2 | | +| stringstream.cpp:76:7:76:9 | ref arg ss2 | stringstream.cpp:83:7:83:9 | ss2 | | +| stringstream.cpp:76:14:76:19 | source | stringstream.cpp:76:7:76:9 | ref arg ss2 | TAINT | +| stringstream.cpp:76:14:76:19 | source | stringstream.cpp:76:11:76:11 | call to operator<< | TAINT | +| stringstream.cpp:77:7:77:9 | ref arg ss1 | stringstream.cpp:80:7:80:9 | ss1 | | +| stringstream.cpp:77:7:77:9 | ref arg ss1 | stringstream.cpp:82:7:82:9 | ss1 | | +| stringstream.cpp:77:14:77:15 | ref arg v1 | stringstream.cpp:84:7:84:8 | v1 | | +| stringstream.cpp:78:7:78:9 | ref arg ss2 | stringstream.cpp:81:7:81:9 | ss2 | | +| stringstream.cpp:78:7:78:9 | ref arg ss2 | stringstream.cpp:83:7:83:9 | ss2 | | +| stringstream.cpp:78:14:78:15 | ref arg v2 | stringstream.cpp:85:7:85:8 | v2 | | +| stringstream.cpp:90:18:90:23 | call to basic_string | stringstream.cpp:92:24:92:25 | s1 | | +| stringstream.cpp:90:19:90:23 | abc | stringstream.cpp:90:18:90:23 | call to basic_string | TAINT | +| stringstream.cpp:91:18:91:26 | call to basic_string | stringstream.cpp:93:24:93:25 | s2 | | +| stringstream.cpp:91:19:91:24 | call to source | stringstream.cpp:91:18:91:26 | call to basic_string | TAINT | +| stringstream.cpp:92:24:92:26 | call to basic_stringstream | stringstream.cpp:102:7:102:9 | ss1 | | +| stringstream.cpp:93:24:93:26 | call to basic_stringstream | stringstream.cpp:103:7:103:9 | ss2 | | +| stringstream.cpp:94:25:94:49 | call to basic_stringstream | stringstream.cpp:104:7:104:9 | ss3 | | +| stringstream.cpp:94:44:94:48 | abc | stringstream.cpp:94:44:94:48 | call to basic_string | TAINT | +| stringstream.cpp:95:25:95:52 | call to basic_stringstream | stringstream.cpp:105:7:105:9 | ss4 | | +| stringstream.cpp:95:44:95:49 | call to source | stringstream.cpp:95:44:95:51 | call to basic_string | TAINT | +| stringstream.cpp:96:20:96:22 | call to basic_stringstream | stringstream.cpp:99:7:99:9 | ss5 | | +| stringstream.cpp:96:20:96:22 | call to basic_stringstream | stringstream.cpp:106:7:106:9 | ss5 | | +| stringstream.cpp:97:20:97:22 | call to basic_stringstream | stringstream.cpp:100:7:100:9 | ss6 | | +| stringstream.cpp:97:20:97:22 | call to basic_stringstream | stringstream.cpp:107:7:107:9 | ss6 | | +| stringstream.cpp:99:7:99:9 | ref arg ss5 | stringstream.cpp:106:7:106:9 | ss5 | | +| stringstream.cpp:99:13:99:36 | call to basic_stringstream | stringstream.cpp:99:7:99:9 | ref arg ss5 | TAINT | +| stringstream.cpp:99:13:99:36 | call to basic_stringstream | stringstream.cpp:99:11:99:11 | call to operator= | TAINT | +| stringstream.cpp:99:31:99:35 | abc | stringstream.cpp:99:31:99:35 | call to basic_string | TAINT | +| stringstream.cpp:100:7:100:9 | ref arg ss6 | stringstream.cpp:107:7:107:9 | ss6 | | +| stringstream.cpp:100:13:100:39 | call to basic_stringstream | stringstream.cpp:100:7:100:9 | ref arg ss6 | TAINT | +| stringstream.cpp:100:13:100:39 | call to basic_stringstream | stringstream.cpp:100:11:100:11 | call to operator= | TAINT | +| stringstream.cpp:100:31:100:36 | call to source | stringstream.cpp:100:31:100:38 | call to basic_string | TAINT | +| stringstream.cpp:112:24:112:28 | abc | stringstream.cpp:112:24:112:28 | call to basic_string | TAINT | +| stringstream.cpp:112:24:112:29 | call to basic_stringstream | stringstream.cpp:117:2:117:4 | ss1 | | +| stringstream.cpp:112:24:112:29 | call to basic_stringstream | stringstream.cpp:120:7:120:9 | ss1 | | +| stringstream.cpp:113:24:113:29 | call to source | stringstream.cpp:113:24:113:31 | call to basic_string | TAINT | +| stringstream.cpp:113:24:113:32 | call to basic_stringstream | stringstream.cpp:117:11:117:13 | ss2 | | +| stringstream.cpp:113:24:113:32 | call to basic_stringstream | stringstream.cpp:121:7:121:9 | ss2 | | +| stringstream.cpp:114:24:114:28 | abc | stringstream.cpp:114:24:114:28 | call to basic_string | TAINT | +| stringstream.cpp:114:24:114:29 | call to basic_stringstream | stringstream.cpp:118:11:118:13 | ss3 | | +| stringstream.cpp:114:24:114:29 | call to basic_stringstream | stringstream.cpp:122:7:122:9 | ss3 | | +| stringstream.cpp:115:24:115:29 | call to source | stringstream.cpp:115:24:115:31 | call to basic_string | TAINT | +| stringstream.cpp:115:24:115:32 | call to basic_stringstream | stringstream.cpp:118:2:118:4 | ss4 | | +| stringstream.cpp:115:24:115:32 | call to basic_stringstream | stringstream.cpp:123:7:123:9 | ss4 | | +| stringstream.cpp:117:2:117:4 | ref arg ss1 | stringstream.cpp:120:7:120:9 | ss1 | | +| stringstream.cpp:117:11:117:13 | ref arg ss2 | stringstream.cpp:121:7:121:9 | ss2 | | +| stringstream.cpp:118:2:118:4 | ref arg ss4 | stringstream.cpp:123:7:123:9 | ss4 | | +| stringstream.cpp:118:11:118:13 | ref arg ss3 | stringstream.cpp:122:7:122:9 | ss3 | | +| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:142:7:142:9 | ss1 | | +| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:145:7:145:9 | ss1 | | +| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:153:7:153:9 | ss1 | | +| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:161:7:161:9 | ss1 | | +| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:163:7:163:9 | ss1 | | +| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:165:7:165:9 | ss1 | | +| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:174:12:174:14 | ss1 | | +| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:176:12:176:14 | ss1 | | +| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:178:7:178:9 | ss1 | | +| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:143:7:143:9 | ss2 | | +| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:146:7:146:9 | ss2 | | +| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:147:7:147:9 | ss2 | | +| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:154:7:154:9 | ss2 | | +| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:155:7:155:9 | ss2 | | +| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:162:7:162:9 | ss2 | | +| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:164:7:164:9 | ss2 | | +| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:166:7:166:9 | ss2 | | +| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:175:12:175:14 | ss2 | | +| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:177:12:177:14 | ss2 | | +| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:179:7:179:9 | ss2 | | +| stringstream.cpp:129:14:129:15 | call to basic_string | stringstream.cpp:145:14:145:15 | s1 | | +| stringstream.cpp:129:14:129:15 | call to basic_string | stringstream.cpp:148:7:148:8 | s1 | | +| stringstream.cpp:129:18:129:19 | call to basic_string | stringstream.cpp:146:14:146:15 | s2 | | +| stringstream.cpp:129:18:129:19 | call to basic_string | stringstream.cpp:149:7:149:8 | s2 | | +| stringstream.cpp:129:22:129:23 | call to basic_string | stringstream.cpp:147:14:147:15 | s3 | | +| stringstream.cpp:129:22:129:23 | call to basic_string | stringstream.cpp:150:7:150:8 | s3 | | +| stringstream.cpp:129:26:129:27 | call to basic_string | stringstream.cpp:147:20:147:21 | s4 | | +| stringstream.cpp:129:26:129:27 | call to basic_string | stringstream.cpp:151:7:151:8 | s4 | | +| stringstream.cpp:130:16:130:19 | {...} | stringstream.cpp:153:14:153:15 | b1 | | +| stringstream.cpp:130:16:130:19 | {...} | stringstream.cpp:156:7:156:8 | b1 | | +| stringstream.cpp:130:18:130:18 | 0 | stringstream.cpp:130:16:130:19 | {...} | TAINT | +| stringstream.cpp:131:16:131:19 | {...} | stringstream.cpp:154:14:154:15 | b2 | | +| stringstream.cpp:131:16:131:19 | {...} | stringstream.cpp:157:7:157:8 | b2 | | +| stringstream.cpp:131:18:131:18 | 0 | stringstream.cpp:131:16:131:19 | {...} | TAINT | +| stringstream.cpp:132:16:132:19 | {...} | stringstream.cpp:155:14:155:15 | b3 | | +| stringstream.cpp:132:16:132:19 | {...} | stringstream.cpp:158:7:158:8 | b3 | | +| stringstream.cpp:132:18:132:18 | 0 | stringstream.cpp:132:16:132:19 | {...} | TAINT | +| stringstream.cpp:133:16:133:19 | {...} | stringstream.cpp:155:20:155:21 | b4 | | +| stringstream.cpp:133:16:133:19 | {...} | stringstream.cpp:159:7:159:8 | b4 | | +| stringstream.cpp:133:18:133:18 | 0 | stringstream.cpp:133:16:133:19 | {...} | TAINT | +| stringstream.cpp:134:16:134:19 | {...} | stringstream.cpp:161:16:161:17 | b5 | | +| stringstream.cpp:134:16:134:19 | {...} | stringstream.cpp:167:7:167:8 | b5 | | +| stringstream.cpp:134:18:134:18 | 0 | stringstream.cpp:134:16:134:19 | {...} | TAINT | +| stringstream.cpp:135:16:135:19 | {...} | stringstream.cpp:162:16:162:17 | b6 | | +| stringstream.cpp:135:16:135:19 | {...} | stringstream.cpp:168:7:168:8 | b6 | | +| stringstream.cpp:135:18:135:18 | 0 | stringstream.cpp:135:16:135:19 | {...} | TAINT | +| stringstream.cpp:136:16:136:19 | {...} | stringstream.cpp:163:20:163:21 | b7 | | +| stringstream.cpp:136:16:136:19 | {...} | stringstream.cpp:169:7:169:8 | b7 | | +| stringstream.cpp:136:18:136:18 | 0 | stringstream.cpp:136:16:136:19 | {...} | TAINT | +| stringstream.cpp:137:16:137:19 | {...} | stringstream.cpp:164:20:164:21 | b8 | | +| stringstream.cpp:137:16:137:19 | {...} | stringstream.cpp:170:7:170:8 | b8 | | +| stringstream.cpp:137:18:137:18 | 0 | stringstream.cpp:137:16:137:19 | {...} | TAINT | +| stringstream.cpp:138:16:138:19 | {...} | stringstream.cpp:165:15:165:16 | b9 | | +| stringstream.cpp:138:16:138:19 | {...} | stringstream.cpp:171:7:171:8 | b9 | | +| stringstream.cpp:138:18:138:18 | 0 | stringstream.cpp:138:16:138:19 | {...} | TAINT | +| stringstream.cpp:139:17:139:20 | {...} | stringstream.cpp:166:15:166:17 | b10 | | +| stringstream.cpp:139:17:139:20 | {...} | stringstream.cpp:172:7:172:9 | b10 | | +| stringstream.cpp:139:19:139:19 | 0 | stringstream.cpp:139:17:139:20 | {...} | TAINT | +| stringstream.cpp:140:44:140:44 | 0 | stringstream.cpp:178:15:178:16 | c5 | | +| stringstream.cpp:140:44:140:44 | 0 | stringstream.cpp:184:7:184:8 | c5 | | +| stringstream.cpp:140:52:140:52 | 0 | stringstream.cpp:179:15:179:16 | c6 | | +| stringstream.cpp:140:52:140:52 | 0 | stringstream.cpp:185:7:185:8 | c6 | | +| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:145:7:145:9 | ss1 | | +| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:153:7:153:9 | ss1 | | +| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:161:7:161:9 | ss1 | | +| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:163:7:163:9 | ss1 | | +| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:165:7:165:9 | ss1 | | +| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:174:12:174:14 | ss1 | | +| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:176:12:176:14 | ss1 | | +| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | | +| stringstream.cpp:142:7:142:9 | ss1 | stringstream.cpp:142:11:142:11 | call to operator<< | | +| stringstream.cpp:142:14:142:18 | abc | stringstream.cpp:142:7:142:9 | ref arg ss1 | TAINT | +| stringstream.cpp:142:14:142:18 | abc | stringstream.cpp:142:11:142:11 | call to operator<< | TAINT | +| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:146:7:146:9 | ss2 | | +| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:147:7:147:9 | ss2 | | +| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:154:7:154:9 | ss2 | | +| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:155:7:155:9 | ss2 | | +| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:162:7:162:9 | ss2 | | +| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:164:7:164:9 | ss2 | | +| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:166:7:166:9 | ss2 | | +| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | | +| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | | +| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | | +| stringstream.cpp:143:7:143:9 | ss2 | stringstream.cpp:143:11:143:11 | call to operator<< | | +| stringstream.cpp:143:14:143:19 | call to source | stringstream.cpp:143:7:143:9 | ref arg ss2 | TAINT | +| stringstream.cpp:143:14:143:19 | call to source | stringstream.cpp:143:11:143:11 | call to operator<< | TAINT | +| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:153:7:153:9 | ss1 | | +| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:161:7:161:9 | ss1 | | +| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:163:7:163:9 | ss1 | | +| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:165:7:165:9 | ss1 | | +| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:174:12:174:14 | ss1 | | +| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:176:12:176:14 | ss1 | | +| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | | +| stringstream.cpp:145:14:145:15 | ref arg s1 | stringstream.cpp:148:7:148:8 | s1 | | +| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:147:7:147:9 | ss2 | | +| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:154:7:154:9 | ss2 | | +| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:155:7:155:9 | ss2 | | +| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:162:7:162:9 | ss2 | | +| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:164:7:164:9 | ss2 | | +| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:166:7:166:9 | ss2 | | +| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | | +| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | | +| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | | +| stringstream.cpp:146:14:146:15 | ref arg s2 | stringstream.cpp:149:7:149:8 | s2 | | +| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:154:7:154:9 | ss2 | | +| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:155:7:155:9 | ss2 | | +| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:162:7:162:9 | ss2 | | +| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:164:7:164:9 | ss2 | | +| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:166:7:166:9 | ss2 | | +| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | | +| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | | +| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | | +| stringstream.cpp:147:14:147:15 | ref arg s3 | stringstream.cpp:150:7:150:8 | s3 | | +| stringstream.cpp:147:20:147:21 | ref arg s4 | stringstream.cpp:151:7:151:8 | s4 | | +| stringstream.cpp:153:7:153:9 | ref arg ss1 | stringstream.cpp:161:7:161:9 | ss1 | | +| stringstream.cpp:153:7:153:9 | ref arg ss1 | stringstream.cpp:163:7:163:9 | ss1 | | +| stringstream.cpp:153:7:153:9 | ref arg ss1 | stringstream.cpp:165:7:165:9 | ss1 | | +| stringstream.cpp:153:7:153:9 | ref arg ss1 | stringstream.cpp:174:12:174:14 | ss1 | | +| stringstream.cpp:153:7:153:9 | ref arg ss1 | stringstream.cpp:176:12:176:14 | ss1 | | +| stringstream.cpp:153:7:153:9 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | | +| stringstream.cpp:153:14:153:15 | ref arg b1 | stringstream.cpp:156:7:156:8 | b1 | | +| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:155:7:155:9 | ss2 | | +| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:162:7:162:9 | ss2 | | +| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:164:7:164:9 | ss2 | | +| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:166:7:166:9 | ss2 | | +| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | | +| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | | +| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | | +| stringstream.cpp:154:14:154:15 | ref arg b2 | stringstream.cpp:157:7:157:8 | b2 | | +| stringstream.cpp:155:7:155:9 | ref arg ss2 | stringstream.cpp:162:7:162:9 | ss2 | | +| stringstream.cpp:155:7:155:9 | ref arg ss2 | stringstream.cpp:164:7:164:9 | ss2 | | +| stringstream.cpp:155:7:155:9 | ref arg ss2 | stringstream.cpp:166:7:166:9 | ss2 | | +| stringstream.cpp:155:7:155:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | | +| stringstream.cpp:155:7:155:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | | +| stringstream.cpp:155:7:155:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | | +| stringstream.cpp:155:14:155:15 | ref arg b3 | stringstream.cpp:158:7:158:8 | b3 | | +| stringstream.cpp:155:20:155:21 | ref arg b4 | stringstream.cpp:159:7:159:8 | b4 | | +| stringstream.cpp:156:7:156:8 | b1 | stringstream.cpp:156:7:156:8 | call to basic_string | TAINT | +| stringstream.cpp:157:7:157:8 | b2 | stringstream.cpp:157:7:157:8 | call to basic_string | TAINT | +| stringstream.cpp:158:7:158:8 | b3 | stringstream.cpp:158:7:158:8 | call to basic_string | TAINT | +| stringstream.cpp:159:7:159:8 | b4 | stringstream.cpp:159:7:159:8 | call to basic_string | TAINT | +| stringstream.cpp:161:7:161:9 | ref arg ss1 | stringstream.cpp:163:7:163:9 | ss1 | | +| stringstream.cpp:161:7:161:9 | ref arg ss1 | stringstream.cpp:165:7:165:9 | ss1 | | +| stringstream.cpp:161:7:161:9 | ref arg ss1 | stringstream.cpp:174:12:174:14 | ss1 | | +| stringstream.cpp:161:7:161:9 | ref arg ss1 | stringstream.cpp:176:12:176:14 | ss1 | | +| stringstream.cpp:161:7:161:9 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | | +| stringstream.cpp:161:16:161:17 | ref arg b5 | stringstream.cpp:167:7:167:8 | b5 | | +| stringstream.cpp:162:7:162:9 | ref arg ss2 | stringstream.cpp:164:7:164:9 | ss2 | | +| stringstream.cpp:162:7:162:9 | ref arg ss2 | stringstream.cpp:166:7:166:9 | ss2 | | +| stringstream.cpp:162:7:162:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | | +| stringstream.cpp:162:7:162:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | | +| stringstream.cpp:162:7:162:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | | +| stringstream.cpp:162:16:162:17 | ref arg b6 | stringstream.cpp:168:7:168:8 | b6 | | +| stringstream.cpp:163:7:163:9 | ref arg ss1 | stringstream.cpp:165:7:165:9 | ss1 | | +| stringstream.cpp:163:7:163:9 | ref arg ss1 | stringstream.cpp:174:12:174:14 | ss1 | | +| stringstream.cpp:163:7:163:9 | ref arg ss1 | stringstream.cpp:176:12:176:14 | ss1 | | +| stringstream.cpp:163:7:163:9 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | | +| stringstream.cpp:163:20:163:21 | ref arg b7 | stringstream.cpp:169:7:169:8 | b7 | | +| stringstream.cpp:164:7:164:9 | ref arg ss2 | stringstream.cpp:166:7:166:9 | ss2 | | +| stringstream.cpp:164:7:164:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | | +| stringstream.cpp:164:7:164:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | | +| stringstream.cpp:164:7:164:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | | +| stringstream.cpp:164:20:164:21 | ref arg b8 | stringstream.cpp:170:7:170:8 | b8 | | +| stringstream.cpp:165:7:165:9 | ref arg ss1 | stringstream.cpp:174:12:174:14 | ss1 | | +| stringstream.cpp:165:7:165:9 | ref arg ss1 | stringstream.cpp:176:12:176:14 | ss1 | | +| stringstream.cpp:165:7:165:9 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | | +| stringstream.cpp:165:15:165:16 | ref arg b9 | stringstream.cpp:171:7:171:8 | b9 | | +| stringstream.cpp:166:7:166:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | | +| stringstream.cpp:166:7:166:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | | +| stringstream.cpp:166:7:166:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | | +| stringstream.cpp:166:15:166:17 | ref arg b10 | stringstream.cpp:172:7:172:9 | b10 | | +| stringstream.cpp:167:7:167:8 | b5 | stringstream.cpp:167:7:167:8 | call to basic_string | TAINT | +| stringstream.cpp:168:7:168:8 | b6 | stringstream.cpp:168:7:168:8 | call to basic_string | TAINT | +| stringstream.cpp:169:7:169:8 | b7 | stringstream.cpp:169:7:169:8 | call to basic_string | TAINT | +| stringstream.cpp:170:7:170:8 | b8 | stringstream.cpp:170:7:170:8 | call to basic_string | TAINT | +| stringstream.cpp:171:7:171:8 | b9 | stringstream.cpp:171:7:171:8 | call to basic_string | TAINT | +| stringstream.cpp:172:7:172:9 | b10 | stringstream.cpp:172:7:172:9 | call to basic_string | TAINT | +| stringstream.cpp:174:12:174:14 | ref arg ss1 | stringstream.cpp:176:12:176:14 | ss1 | | +| stringstream.cpp:174:12:174:14 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | | +| stringstream.cpp:174:16:174:18 | call to get | stringstream.cpp:174:7:174:20 | ... = ... | | +| stringstream.cpp:174:16:174:18 | call to get | stringstream.cpp:180:7:180:8 | c1 | | +| stringstream.cpp:175:12:175:14 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | | +| stringstream.cpp:175:12:175:14 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | | +| stringstream.cpp:175:16:175:18 | call to get | stringstream.cpp:175:7:175:20 | ... = ... | | +| stringstream.cpp:175:16:175:18 | call to get | stringstream.cpp:181:7:181:8 | c2 | | +| stringstream.cpp:176:12:176:14 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | | +| stringstream.cpp:176:16:176:19 | call to peek | stringstream.cpp:176:7:176:21 | ... = ... | | +| stringstream.cpp:176:16:176:19 | call to peek | stringstream.cpp:182:7:182:8 | c3 | | +| stringstream.cpp:177:12:177:14 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | | +| stringstream.cpp:177:16:177:19 | call to peek | stringstream.cpp:177:7:177:21 | ... = ... | | +| stringstream.cpp:177:16:177:19 | call to peek | stringstream.cpp:183:7:183:8 | c4 | | +| stringstream.cpp:178:15:178:16 | ref arg c5 | stringstream.cpp:184:7:184:8 | c5 | | +| stringstream.cpp:179:15:179:16 | ref arg c6 | stringstream.cpp:185:7:185:8 | c6 | | +| stringstream.cpp:190:20:190:21 | call to basic_stringstream | stringstream.cpp:192:7:192:8 | ss | | +| stringstream.cpp:190:20:190:21 | call to basic_stringstream | stringstream.cpp:193:7:193:8 | ss | | +| stringstream.cpp:190:20:190:21 | call to basic_stringstream | stringstream.cpp:194:7:194:8 | ss | | +| stringstream.cpp:190:20:190:21 | call to basic_stringstream | stringstream.cpp:195:7:195:8 | ss | | +| stringstream.cpp:190:20:190:21 | call to basic_stringstream | stringstream.cpp:196:7:196:8 | ss | | +| stringstream.cpp:190:20:190:21 | call to basic_stringstream | stringstream.cpp:197:7:197:8 | ss | | +| stringstream.cpp:192:7:192:8 | ref arg ss | stringstream.cpp:193:7:193:8 | ss | | +| stringstream.cpp:192:7:192:8 | ref arg ss | stringstream.cpp:194:7:194:8 | ss | | +| stringstream.cpp:192:7:192:8 | ref arg ss | stringstream.cpp:195:7:195:8 | ss | | +| stringstream.cpp:192:7:192:8 | ref arg ss | stringstream.cpp:196:7:196:8 | ss | | +| stringstream.cpp:192:7:192:8 | ref arg ss | stringstream.cpp:197:7:197:8 | ss | | +| stringstream.cpp:193:7:193:8 | ref arg ss | stringstream.cpp:194:7:194:8 | ss | | +| stringstream.cpp:193:7:193:8 | ref arg ss | stringstream.cpp:195:7:195:8 | ss | | +| stringstream.cpp:193:7:193:8 | ref arg ss | stringstream.cpp:196:7:196:8 | ss | | +| stringstream.cpp:193:7:193:8 | ref arg ss | stringstream.cpp:197:7:197:8 | ss | | +| stringstream.cpp:194:7:194:8 | ref arg ss | stringstream.cpp:195:7:195:8 | ss | | +| stringstream.cpp:194:7:194:8 | ref arg ss | stringstream.cpp:196:7:196:8 | ss | | +| stringstream.cpp:194:7:194:8 | ref arg ss | stringstream.cpp:197:7:197:8 | ss | | +| stringstream.cpp:195:7:195:8 | ref arg ss | stringstream.cpp:196:7:196:8 | ss | | +| stringstream.cpp:195:7:195:8 | ref arg ss | stringstream.cpp:197:7:197:8 | ss | | +| stringstream.cpp:196:7:196:8 | ref arg ss | stringstream.cpp:197:7:197:8 | ss | | | structlikeclass.cpp:5:7:5:7 | Unknown literal | structlikeclass.cpp:5:7:5:7 | constructor init of field v | TAINT | | structlikeclass.cpp:5:7:5:7 | Unknown literal | structlikeclass.cpp:5:7:5:7 | constructor init of field v | TAINT | | structlikeclass.cpp:5:7:5:7 | this | structlikeclass.cpp:5:7:5:7 | constructor init of field v [pre-this] | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h b/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h index 992a97d1a32..6392b42e4b4 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h @@ -132,16 +132,33 @@ namespace std template > class basic_istream /*: virtual public basic_ios - not needed for this test */ { public: - basic_istream& operator>>(int& n); + using char_type = charT; + using int_type = int; //typename traits::int_type; + + basic_istream& operator>>(int& n); + + int_type get(); + basic_istream& get(char_type& c); + basic_istream& get(char_type* s, streamsize n); + int_type peek(); + basic_istream& read (char_type* s, streamsize n); + streamsize readsome(char_type* s, streamsize n); + basic_istream& putback(char_type c); + }; + template basic_istream& operator>>(basic_istream&, charT*); + template basic_istream& operator>>(basic_istream& is, basic_string& str); + template > class basic_ostream /*: virtual public basic_ios - not needed for this test */ { public: typedef charT char_type; - basic_ostream& write(const char_type* s, streamsize n); basic_ostream& operator<<(int n); + + basic_ostream& put(char_type c); + basic_ostream& write(const char_type* s, streamsize n); }; template basic_ostream& operator<<(basic_ostream&, const charT*); @@ -156,8 +173,16 @@ namespace std class basic_stringstream : public basic_iostream { public: explicit basic_stringstream(/*ios_base::openmode which = ios_base::out|ios_base::in - not needed for this test*/); + explicit basic_stringstream( const basic_string& str/*, ios_base::openmode which = ios_base::out | ios_base::in*/); + basic_stringstream(const basic_stringstream& rhs) = delete; + basic_stringstream(basic_stringstream&& rhs); + basic_stringstream& operator=(const basic_stringstream& rhs) = delete; + basic_stringstream& operator=(basic_stringstream&& rhs); + + void swap(basic_stringstream& rhs); basic_string str() const; + void str(const basic_string& str); }; using stringstream = basic_stringstream; diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp index 0656da01277..e656277c567 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp @@ -5,41 +5,194 @@ using namespace std; char *source(); -void sink(const std::string &s) {}; -void sink(const std::stringstream &s) {}; - -void test_stringstream() +namespace ns_char { - std::stringstream ss1, ss2, ss3, ss4, ss5; + char source(); +} + +void sink(int i) {}; + +void sink(const std::string &s) {}; + +template +void sink(const std::basic_ostream &s) {}; + +template +void sink(const std::basic_istream &s) {}; + +template +void sink(const std::basic_iostream &s) {}; + +void test_stringstream_string(int amount) +{ + std::stringstream ss1, ss2, ss3, ss4, ss5, ss6, ss7, ss8, ss9, ss10, ss11, ss12, ss13; std::string t(source()); - ss1 << "1234"; - ss2 << source(); - ss3 << "123" << source(); - ss4 << source() << "456"; - ss5 << t; + sink(ss1 << "1234"); + sink(ss2 << source()); // tainted + sink(ss3 << "123" << source()); // tainted + sink(ss4 << source() << "456"); // tainted + sink(ss5 << t); // tainted sink(ss1); - sink(ss2); // tainted [NOT DETECTED] - sink(ss3); // tainted [NOT DETECTED] - sink(ss4); // tainted [NOT DETECTED] - sink(ss5); // tainted [NOT DETECTED] + sink(ss2); // tainted + sink(ss3); // tainted + sink(ss4); // tainted + sink(ss5); // tainted sink(ss1.str()); sink(ss2.str()); // tainted [NOT DETECTED] sink(ss3.str()); // tainted [NOT DETECTED] sink(ss4.str()); // tainted [NOT DETECTED] sink(ss5.str()); // tainted [NOT DETECTED] + + ss6.str("abc"); + ss6.str(source()); // (overwrites) + ss7.str(source()); + ss7.str("abc"); // (overwrites) + sink(ss6); // tainted [NOT DETECTED] + sink(ss7); + + sink(ss8.put('a')); + sink(ss9.put(ns_char::source())); // tainted [NOT DETECTED] + sink(ss10.put('a').put(ns_char::source()).put('z')); // tainted [NOT DETECTED] + sink(ss8); + sink(ss9); // tainted [NOT DETECTED] + sink(ss10); // tainted [NOT DETECTED] + + sink(ss11.write("begin", 5)); + sink(ss12.write(source(), 5)); // tainted [NOT DETECTED] + sink(ss13.write("begin", 5).write(source(), amount).write("end", 3)); // tainted [NOT DETECTED] + sink(ss11); + sink(ss12); // tainted [NOT DETECTED] + sink(ss13); // tainted [NOT DETECTED] } void test_stringstream_int(int source) { std::stringstream ss1, ss2; + int v1 = 0, v2 = 0; - ss1 << 1234; - ss2 << source; + sink(ss1 << 1234); + sink(ss2 << source); // tainted + sink(ss1 >> v1); + sink(ss2 >> v2); // tainted [NOT DETECTED] + + sink(ss1); + sink(ss2); // tainted + sink(ss1.str()); + sink(ss2.str()); // tainted [NOT DETECTED] + sink(v1); + sink(v2); // tainted [NOT DETECTED] +} + +void test_stringstream_constructors() +{ + std::string s1 = "abc"; + std::string s2 = source(); + std::stringstream ss1(s1); + std::stringstream ss2(s2); + std::stringstream ss3 = std::stringstream("abc"); + std::stringstream ss4 = std::stringstream(source()); + std::stringstream ss5; + std::stringstream ss6; + + sink(ss5 = std::stringstream("abc")); + sink(ss6 = std::stringstream(source())); // tainted [NOT DETECTED] sink(ss1); sink(ss2); // tainted [NOT DETECTED] - sink(ss1.str()); - sink(ss2.str()); // tainted [NOT DETECTED] + sink(ss3); + sink(ss4); // tainted [NOT DETECTED] + sink(ss5); + sink(ss6); // tainted [NOT DETECTED] +} + +void test_stringstream_swap() +{ + std::stringstream ss1("abc"); + std::stringstream ss2(source()); + std::stringstream ss3("abc"); + std::stringstream ss4(source()); + + ss1.swap(ss2); + ss4.swap(ss3); + + sink(ss1); // tainted [NOT DETECTED] + sink(ss2); + sink(ss3); // tainted [NOT DETECTED] + sink(ss4); +} + +void test_stringstream_in() +{ + std::stringstream ss1, ss2; + std::string s1, s2, s3, s4; + char b1[100] = {0}; + char b2[100] = {0}; + char b3[100] = {0}; + char b4[100] = {0}; + char b5[100] = {0}; + char b6[100] = {0}; + char b7[100] = {0}; + char b8[100] = {0}; + char b9[100] = {0}; + char b10[100] = {0}; + char c1 = 0, c2 = 0, c3 = 0, c4 = 0, c5 = 0, c6 = 0; + + sink(ss1 << "abc"); + sink(ss2 << source()); // tainted + + sink(ss1 >> s1); + sink(ss2 >> s2); // tainted [NOT DETECTED] + sink(ss2 >> s3 >> s4); // tainted [NOT DETECTED] + sink(s1); + sink(s2); // tainted [NOT DETECTED] + sink(s3); // tainted [NOT DETECTED] + sink(s4); // tainted [NOT DETECTED] + + sink(ss1 >> b1); + sink(ss2 >> b2); + sink(ss2 >> b3 >> b4); + sink(b1); + sink(b2); // tainted [NOT DETECTED] + sink(b3); // tainted [NOT DETECTED] + sink(b4); // tainted [NOT DETECTED] + + sink(ss1.read(b5, 100)); + sink(ss2.read(b6, 100)); // tainted [NOT DETECTED] + sink(ss1.readsome(b7, 100)); + sink(ss2.readsome(b8, 100)); // (returns a length, not significantly tainted) + sink(ss1.get(b9, 100)); + sink(ss2.get(b10, 100)); + sink(b5); + sink(b6); // tainted [NOT DETECTED] + sink(b7); + sink(b8); // tainted [NOT DETECTED] + sink(b9); + sink(b10); // tainted [NOT DETECTED] + + sink(c1 = ss1.get()); + sink(c2 = ss2.get()); // tainted [NOT DETECTED] + sink(c3 = ss1.peek()); + sink(c4 = ss2.peek()); // tainted [NOT DETECTED] + sink(ss1.get(c5)); + sink(ss2.get(c6)); // tainted [NOT DETECTED] + sink(c1); + sink(c2); // tainted [NOT DETECTED] + sink(c3); + sink(c4); // tainted [NOT DETECTED] + sink(c5); + sink(c6); // tainted [NOT DETECTED] +} + +void test_stringstream_putback() +{ + std::stringstream ss; + + sink(ss.put('a')); + sink(ss.get()); + sink(ss.putback('b')); + sink(ss.get()); + sink(ss.putback(ns_char::source())); // tainted [NOT DETECTED] + sink(ss.get()); // tainted [NOT DETECTED] } 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 463fcb57415..03c5ed8b5e4 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -162,6 +162,17 @@ | string.cpp:555:8:555:8 | d | string.cpp:549:27:549:32 | call to source | | string.cpp:556:8:556:8 | e | string.cpp:550:31:550:36 | call to source | | string.cpp:557:8:557:8 | f | string.cpp:551:18:551:23 | call to source | +| stringstream.cpp:32:11:32:11 | call to operator<< | stringstream.cpp:32:14:32:19 | call to source | +| stringstream.cpp:33:20:33:20 | call to operator<< | stringstream.cpp:33:23:33:28 | call to source | +| stringstream.cpp:34:23:34:23 | call to operator<< | stringstream.cpp:34:14:34:19 | call to source | +| stringstream.cpp:35:11:35:11 | call to operator<< | stringstream.cpp:29:16:29:21 | call to source | +| stringstream.cpp:38:7:38:9 | ss2 | stringstream.cpp:32:14:32:19 | call to source | +| stringstream.cpp:39:7:39:9 | ss3 | stringstream.cpp:33:23:33:28 | call to source | +| stringstream.cpp:40:7:40:9 | ss4 | stringstream.cpp:34:14:34:19 | call to source | +| stringstream.cpp:41:7:41:9 | ss5 | stringstream.cpp:29:16:29:21 | call to source | +| stringstream.cpp:76:11:76:11 | call to operator<< | stringstream.cpp:70:32:70:37 | source | +| stringstream.cpp:81:7:81:9 | ss2 | stringstream.cpp:70:32:70:37 | source | +| stringstream.cpp:143:11:143:11 | call to operator<< | stringstream.cpp:143:14:143:19 | call to source | | structlikeclass.cpp:35:8:35:9 | s1 | structlikeclass.cpp:29:22:29:27 | call to source | | structlikeclass.cpp:36:8:36:9 | s2 | structlikeclass.cpp:30:24:30:29 | call to source | | structlikeclass.cpp:37:8:37:9 | s3 | structlikeclass.cpp:29:22:29:27 | call to source | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected index 9af7dffd8bb..0b817edb770 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected @@ -172,6 +172,25 @@ | string.cpp:555:8:555:8 | string.cpp:549:27:549:32 | AST only | | string.cpp:556:8:556:8 | string.cpp:550:31:550:36 | AST only | | string.cpp:557:8:557:8 | string.cpp:551:18:551:23 | AST only | +| stringstream.cpp:32:11:32:11 | stringstream.cpp:32:14:32:21 | IR only | +| stringstream.cpp:32:11:32:22 | stringstream.cpp:32:14:32:19 | IR only | +| stringstream.cpp:32:11:32:22 | stringstream.cpp:32:14:32:21 | IR only | +| stringstream.cpp:33:20:33:20 | stringstream.cpp:33:23:33:30 | IR only | +| stringstream.cpp:33:20:33:31 | stringstream.cpp:33:23:33:28 | IR only | +| stringstream.cpp:33:20:33:31 | stringstream.cpp:33:23:33:30 | IR only | +| stringstream.cpp:34:23:34:23 | stringstream.cpp:34:14:34:21 | IR only | +| stringstream.cpp:34:23:34:31 | stringstream.cpp:34:14:34:19 | IR only | +| stringstream.cpp:34:23:34:31 | stringstream.cpp:34:14:34:21 | IR only | +| stringstream.cpp:35:11:35:11 | stringstream.cpp:29:16:29:21 | AST only | +| stringstream.cpp:38:7:38:9 | stringstream.cpp:32:14:32:19 | AST only | +| stringstream.cpp:39:7:39:9 | stringstream.cpp:33:23:33:28 | AST only | +| stringstream.cpp:40:7:40:9 | stringstream.cpp:34:14:34:19 | AST only | +| stringstream.cpp:41:7:41:9 | stringstream.cpp:29:16:29:21 | AST only | +| stringstream.cpp:76:11:76:11 | stringstream.cpp:70:32:70:37 | AST only | +| stringstream.cpp:81:7:81:9 | stringstream.cpp:70:32:70:37 | AST only | +| stringstream.cpp:143:11:143:11 | stringstream.cpp:143:14:143:21 | IR only | +| stringstream.cpp:143:11:143:22 | stringstream.cpp:143:14:143:19 | IR only | +| stringstream.cpp:143:11:143:22 | stringstream.cpp:143:14:143:21 | IR only | | structlikeclass.cpp:35:8:35:9 | structlikeclass.cpp:29:22:29:27 | AST only | | structlikeclass.cpp:36:8:36:9 | structlikeclass.cpp:30:24:30:29 | AST only | | structlikeclass.cpp:37:8:37:9 | structlikeclass.cpp:29:22:29:27 | AST only | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_ir.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_ir.expected index ca494a4c2fb..d1457e0cc20 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_ir.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_ir.expected @@ -24,6 +24,38 @@ | string.cpp:28:7:28:7 | a | string.cpp:24:12:24:17 | call to source | | string.cpp:55:7:55:8 | cs | string.cpp:50:19:50:24 | call to source | | string.cpp:55:7:55:8 | cs | string.cpp:50:19:50:26 | (const char *)... | +| stringstream.cpp:32:11:32:11 | call to operator<< | stringstream.cpp:32:14:32:19 | call to source | +| stringstream.cpp:32:11:32:11 | call to operator<< | stringstream.cpp:32:14:32:21 | (const char *)... | +| stringstream.cpp:32:11:32:22 | (const basic_ostream>)... | stringstream.cpp:32:14:32:19 | call to source | +| stringstream.cpp:32:11:32:22 | (const basic_ostream>)... | stringstream.cpp:32:14:32:21 | (const char *)... | +| stringstream.cpp:32:11:32:22 | (reference dereference) | stringstream.cpp:32:14:32:19 | call to source | +| stringstream.cpp:32:11:32:22 | (reference dereference) | stringstream.cpp:32:14:32:21 | (const char *)... | +| stringstream.cpp:32:11:32:22 | (reference to) | stringstream.cpp:32:14:32:19 | call to source | +| stringstream.cpp:32:11:32:22 | (reference to) | stringstream.cpp:32:14:32:21 | (const char *)... | +| stringstream.cpp:33:20:33:20 | call to operator<< | stringstream.cpp:33:23:33:28 | call to source | +| stringstream.cpp:33:20:33:20 | call to operator<< | stringstream.cpp:33:23:33:30 | (const char *)... | +| stringstream.cpp:33:20:33:31 | (const basic_ostream>)... | stringstream.cpp:33:23:33:28 | call to source | +| stringstream.cpp:33:20:33:31 | (const basic_ostream>)... | stringstream.cpp:33:23:33:30 | (const char *)... | +| stringstream.cpp:33:20:33:31 | (reference dereference) | stringstream.cpp:33:23:33:28 | call to source | +| stringstream.cpp:33:20:33:31 | (reference dereference) | stringstream.cpp:33:23:33:30 | (const char *)... | +| stringstream.cpp:33:20:33:31 | (reference to) | stringstream.cpp:33:23:33:28 | call to source | +| stringstream.cpp:33:20:33:31 | (reference to) | stringstream.cpp:33:23:33:30 | (const char *)... | +| stringstream.cpp:34:23:34:23 | call to operator<< | stringstream.cpp:34:14:34:19 | call to source | +| stringstream.cpp:34:23:34:23 | call to operator<< | stringstream.cpp:34:14:34:21 | (const char *)... | +| stringstream.cpp:34:23:34:31 | (const basic_ostream>)... | stringstream.cpp:34:14:34:19 | call to source | +| stringstream.cpp:34:23:34:31 | (const basic_ostream>)... | stringstream.cpp:34:14:34:21 | (const char *)... | +| stringstream.cpp:34:23:34:31 | (reference dereference) | stringstream.cpp:34:14:34:19 | call to source | +| stringstream.cpp:34:23:34:31 | (reference dereference) | stringstream.cpp:34:14:34:21 | (const char *)... | +| stringstream.cpp:34:23:34:31 | (reference to) | stringstream.cpp:34:14:34:19 | call to source | +| stringstream.cpp:34:23:34:31 | (reference to) | stringstream.cpp:34:14:34:21 | (const char *)... | +| stringstream.cpp:143:11:143:11 | call to operator<< | stringstream.cpp:143:14:143:19 | call to source | +| stringstream.cpp:143:11:143:11 | call to operator<< | stringstream.cpp:143:14:143:21 | (const char *)... | +| stringstream.cpp:143:11:143:22 | (const basic_ostream>)... | stringstream.cpp:143:14:143:19 | call to source | +| stringstream.cpp:143:11:143:22 | (const basic_ostream>)... | stringstream.cpp:143:14:143:21 | (const char *)... | +| stringstream.cpp:143:11:143:22 | (reference dereference) | stringstream.cpp:143:14:143:19 | call to source | +| stringstream.cpp:143:11:143:22 | (reference dereference) | stringstream.cpp:143:14:143:21 | (const char *)... | +| stringstream.cpp:143:11:143:22 | (reference to) | stringstream.cpp:143:14:143:19 | call to source | +| stringstream.cpp:143:11:143:22 | (reference to) | stringstream.cpp:143:14:143:21 | (const char *)... | | structlikeclass.cpp:38:8:38:9 | s4 | structlikeclass.cpp:33:8:33:13 | call to source | | structlikeclass.cpp:61:8:61:9 | s2 | structlikeclass.cpp:58:24:58:29 | call to source | | structlikeclass.cpp:62:8:62:20 | ... = ... | structlikeclass.cpp:62:13:62:18 | call to source | diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 2e204cde856..e58a36e747d 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -71,7 +71,7 @@ bad_asts.cpp: # 9| params: # 9| 0: [Parameter] y # 9| Type = [IntType] int -# 9| body: [Block] { ... } +# 9| body: [BlockStmt] { ... } # 10| 0: [ReturnStmt] return ... # 10| 0: [AddExpr] ... + ... # 10| Type = [IntType] int @@ -96,7 +96,7 @@ bad_asts.cpp: # 9| params: # 9| 0: [Parameter] y # 9| Type = [IntType] int -# 9| body: [Block] { ... } +# 9| body: [BlockStmt] { ... } # 10| 0: [ReturnStmt] return ... # 10| 0: [AddExpr] ... + ... # 10| Type = [IntType] int @@ -119,7 +119,7 @@ bad_asts.cpp: # 10| ValueCategory = prvalue(load) # 14| [TopLevelFunction] void Bad::CallBadMemberFunction() # 14| params: -# 14| body: [Block] { ... } +# 14| body: [BlockStmt] { ... } # 15| 0: [DeclStmt] declaration # 15| 0: [VariableDeclarationEntry] definition of s # 15| Type = [Struct] S @@ -164,7 +164,7 @@ bad_asts.cpp: # 19| 0: [Literal] Unknown literal # 19| Type = [IntType] int # 19| ValueCategory = prvalue -# 19| body: [Block] { ... } +# 19| body: [BlockStmt] { ... } # 19| 0: [ReturnStmt] return ... # 19| [MoveConstructor] void Bad::Point::Point(Bad::Point&&) # 19| params: @@ -173,13 +173,13 @@ bad_asts.cpp: # 22| [Constructor] void Bad::Point::Point() # 22| params: # 22| initializations: -# 22| body: [Block] { ... } +# 22| body: [BlockStmt] { ... } # 23| 0: [ReturnStmt] return ... # 26| [TopLevelFunction] void Bad::CallCopyConstructor(Bad::Point const&) # 26| params: # 26| 0: [Parameter] a # 26| Type = [LValueReferenceType] const Point & -# 26| body: [Block] { ... } +# 26| body: [BlockStmt] { ... } # 27| 0: [DeclStmt] declaration # 27| 0: [VariableDeclarationEntry] definition of b # 27| Type = [Struct] Point @@ -197,7 +197,7 @@ bad_asts.cpp: # 28| 1: [ReturnStmt] return ... # 30| [TopLevelFunction] void Bad::errorExpr() # 30| params: -# 30| body: [Block] { ... } +# 30| body: [BlockStmt] { ... } # 31| 0: [DeclStmt] declaration # 31| 0: [VariableDeclarationEntry] definition of intref # 31| Type = [LValueReferenceType] int & @@ -226,7 +226,7 @@ bad_asts.cpp: clang.cpp: # 5| [TopLevelFunction] int* globalIntAddress() # 5| params: -# 5| body: [Block] { ... } +# 5| body: [BlockStmt] { ... } # 6| 0: [ReturnStmt] return ... # 6| 0: [BuiltInOperationBuiltInAddressOf] __builtin_addressof ... # 6| Type = [IntPointerType] int * @@ -237,7 +237,7 @@ clang.cpp: complex.c: # 1| [TopLevelFunction] void complex_literals() # 1| params: -# 1| body: [Block] { ... } +# 1| body: [BlockStmt] { ... } # 2| 0: [DeclStmt] declaration # 2| 0: [VariableDeclarationEntry] definition of cf # 2| Type = [ArithmeticType] _Complex float @@ -354,7 +354,7 @@ complex.c: # 12| 9: [ReturnStmt] return ... # 14| [TopLevelFunction] void complex_arithmetic() # 14| params: -# 14| body: [Block] { ... } +# 14| body: [BlockStmt] { ... } # 15| 0: [DeclStmt] declaration # 15| 0: [VariableDeclarationEntry] definition of f1 # 15| Type = [FloatType] float @@ -741,7 +741,7 @@ complex.c: # 56| 29: [ReturnStmt] return ... # 58| [TopLevelFunction] void complex_conversions() # 58| params: -# 58| body: [Block] { ... } +# 58| body: [BlockStmt] { ... } # 59| 0: [DeclStmt] declaration # 59| 0: [VariableDeclarationEntry] definition of f # 59| Type = [FloatType] float @@ -1718,7 +1718,7 @@ complex.c: ir.cpp: # 1| [TopLevelFunction] void Constants() # 1| params: -# 1| body: [Block] { ... } +# 1| body: [BlockStmt] { ... } # 2| 0: [DeclStmt] declaration # 2| 0: [VariableDeclarationEntry] definition of c_i # 2| Type = [PlainCharType] char @@ -2035,7 +2035,7 @@ ir.cpp: # 41| 28: [ReturnStmt] return ... # 43| [TopLevelFunction] void Foo() # 43| params: -# 43| body: [Block] { ... } +# 43| body: [BlockStmt] { ... } # 44| 0: [DeclStmt] declaration # 44| 0: [VariableDeclarationEntry] definition of x # 44| Type = [IntType] int @@ -2116,7 +2116,7 @@ ir.cpp: # 50| Type = [IntType] int # 50| 1: [Parameter] y # 50| Type = [IntType] int -# 50| body: [Block] { ... } +# 50| body: [BlockStmt] { ... } # 51| 0: [DeclStmt] declaration # 51| 0: [VariableDeclarationEntry] definition of z # 51| Type = [IntType] int @@ -2457,7 +2457,7 @@ ir.cpp: # 87| Type = [IntType] int # 87| 1: [Parameter] y # 87| Type = [IntType] int -# 87| body: [Block] { ... } +# 87| body: [BlockStmt] { ... } # 88| 0: [DeclStmt] declaration # 88| 0: [VariableDeclarationEntry] definition of b # 88| Type = [BoolType] bool @@ -2562,7 +2562,7 @@ ir.cpp: # 98| params: # 98| 0: [Parameter] x # 98| Type = [IntType] int -# 98| body: [Block] { ... } +# 98| body: [BlockStmt] { ... } # 99| 0: [DeclStmt] declaration # 99| 0: [VariableDeclarationEntry] definition of y # 99| Type = [IntType] int @@ -2623,7 +2623,7 @@ ir.cpp: # 107| params: # 107| 0: [Parameter] x # 107| Type = [IntType] int -# 107| body: [Block] { ... } +# 107| body: [BlockStmt] { ... } # 108| 0: [DeclStmt] declaration # 108| 0: [VariableDeclarationEntry] definition of p # 108| Type = [IntPointerType] int * @@ -2672,7 +2672,7 @@ ir.cpp: # 114| Type = [DoubleType] double # 114| 1: [Parameter] y # 114| Type = [DoubleType] double -# 114| body: [Block] { ... } +# 114| body: [BlockStmt] { ... } # 115| 0: [DeclStmt] declaration # 115| 0: [VariableDeclarationEntry] definition of z # 115| Type = [DoubleType] double @@ -2823,7 +2823,7 @@ ir.cpp: # 133| Type = [DoubleType] double # 133| 1: [Parameter] y # 133| Type = [DoubleType] double -# 133| body: [Block] { ... } +# 133| body: [BlockStmt] { ... } # 134| 0: [DeclStmt] declaration # 134| 0: [VariableDeclarationEntry] definition of b # 134| Type = [BoolType] bool @@ -2928,7 +2928,7 @@ ir.cpp: # 144| params: # 144| 0: [Parameter] x # 144| Type = [FloatType] float -# 144| body: [Block] { ... } +# 144| body: [BlockStmt] { ... } # 145| 0: [DeclStmt] declaration # 145| 0: [VariableDeclarationEntry] definition of y # 145| Type = [FloatType] float @@ -2991,7 +2991,7 @@ ir.cpp: # 153| Type = [IntPointerType] int * # 153| 1: [Parameter] i # 153| Type = [IntType] int -# 153| body: [Block] { ... } +# 153| body: [BlockStmt] { ... } # 154| 0: [DeclStmt] declaration # 154| 0: [VariableDeclarationEntry] definition of q # 154| Type = [IntPointerType] int * @@ -3134,7 +3134,7 @@ ir.cpp: # 171| Type = [IntPointerType] int * # 171| 1: [Parameter] i # 171| Type = [IntType] int -# 171| body: [Block] { ... } +# 171| body: [BlockStmt] { ... } # 172| 0: [DeclStmt] declaration # 172| 0: [VariableDeclarationEntry] definition of x # 172| Type = [IntType] int @@ -3286,7 +3286,7 @@ ir.cpp: # 187| params: # 187| 0: [Parameter] i # 187| Type = [IntType] int -# 187| body: [Block] { ... } +# 187| body: [BlockStmt] { ... } # 188| 0: [DeclStmt] declaration # 188| 0: [VariableDeclarationEntry] definition of c # 188| Type = [PlainCharType] char @@ -3339,7 +3339,7 @@ ir.cpp: # 193| Type = [IntPointerType] int * # 193| 1: [Parameter] q # 193| Type = [IntPointerType] int * -# 193| body: [Block] { ... } +# 193| body: [BlockStmt] { ... } # 194| 0: [DeclStmt] declaration # 194| 0: [VariableDeclarationEntry] definition of b # 194| Type = [BoolType] bool @@ -3444,7 +3444,7 @@ ir.cpp: # 204| params: # 204| 0: [Parameter] p # 204| Type = [IntPointerType] int * -# 204| body: [Block] { ... } +# 204| body: [BlockStmt] { ... } # 205| 0: [DeclStmt] declaration # 205| 0: [VariableDeclarationEntry] definition of q # 205| Type = [IntPointerType] int * @@ -3503,7 +3503,7 @@ ir.cpp: # 211| 5: [ReturnStmt] return ... # 213| [TopLevelFunction] void CompoundAssignment() # 213| params: -# 213| body: [Block] { ... } +# 213| body: [BlockStmt] { ... } # 215| 0: [DeclStmt] declaration # 215| 0: [VariableDeclarationEntry] definition of x # 215| Type = [IntType] int @@ -3584,7 +3584,7 @@ ir.cpp: # 228| 7: [ReturnStmt] return ... # 230| [TopLevelFunction] void UninitializedVariables() # 230| params: -# 230| body: [Block] { ... } +# 230| body: [BlockStmt] { ... } # 231| 0: [DeclStmt] declaration # 231| 0: [VariableDeclarationEntry] definition of x # 231| Type = [IntType] int @@ -3602,7 +3602,7 @@ ir.cpp: # 235| Type = [IntType] int # 235| 1: [Parameter] y # 235| Type = [IntType] int -# 235| body: [Block] { ... } +# 235| body: [BlockStmt] { ... } # 236| 0: [ReturnStmt] return ... # 236| 0: [RemExpr] ... % ... # 236| Type = [IntType] int @@ -3621,17 +3621,17 @@ ir.cpp: # 239| Type = [IntType] int # 239| 2: [Parameter] y # 239| Type = [IntType] int -# 239| body: [Block] { ... } +# 239| body: [BlockStmt] { ... } # 240| 0: [IfStmt] if (...) ... # 240| 0: [VariableAccess] b # 240| Type = [BoolType] bool # 240| ValueCategory = prvalue(load) -# 240| 1: [Block] { ... } +# 240| 1: [BlockStmt] { ... } # 243| 1: [IfStmt] if (...) ... # 243| 0: [VariableAccess] b # 243| Type = [BoolType] bool # 243| ValueCategory = prvalue(load) -# 243| 1: [Block] { ... } +# 243| 1: [BlockStmt] { ... } # 244| 0: [ExprStmt] ExprStmt # 244| 0: [AssignExpr] ... = ... # 244| Type = [IntType] int @@ -3680,7 +3680,7 @@ ir.cpp: # 253| params: # 253| 0: [Parameter] n # 253| Type = [IntType] int -# 253| body: [Block] { ... } +# 253| body: [BlockStmt] { ... } # 254| 0: [WhileStmt] while (...) ... # 254| 0: [GTExpr] ... > ... # 254| Type = [BoolType] bool @@ -3692,7 +3692,7 @@ ir.cpp: # 254| Type = [IntType] int # 254| Value = [Literal] 0 # 254| ValueCategory = prvalue -# 254| 1: [Block] { ... } +# 254| 1: [BlockStmt] { ... } # 255| 0: [ExprStmt] ExprStmt # 255| 0: [AssignSubExpr] ... -= ... # 255| Type = [IntType] int @@ -3709,7 +3709,7 @@ ir.cpp: # 259| params: # 259| 0: [Parameter] n # 259| Type = [IntType] int -# 259| body: [Block] { ... } +# 259| body: [BlockStmt] { ... } # 260| 0: [DoStmt] do (...) ... # 262| 0: [GTExpr] ... > ... # 262| Type = [BoolType] bool @@ -3721,7 +3721,7 @@ ir.cpp: # 262| Type = [IntType] int # 262| Value = [Literal] 0 # 262| ValueCategory = prvalue -# 260| 1: [Block] { ... } +# 260| 1: [BlockStmt] { ... } # 261| 0: [ExprStmt] ExprStmt # 261| 0: [AssignSubExpr] ... -= ... # 261| Type = [IntType] int @@ -3736,16 +3736,16 @@ ir.cpp: # 263| 1: [ReturnStmt] return ... # 265| [TopLevelFunction] void For_Empty() # 265| params: -# 265| body: [Block] { ... } +# 265| body: [BlockStmt] { ... } # 266| 0: [DeclStmt] declaration # 266| 0: [VariableDeclarationEntry] definition of j # 266| Type = [IntType] int # 267| 1: [ForStmt] for(...;...;...) ... -# 267| 3: [Block] { ... } +# 267| 3: [BlockStmt] { ... } # 268| 0: [EmptyStmt] ; # 272| [TopLevelFunction] void For_Init() # 272| params: -# 272| body: [Block] { ... } +# 272| body: [BlockStmt] { ... } # 273| 0: [ForStmt] for(...;...;...) ... # 273| 0: [DeclStmt] declaration # 273| 0: [VariableDeclarationEntry] definition of i @@ -3755,11 +3755,11 @@ ir.cpp: # 273| Type = [IntType] int # 273| Value = [Literal] 0 # 273| ValueCategory = prvalue -# 273| 3: [Block] { ... } +# 273| 3: [BlockStmt] { ... } # 274| 0: [EmptyStmt] ; # 278| [TopLevelFunction] void For_Condition() # 278| params: -# 278| body: [Block] { ... } +# 278| body: [BlockStmt] { ... } # 279| 0: [DeclStmt] declaration # 279| 0: [VariableDeclarationEntry] definition of i # 279| Type = [IntType] int @@ -3779,12 +3779,12 @@ ir.cpp: # 280| Type = [IntType] int # 280| Value = [Literal] 10 # 280| ValueCategory = prvalue -# 280| 3: [Block] { ... } +# 280| 3: [BlockStmt] { ... } # 281| 0: [EmptyStmt] ; # 283| 2: [ReturnStmt] return ... # 285| [TopLevelFunction] void For_Update() # 285| params: -# 285| body: [Block] { ... } +# 285| body: [BlockStmt] { ... } # 286| 0: [DeclStmt] declaration # 286| 0: [VariableDeclarationEntry] definition of i # 286| Type = [IntType] int @@ -3804,11 +3804,11 @@ ir.cpp: # 287| Type = [IntType] int # 287| Value = [Literal] 1 # 287| ValueCategory = prvalue -# 287| 3: [Block] { ... } +# 287| 3: [BlockStmt] { ... } # 288| 0: [EmptyStmt] ; # 292| [TopLevelFunction] void For_InitCondition() # 292| params: -# 292| body: [Block] { ... } +# 292| body: [BlockStmt] { ... } # 293| 0: [ForStmt] for(...;...;...) ... # 293| 0: [DeclStmt] declaration # 293| 0: [VariableDeclarationEntry] definition of i @@ -3828,12 +3828,12 @@ ir.cpp: # 293| Type = [IntType] int # 293| Value = [Literal] 10 # 293| ValueCategory = prvalue -# 293| 3: [Block] { ... } +# 293| 3: [BlockStmt] { ... } # 294| 0: [EmptyStmt] ; # 296| 1: [ReturnStmt] return ... # 298| [TopLevelFunction] void For_InitUpdate() # 298| params: -# 298| body: [Block] { ... } +# 298| body: [BlockStmt] { ... } # 299| 0: [ForStmt] for(...;...;...) ... # 299| 0: [DeclStmt] declaration # 299| 0: [VariableDeclarationEntry] definition of i @@ -3853,11 +3853,11 @@ ir.cpp: # 299| Type = [IntType] int # 299| Value = [Literal] 1 # 299| ValueCategory = prvalue -# 299| 3: [Block] { ... } +# 299| 3: [BlockStmt] { ... } # 300| 0: [EmptyStmt] ; # 304| [TopLevelFunction] void For_ConditionUpdate() # 304| params: -# 304| body: [Block] { ... } +# 304| body: [BlockStmt] { ... } # 305| 0: [DeclStmt] declaration # 305| 0: [VariableDeclarationEntry] definition of i # 305| Type = [IntType] int @@ -3887,12 +3887,12 @@ ir.cpp: # 306| Type = [IntType] int # 306| Value = [Literal] 1 # 306| ValueCategory = prvalue -# 306| 3: [Block] { ... } +# 306| 3: [BlockStmt] { ... } # 307| 0: [EmptyStmt] ; # 309| 2: [ReturnStmt] return ... # 311| [TopLevelFunction] void For_InitConditionUpdate() # 311| params: -# 311| body: [Block] { ... } +# 311| body: [BlockStmt] { ... } # 312| 0: [ForStmt] for(...;...;...) ... # 312| 0: [DeclStmt] declaration # 312| 0: [VariableDeclarationEntry] definition of i @@ -3922,12 +3922,12 @@ ir.cpp: # 312| Type = [IntType] int # 312| Value = [Literal] 1 # 312| ValueCategory = prvalue -# 312| 3: [Block] { ... } +# 312| 3: [BlockStmt] { ... } # 313| 0: [EmptyStmt] ; # 315| 1: [ReturnStmt] return ... # 317| [TopLevelFunction] void For_Break() # 317| params: -# 317| body: [Block] { ... } +# 317| body: [BlockStmt] { ... } # 318| 0: [ForStmt] for(...;...;...) ... # 318| 0: [DeclStmt] declaration # 318| 0: [VariableDeclarationEntry] definition of i @@ -3957,7 +3957,7 @@ ir.cpp: # 318| Type = [IntType] int # 318| Value = [Literal] 1 # 318| ValueCategory = prvalue -# 318| 3: [Block] { ... } +# 318| 3: [BlockStmt] { ... } # 319| 0: [IfStmt] if (...) ... # 319| 0: [EQExpr] ... == ... # 319| Type = [BoolType] bool @@ -3969,13 +3969,13 @@ ir.cpp: # 319| Type = [IntType] int # 319| Value = [Literal] 5 # 319| ValueCategory = prvalue -# 319| 1: [Block] { ... } +# 319| 1: [BlockStmt] { ... } # 320| 0: [BreakStmt] break; # 322| 1: [LabelStmt] label ...: # 323| 2: [ReturnStmt] return ... # 325| [TopLevelFunction] void For_Continue_Update() # 325| params: -# 325| body: [Block] { ... } +# 325| body: [BlockStmt] { ... } # 326| 0: [ForStmt] for(...;...;...) ... # 326| 0: [DeclStmt] declaration # 326| 0: [VariableDeclarationEntry] definition of i @@ -4005,7 +4005,7 @@ ir.cpp: # 326| Type = [IntType] int # 326| Value = [Literal] 1 # 326| ValueCategory = prvalue -# 326| 3: [Block] { ... } +# 326| 3: [BlockStmt] { ... } # 327| 0: [IfStmt] if (...) ... # 327| 0: [EQExpr] ... == ... # 327| Type = [BoolType] bool @@ -4017,13 +4017,13 @@ ir.cpp: # 327| Type = [IntType] int # 327| Value = [Literal] 5 # 327| ValueCategory = prvalue -# 327| 1: [Block] { ... } +# 327| 1: [BlockStmt] { ... } # 328| 0: [ContinueStmt] continue; # 326| 1: [LabelStmt] label ...: # 331| 1: [ReturnStmt] return ... # 333| [TopLevelFunction] void For_Continue_NoUpdate() # 333| params: -# 333| body: [Block] { ... } +# 333| body: [BlockStmt] { ... } # 334| 0: [ForStmt] for(...;...;...) ... # 334| 0: [DeclStmt] declaration # 334| 0: [VariableDeclarationEntry] definition of i @@ -4043,7 +4043,7 @@ ir.cpp: # 334| Type = [IntType] int # 334| Value = [Literal] 10 # 334| ValueCategory = prvalue -# 334| 3: [Block] { ... } +# 334| 3: [BlockStmt] { ... } # 335| 0: [IfStmt] if (...) ... # 335| 0: [EQExpr] ... == ... # 335| Type = [BoolType] bool @@ -4055,7 +4055,7 @@ ir.cpp: # 335| Type = [IntType] int # 335| Value = [Literal] 5 # 335| ValueCategory = prvalue -# 335| 1: [Block] { ... } +# 335| 1: [BlockStmt] { ... } # 336| 0: [ContinueStmt] continue; # 334| 1: [LabelStmt] label ...: # 339| 1: [ReturnStmt] return ... @@ -4063,7 +4063,7 @@ ir.cpp: # 341| params: # 341| 0: [Parameter] p # 341| Type = [IntPointerType] int * -# 341| body: [Block] { ... } +# 341| body: [BlockStmt] { ... } # 342| 0: [ExprStmt] ExprStmt # 342| 0: [AssignExpr] ... = ... # 342| Type = [IntType] int @@ -4087,7 +4087,7 @@ ir.cpp: # 343| ValueCategory = prvalue(load) # 348| [TopLevelFunction] int* AddressOf() # 348| params: -# 348| body: [Block] { ... } +# 348| body: [BlockStmt] { ... } # 349| 0: [ReturnStmt] return ... # 349| 0: [AddressOfExpr] & ... # 349| Type = [IntPointerType] int * @@ -4099,7 +4099,7 @@ ir.cpp: # 352| params: # 352| 0: [Parameter] n # 352| Type = [IntType] int -# 352| body: [Block] { ... } +# 352| body: [BlockStmt] { ... } # 353| 0: [WhileStmt] while (...) ... # 353| 0: [GTExpr] ... > ... # 353| Type = [BoolType] bool @@ -4111,7 +4111,7 @@ ir.cpp: # 353| Type = [IntType] int # 353| Value = [Literal] 0 # 353| ValueCategory = prvalue -# 353| 1: [Block] { ... } +# 353| 1: [BlockStmt] { ... } # 354| 0: [IfStmt] if (...) ... # 354| 0: [EQExpr] ... == ... # 354| Type = [BoolType] bool @@ -4141,7 +4141,7 @@ ir.cpp: # 360| params: # 360| 0: [Parameter] n # 360| Type = [IntType] int -# 360| body: [Block] { ... } +# 360| body: [BlockStmt] { ... } # 361| 0: [DoStmt] do (...) ... # 366| 0: [GTExpr] ... > ... # 366| Type = [BoolType] bool @@ -4153,7 +4153,7 @@ ir.cpp: # 366| Type = [IntType] int # 366| Value = [Literal] 0 # 366| ValueCategory = prvalue -# 361| 1: [Block] { ... } +# 361| 1: [BlockStmt] { ... } # 362| 0: [IfStmt] if (...) ... # 362| 0: [EQExpr] ... == ... # 362| Type = [BoolType] bool @@ -4165,7 +4165,7 @@ ir.cpp: # 362| Type = [IntType] int # 362| Value = [Literal] 1 # 362| ValueCategory = prvalue -# 362| 1: [Block] { ... } +# 362| 1: [BlockStmt] { ... } # 363| 0: [ContinueStmt] continue; # 365| 1: [ExprStmt] ExprStmt # 365| 0: [AssignSubExpr] ... -= ... @@ -4190,7 +4190,7 @@ ir.cpp: # 370| Type = [IntType] int # 372| [TopLevelFunction] void Call() # 372| params: -# 372| body: [Block] { ... } +# 372| body: [BlockStmt] { ... } # 373| 0: [ExprStmt] ExprStmt # 373| 0: [FunctionCall] call to VoidFunc # 373| Type = [VoidType] void @@ -4202,7 +4202,7 @@ ir.cpp: # 376| Type = [IntType] int # 376| 1: [Parameter] y # 376| Type = [IntType] int -# 376| body: [Block] { ... } +# 376| body: [BlockStmt] { ... } # 377| 0: [ReturnStmt] return ... # 377| 0: [FunctionCall] call to Add # 377| Type = [IntType] int @@ -4219,7 +4219,7 @@ ir.cpp: # 380| Type = [IntType] int # 380| 1: [Parameter] y # 380| Type = [IntType] int -# 380| body: [Block] { ... } +# 380| body: [BlockStmt] { ... } # 381| 0: [ReturnStmt] return ... # 381| 0: [CommaExpr] ... , ... # 381| Type = [IntType] int @@ -4240,7 +4240,7 @@ ir.cpp: # 384| params: # 384| 0: [Parameter] x # 384| Type = [IntType] int -# 384| body: [Block] { ... } +# 384| body: [BlockStmt] { ... } # 385| 0: [DeclStmt] declaration # 385| 0: [VariableDeclarationEntry] definition of y # 385| Type = [IntType] int @@ -4248,7 +4248,7 @@ ir.cpp: # 386| 0: [VariableAccess] x # 386| Type = [IntType] int # 386| ValueCategory = prvalue(load) -# 386| 1: [Block] { ... } +# 386| 1: [BlockStmt] { ... } # 387| 0: [ExprStmt] ExprStmt # 387| 0: [AssignExpr] ... = ... # 387| Type = [IntType] int @@ -4386,14 +4386,14 @@ ir.cpp: # 422| params: # 422| 0: [Parameter] pt # 422| Type = [Struct] Point -# 422| body: [Block] { ... } +# 422| body: [BlockStmt] { ... } # 423| 0: [ReturnStmt] return ... # 423| 0: [VariableAccess] pt # 423| Type = [Struct] Point # 423| ValueCategory = prvalue(load) # 426| [TopLevelFunction] void FieldAccess() # 426| params: -# 426| body: [Block] { ... } +# 426| body: [BlockStmt] { ... } # 427| 0: [DeclStmt] declaration # 427| 0: [VariableDeclarationEntry] definition of pt # 427| Type = [Struct] Point @@ -4447,7 +4447,7 @@ ir.cpp: # 433| Type = [BoolType] bool # 433| 1: [Parameter] b # 433| Type = [BoolType] bool -# 433| body: [Block] { ... } +# 433| body: [BlockStmt] { ... } # 434| 0: [DeclStmt] declaration # 434| 0: [VariableDeclarationEntry] definition of x # 434| Type = [IntType] int @@ -4461,7 +4461,7 @@ ir.cpp: # 435| 1: [VariableAccess] b # 435| Type = [BoolType] bool # 435| ValueCategory = prvalue(load) -# 435| 1: [Block] { ... } +# 435| 1: [BlockStmt] { ... } # 436| 0: [ExprStmt] ExprStmt # 436| 0: [AssignExpr] ... = ... # 436| Type = [IntType] int @@ -4483,7 +4483,7 @@ ir.cpp: # 439| 1: [VariableAccess] b # 439| Type = [BoolType] bool # 439| ValueCategory = prvalue(load) -# 439| 1: [Block] { ... } +# 439| 1: [BlockStmt] { ... } # 440| 0: [ExprStmt] ExprStmt # 440| 0: [AssignExpr] ... = ... # 440| Type = [IntType] int @@ -4495,7 +4495,7 @@ ir.cpp: # 440| Type = [IntType] int # 440| Value = [Literal] 1 # 440| ValueCategory = prvalue -# 442| 2: [Block] { ... } +# 442| 2: [BlockStmt] { ... } # 443| 0: [ExprStmt] ExprStmt # 443| 0: [AssignExpr] ... = ... # 443| Type = [IntType] int @@ -4514,7 +4514,7 @@ ir.cpp: # 447| Type = [BoolType] bool # 447| 1: [Parameter] b # 447| Type = [BoolType] bool -# 447| body: [Block] { ... } +# 447| body: [BlockStmt] { ... } # 448| 0: [DeclStmt] declaration # 448| 0: [VariableDeclarationEntry] definition of x # 448| Type = [IntType] int @@ -4528,7 +4528,7 @@ ir.cpp: # 449| 1: [VariableAccess] b # 449| Type = [BoolType] bool # 449| ValueCategory = prvalue(load) -# 449| 1: [Block] { ... } +# 449| 1: [BlockStmt] { ... } # 450| 0: [ExprStmt] ExprStmt # 450| 0: [AssignExpr] ... = ... # 450| Type = [IntType] int @@ -4550,7 +4550,7 @@ ir.cpp: # 453| 1: [VariableAccess] b # 453| Type = [BoolType] bool # 453| ValueCategory = prvalue(load) -# 453| 1: [Block] { ... } +# 453| 1: [BlockStmt] { ... } # 454| 0: [ExprStmt] ExprStmt # 454| 0: [AssignExpr] ... = ... # 454| Type = [IntType] int @@ -4562,7 +4562,7 @@ ir.cpp: # 454| Type = [IntType] int # 454| Value = [Literal] 1 # 454| ValueCategory = prvalue -# 456| 2: [Block] { ... } +# 456| 2: [BlockStmt] { ... } # 457| 0: [ExprStmt] ExprStmt # 457| 0: [AssignExpr] ... = ... # 457| Type = [IntType] int @@ -4581,7 +4581,7 @@ ir.cpp: # 461| Type = [BoolType] bool # 461| 1: [Parameter] b # 461| Type = [BoolType] bool -# 461| body: [Block] { ... } +# 461| body: [BlockStmt] { ... } # 462| 0: [DeclStmt] declaration # 462| 0: [VariableDeclarationEntry] definition of x # 462| Type = [IntType] int @@ -4592,7 +4592,7 @@ ir.cpp: # 463| 0: [VariableAccess] a # 463| Type = [BoolType] bool # 463| ValueCategory = prvalue(load) -# 463| 1: [Block] { ... } +# 463| 1: [BlockStmt] { ... } # 464| 0: [ExprStmt] ExprStmt # 464| 0: [AssignExpr] ... = ... # 464| Type = [IntType] int @@ -4620,7 +4620,7 @@ ir.cpp: # 467| 1: [VariableAccess] b # 467| Type = [BoolType] bool # 467| ValueCategory = prvalue(load) -# 467| 1: [Block] { ... } +# 467| 1: [BlockStmt] { ... } # 468| 0: [ExprStmt] ExprStmt # 468| 0: [AssignExpr] ... = ... # 468| Type = [IntType] int @@ -4632,7 +4632,7 @@ ir.cpp: # 468| Type = [IntType] int # 468| Value = [Literal] 2 # 468| ValueCategory = prvalue -# 470| 2: [Block] { ... } +# 470| 2: [BlockStmt] { ... } # 471| 0: [ExprStmt] ExprStmt # 471| 0: [AssignExpr] ... = ... # 471| Type = [IntType] int @@ -4651,7 +4651,7 @@ ir.cpp: # 475| Type = [BoolType] bool # 475| 1: [Parameter] b # 475| Type = [BoolType] bool -# 475| body: [Block] { ... } +# 475| body: [BlockStmt] { ... } # 476| 0: [DeclStmt] declaration # 476| 0: [VariableDeclarationEntry] definition of x # 476| Type = [BoolType] bool @@ -4718,7 +4718,7 @@ ir.cpp: # 482| Type = [IntType] int # 482| 2: [Parameter] y # 482| Type = [IntType] int -# 482| body: [Block] { ... } +# 482| body: [BlockStmt] { ... } # 483| 0: [DeclStmt] declaration # 483| 0: [VariableDeclarationEntry] definition of z # 483| Type = [IntType] int @@ -4740,7 +4740,7 @@ ir.cpp: # 486| params: # 486| 0: [Parameter] a # 486| Type = [BoolType] bool -# 486| body: [Block] { ... } +# 486| body: [BlockStmt] { ... } # 487| 0: [DeclStmt] declaration # 487| 0: [VariableDeclarationEntry] definition of x # 487| Type = [IntType] int @@ -4775,7 +4775,7 @@ ir.cpp: # 492| params: # 492| 0: [Parameter] a # 492| Type = [BoolType] bool -# 492| body: [Block] { ... } +# 492| body: [BlockStmt] { ... } # 493| 0: [ExprStmt] ExprStmt # 493| 0: [ConditionalExpr] ... ? ... : ... # 493| Type = [VoidType] void @@ -4792,7 +4792,7 @@ ir.cpp: # 494| 1: [ReturnStmt] return ... # 496| [TopLevelFunction] void Nullptr() # 496| params: -# 496| body: [Block] { ... } +# 496| body: [BlockStmt] { ... } # 497| 0: [DeclStmt] declaration # 497| 0: [VariableDeclarationEntry] definition of p # 497| Type = [IntPointerType] int * @@ -4858,7 +4858,7 @@ ir.cpp: # 503| Type = [IntType] int # 503| 1: [Parameter] f # 503| Type = [FloatType] float -# 503| body: [Block] { ... } +# 503| body: [BlockStmt] { ... } # 504| 0: [DeclStmt] declaration # 504| 0: [VariableDeclarationEntry] definition of pt1 # 504| Type = [Struct] Point @@ -4916,7 +4916,7 @@ ir.cpp: # 512| Type = [IntType] int # 512| 1: [Parameter] f # 512| Type = [FloatType] float -# 512| body: [Block] { ... } +# 512| body: [BlockStmt] { ... } # 513| 0: [DeclStmt] declaration # 513| 0: [VariableDeclarationEntry] definition of r1 # 513| Type = [Struct] Rect @@ -5003,7 +5003,7 @@ ir.cpp: # 519| Type = [IntType] int # 519| 1: [Parameter] f # 519| Type = [FloatType] float -# 519| body: [Block] { ... } +# 519| body: [BlockStmt] { ... } # 520| 0: [DeclStmt] declaration # 520| 0: [VariableDeclarationEntry] definition of a1 # 520| Type = [ArrayType] int[3] @@ -5057,7 +5057,7 @@ ir.cpp: # 530| Type = [IntType] int # 530| 1: [Parameter] f # 530| Type = [FloatType] float -# 530| body: [Block] { ... } +# 530| body: [BlockStmt] { ... } # 531| 0: [DeclStmt] declaration # 531| 0: [VariableDeclarationEntry] definition of u1 # 531| Type = [Union] U @@ -5079,7 +5079,7 @@ ir.cpp: # 535| Type = [IntType] int # 535| 1: [Parameter] y # 535| Type = [IntType] int -# 535| body: [Block] { ... } +# 535| body: [BlockStmt] { ... } # 536| 0: [IfStmt] if (...) ... # 536| 0: [LTExpr] ... < ... # 536| Type = [BoolType] bool @@ -5090,7 +5090,7 @@ ir.cpp: # 536| 1: [VariableAccess] y # 536| Type = [IntType] int # 536| ValueCategory = prvalue(load) -# 536| 1: [Block] { ... } +# 536| 1: [BlockStmt] { ... } # 537| 0: [ReturnStmt] return ... # 540| 1: [ExprStmt] ExprStmt # 540| 0: [AssignExpr] ... = ... @@ -5109,7 +5109,7 @@ ir.cpp: # 543| Type = [IntType] int # 543| 1: [Parameter] y # 543| Type = [IntType] int -# 543| body: [Block] { ... } +# 543| body: [BlockStmt] { ... } # 544| 0: [IfStmt] if (...) ... # 544| 0: [LTExpr] ... < ... # 544| Type = [BoolType] bool @@ -5120,7 +5120,7 @@ ir.cpp: # 544| 1: [VariableAccess] y # 544| Type = [IntType] int # 544| ValueCategory = prvalue(load) -# 544| 1: [Block] { ... } +# 544| 1: [BlockStmt] { ... } # 545| 0: [ReturnStmt] return ... # 545| 0: [VariableAccess] x # 545| Type = [IntType] int @@ -5139,7 +5139,7 @@ ir.cpp: # 551| params: # 551| 0: [Parameter] pfn # 551| Type = [FunctionPointerType] ..(*)(..) -# 551| body: [Block] { ... } +# 551| body: [BlockStmt] { ... } # 552| 0: [ReturnStmt] return ... # 552| 0: [VariableCall] call to expression # 552| Type = [IntType] int @@ -5155,7 +5155,7 @@ ir.cpp: # 560| params: # 560| 0: [Parameter] e # 560| Type = [CTypedefType] E -# 560| body: [Block] { ... } +# 560| body: [BlockStmt] { ... } # 561| 0: [SwitchStmt] switch (...) ... # 561| 0: [CStyleCast] (int)... # 561| Conversion = [IntegralConversion] integral conversion @@ -5164,7 +5164,7 @@ ir.cpp: # 561| expr: [VariableAccess] e # 561| Type = [CTypedefType] E # 561| ValueCategory = prvalue(load) -# 561| 1: [Block] { ... } +# 561| 1: [BlockStmt] { ... } # 562| 0: [SwitchCase] case ...: # 562| 0: [CStyleCast] (int)... # 562| Conversion = [IntegralConversion] integral conversion @@ -5207,7 +5207,7 @@ ir.cpp: # 567| ValueCategory = prvalue # 571| [TopLevelFunction] void InitArray() # 571| params: -# 571| body: [Block] { ... } +# 571| body: [BlockStmt] { ... } # 572| 0: [DeclStmt] declaration # 572| 0: [VariableDeclarationEntry] definition of a_pad # 572| Type = [ArrayType] char[32] @@ -5306,7 +5306,7 @@ ir.cpp: # 582| Type = [PointerType] const char * # 584| [TopLevelFunction] void VarArgs() # 584| params: -# 584| body: [Block] { ... } +# 584| body: [BlockStmt] { ... } # 585| 0: [ExprStmt] ExprStmt # 585| 0: [FunctionCall] call to VarArgFunction # 585| Type = [VoidType] void @@ -5336,7 +5336,7 @@ ir.cpp: # 588| Type = [IntType] int # 590| [TopLevelFunction] void SetFuncPtr() # 590| params: -# 590| body: [Block] { ... } +# 590| body: [BlockStmt] { ... } # 591| 0: [DeclStmt] declaration # 591| 0: [VariableDeclarationEntry] definition of pfn # 591| Type = [FunctionPointerType] ..(*)(..) @@ -5421,7 +5421,7 @@ ir.cpp: # 613| params: # 615| [TopLevelFunction] void DeclareObject() # 615| params: -# 615| body: [Block] { ... } +# 615| body: [BlockStmt] { ... } # 616| 0: [DeclStmt] declaration # 616| 0: [VariableDeclarationEntry] definition of s1 # 616| Type = [Struct] String @@ -5473,7 +5473,7 @@ ir.cpp: # 622| Type = [PointerType] String * # 622| 2: [Parameter] s # 622| Type = [Struct] String -# 622| body: [Block] { ... } +# 622| body: [BlockStmt] { ... } # 623| 0: [ExprStmt] ExprStmt # 623| 0: [FunctionCall] call to c_str # 623| Type = [PointerType] const char * @@ -5529,7 +5529,7 @@ ir.cpp: #-----| Type = [RValueReferenceType] C && # 628| [Destructor] void C::~C() # 628| params: -#-----| body: [Block] { ... } +#-----| body: [BlockStmt] { ... } #-----| 0: [ReturnStmt] return ... # 628| destructions: # 628| 0: [DestructorFieldDestruction] destructor field destruction of m_f @@ -5554,7 +5554,7 @@ ir.cpp: # 630| params: # 630| 0: [Parameter] x # 630| Type = [IntType] int -# 630| body: [Block] { ... } +# 630| body: [BlockStmt] { ... } # 631| 0: [ReturnStmt] return ... # 631| 0: [VariableAccess] x # 631| Type = [IntType] int @@ -5563,7 +5563,7 @@ ir.cpp: # 634| params: # 634| 0: [Parameter] x # 634| Type = [IntType] int -# 634| body: [Block] { ... } +# 634| body: [BlockStmt] { ... } # 635| 0: [ReturnStmt] return ... # 635| 0: [VariableAccess] x # 635| Type = [IntType] int @@ -5572,14 +5572,14 @@ ir.cpp: # 638| params: # 638| 0: [Parameter] x # 638| Type = [IntType] int -# 638| body: [Block] { ... } +# 638| body: [BlockStmt] { ... } # 639| 0: [ReturnStmt] return ... # 639| 0: [VariableAccess] x # 639| Type = [IntType] int # 639| ValueCategory = prvalue(load) # 642| [MemberFunction] void C::FieldAccess() # 642| params: -# 642| body: [Block] { ... } +# 642| body: [BlockStmt] { ... } # 643| 0: [ExprStmt] ExprStmt # 643| 0: [AssignExpr] ... = ... # 643| Type = [IntType] int @@ -5679,7 +5679,7 @@ ir.cpp: # 650| 7: [ReturnStmt] return ... # 652| [MemberFunction] void C::MethodCalls() # 652| params: -# 652| body: [Block] { ... } +# 652| body: [BlockStmt] { ... } # 653| 0: [ExprStmt] ExprStmt # 653| 0: [FunctionCall] call to InstanceMemberFunction # 653| Type = [IntType] int @@ -5768,13 +5768,13 @@ ir.cpp: # 662| Type = [ArrayType] const char[5] # 662| Value = [StringLiteral] "test" # 662| ValueCategory = lvalue -# 663| body: [Block] { ... } +# 663| body: [BlockStmt] { ... } # 664| 0: [ReturnStmt] return ... # 675| [TopLevelFunction] int DerefReference(int&) # 675| params: # 675| 0: [Parameter] r # 675| Type = [LValueReferenceType] int & -# 675| body: [Block] { ... } +# 675| body: [BlockStmt] { ... } # 676| 0: [ReturnStmt] return ... # 676| 0: [ReferenceDereferenceExpr] (reference dereference) # 676| Type = [IntType] int @@ -5784,7 +5784,7 @@ ir.cpp: # 676| ValueCategory = prvalue(load) # 679| [TopLevelFunction] int& TakeReference() # 679| params: -# 679| body: [Block] { ... } +# 679| body: [BlockStmt] { ... } # 680| 0: [ReturnStmt] return ... # 680| 0: [ReferenceToExpr] (reference to) # 680| Type = [LValueReferenceType] int & @@ -5798,7 +5798,7 @@ ir.cpp: # 685| params: # 685| 0: [Parameter] x # 685| Type = [IntType] int -# 685| body: [Block] { ... } +# 685| body: [BlockStmt] { ... } # 686| 0: [DeclStmt] declaration # 686| 0: [VariableDeclarationEntry] definition of r # 686| Type = [LValueReferenceType] int & @@ -5842,7 +5842,7 @@ ir.cpp: # 689| 3: [ReturnStmt] return ... # 691| [TopLevelFunction] void ArrayReferences() # 691| params: -# 691| body: [Block] { ... } +# 691| body: [BlockStmt] { ... } # 692| 0: [DeclStmt] declaration # 692| 0: [VariableDeclarationEntry] definition of a # 692| Type = [ArrayType] int[10] @@ -5879,7 +5879,7 @@ ir.cpp: # 695| 3: [ReturnStmt] return ... # 697| [TopLevelFunction] void FunctionReferences() # 697| params: -# 697| body: [Block] { ... } +# 697| body: [BlockStmt] { ... } # 698| 0: [DeclStmt] declaration # 698| 0: [VariableDeclarationEntry] definition of rfn # 698| Type = [FunctionReferenceType] ..(&)(..) @@ -5921,7 +5921,7 @@ ir.cpp: # 704| Type = [TemplateParameter] T # 704| 1: [Parameter] y # 704| Type = [TemplateParameter] T -# 704| body: [Block] { ... } +# 704| body: [BlockStmt] { ... } # 705| 0: [ReturnStmt] return ... # 705| 0: [ConditionalExpr] ... ? ... : ... # 705| Type = [UnknownType] unknown @@ -5954,7 +5954,7 @@ ir.cpp: # 704| Type = [IntType] int # 704| 1: [Parameter] y # 704| Type = [IntType] int -# 704| body: [Block] { ... } +# 704| body: [BlockStmt] { ... } # 705| 0: [ReturnStmt] return ... # 705| 0: [ConditionalExpr] ... ? ... : ... # 705| Type = [IntType] int @@ -5983,7 +5983,7 @@ ir.cpp: # 708| Type = [IntType] int # 708| 1: [Parameter] y # 708| Type = [IntType] int -# 708| body: [Block] { ... } +# 708| body: [BlockStmt] { ... } # 709| 0: [ReturnStmt] return ... # 709| 0: [FunctionCall] call to min # 709| Type = [IntType] int @@ -6008,7 +6008,7 @@ ir.cpp: # 715| Type = [TemplateParameter] U # 715| 1: [Parameter] y # 715| Type = [TemplateParameter] V -# 715| body: [Block] { ... } +# 715| body: [BlockStmt] { ... } # 716| 0: [ReturnStmt] return ... # 716| 0: [Literal] 0 # 716| Type = [TemplateParameter] T @@ -6026,7 +6026,7 @@ ir.cpp: # 715| Type = [VoidPointerType] void * # 715| 1: [Parameter] y # 715| Type = [PlainCharType] char -# 715| body: [Block] { ... } +# 715| body: [BlockStmt] { ... } # 716| 0: [ReturnStmt] return ... # 716| 0: [Literal] 0 # 716| Type = [LongType] long @@ -6034,7 +6034,7 @@ ir.cpp: # 716| ValueCategory = prvalue # 720| [TopLevelFunction] double CallNestedTemplateFunc() # 720| params: -# 720| body: [Block] { ... } +# 720| body: [BlockStmt] { ... } # 721| 0: [ReturnStmt] return ... # 721| 0: [CStyleCast] (double)... # 721| Conversion = [IntegralToFloatingPointConversion] integral to floating point conversion @@ -6060,9 +6060,9 @@ ir.cpp: # 724| params: # 724| 0: [Parameter] b # 724| Type = [BoolType] bool -# 724| body: [Block] { ... } +# 724| body: [BlockStmt] { ... } # 725| 0: [TryStmt] try { ... } -# 725| 0: [Block] { ... } +# 725| 0: [BlockStmt] { ... } # 726| 0: [DeclStmt] declaration # 726| 0: [VariableDeclarationEntry] definition of x # 726| Type = [IntType] int @@ -6075,7 +6075,7 @@ ir.cpp: # 727| 0: [VariableAccess] b # 727| Type = [BoolType] bool # 727| ValueCategory = prvalue(load) -# 727| 1: [Block] { ... } +# 727| 1: [BlockStmt] { ... } # 728| 0: [ExprStmt] ExprStmt # 728| 0: [ThrowExpr] throw ... # 728| Type = [PointerType] const char * @@ -6098,7 +6098,7 @@ ir.cpp: # 730| Type = [IntType] int # 730| Value = [Literal] 2 # 730| ValueCategory = prvalue -# 730| 1: [Block] { ... } +# 730| 1: [BlockStmt] { ... } # 731| 0: [ExprStmt] ExprStmt # 731| 0: [AssignExpr] ... = ... # 731| Type = [IntType] int @@ -6165,7 +6165,7 @@ ir.cpp: # 745| params: #-----| 0: [Parameter] p#0 #-----| Type = [LValueReferenceType] const Base & -#-----| body: [Block] { ... } +#-----| body: [BlockStmt] { ... } #-----| 0: [ExprStmt] ExprStmt #-----| 0: [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [Struct] String @@ -6215,7 +6215,7 @@ ir.cpp: # 745| 0: [ConstructorCall] call to String # 745| Type = [VoidType] void # 745| ValueCategory = prvalue -# 745| body: [Block] { ... } +# 745| body: [BlockStmt] { ... } # 745| 0: [ReturnStmt] return ... # 748| [Constructor] void Base::Base() # 748| params: @@ -6226,11 +6226,11 @@ ir.cpp: # 748| 0: [ConstructorCall] call to String # 748| Type = [VoidType] void # 748| ValueCategory = prvalue -# 748| body: [Block] { ... } +# 748| body: [BlockStmt] { ... } # 749| 0: [ReturnStmt] return ... # 750| [Destructor] void Base::~Base() # 750| params: -# 750| body: [Block] { ... } +# 750| body: [BlockStmt] { ... } # 751| 0: [ReturnStmt] return ... # 750| destructions: # 751| 0: [DestructorFieldDestruction] destructor field destruction of base_s @@ -6246,7 +6246,7 @@ ir.cpp: # 754| params: #-----| 0: [Parameter] p#0 #-----| Type = [LValueReferenceType] const Middle & -#-----| body: [Block] { ... } +#-----| body: [BlockStmt] { ... } #-----| 0: [ExprStmt] ExprStmt #-----| 0: [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [Struct,VirtualBaseClass] Base @@ -6334,11 +6334,11 @@ ir.cpp: # 757| 0: [ConstructorCall] call to String # 757| Type = [VoidType] void # 757| ValueCategory = prvalue -# 757| body: [Block] { ... } +# 757| body: [BlockStmt] { ... } # 758| 0: [ReturnStmt] return ... # 759| [Destructor] void Middle::~Middle() # 759| params: -# 759| body: [Block] { ... } +# 759| body: [BlockStmt] { ... } # 760| 0: [ReturnStmt] return ... # 759| destructions: # 760| 0: [DestructorFieldDestruction] destructor field destruction of middle_s @@ -6357,7 +6357,7 @@ ir.cpp: # 763| params: #-----| 0: [Parameter] p#0 #-----| Type = [LValueReferenceType] const Derived & -#-----| body: [Block] { ... } +#-----| body: [BlockStmt] { ... } #-----| 0: [ExprStmt] ExprStmt #-----| 0: [ReferenceDereferenceExpr] (reference dereference) #-----| Type = [Struct] Middle @@ -6445,11 +6445,11 @@ ir.cpp: # 766| 0: [ConstructorCall] call to String # 766| Type = [VoidType] void # 766| ValueCategory = prvalue -# 766| body: [Block] { ... } +# 766| body: [BlockStmt] { ... } # 767| 0: [ReturnStmt] return ... # 768| [Destructor] void Derived::~Derived() # 768| params: -# 768| body: [Block] { ... } +# 768| body: [BlockStmt] { ... } # 769| 0: [ReturnStmt] return ... # 768| destructions: # 769| 0: [DestructorFieldDestruction] destructor field destruction of derived_s @@ -6484,11 +6484,11 @@ ir.cpp: # 775| 0: [ConstructorCall] call to String # 775| Type = [VoidType] void # 775| ValueCategory = prvalue -# 775| body: [Block] { ... } +# 775| body: [BlockStmt] { ... } # 776| 0: [ReturnStmt] return ... # 777| [Destructor] void MiddleVB1::~MiddleVB1() # 777| params: -# 777| body: [Block] { ... } +# 777| body: [BlockStmt] { ... } # 778| 0: [ReturnStmt] return ... # 777| destructions: # 778| 0: [DestructorFieldDestruction] destructor field destruction of middlevb1_s @@ -6523,11 +6523,11 @@ ir.cpp: # 784| 0: [ConstructorCall] call to String # 784| Type = [VoidType] void # 784| ValueCategory = prvalue -# 784| body: [Block] { ... } +# 784| body: [BlockStmt] { ... } # 785| 0: [ReturnStmt] return ... # 786| [Destructor] void MiddleVB2::~MiddleVB2() # 786| params: -# 786| body: [Block] { ... } +# 786| body: [BlockStmt] { ... } # 787| 0: [ReturnStmt] return ... # 786| destructions: # 787| 0: [DestructorFieldDestruction] destructor field destruction of middlevb2_s @@ -6568,11 +6568,11 @@ ir.cpp: # 793| 0: [ConstructorCall] call to String # 793| Type = [VoidType] void # 793| ValueCategory = prvalue -# 793| body: [Block] { ... } +# 793| body: [BlockStmt] { ... } # 794| 0: [ReturnStmt] return ... # 795| [Destructor] void DerivedVB::~DerivedVB() # 795| params: -# 795| body: [Block] { ... } +# 795| body: [BlockStmt] { ... } # 796| 0: [ReturnStmt] return ... # 795| destructions: # 796| 0: [DestructorFieldDestruction] destructor field destruction of derivedvb_s @@ -6595,7 +6595,7 @@ ir.cpp: # 796| ValueCategory = prvalue # 799| [TopLevelFunction] void HierarchyConversions() # 799| params: -# 799| body: [Block] { ... } +# 799| body: [BlockStmt] { ... } # 800| 0: [DeclStmt] declaration # 800| 0: [VariableDeclarationEntry] definition of b # 800| Type = [Struct,VirtualBaseClass] Base @@ -7201,7 +7201,7 @@ ir.cpp: # 842| [Constructor] void PolymorphicBase::PolymorphicBase() # 842| params: # 842| initializations: -# 842| body: [Block] { ... } +# 842| body: [BlockStmt] { ... } # 842| 0: [ReturnStmt] return ... # 842| [CopyConstructor] void PolymorphicBase::PolymorphicBase(PolymorphicBase const&) # 842| params: @@ -7223,7 +7223,7 @@ ir.cpp: # 846| 0: [ConstructorDirectInit] call to PolymorphicBase # 846| Type = [VoidType] void # 846| ValueCategory = prvalue -# 846| body: [Block] { ... } +# 846| body: [BlockStmt] { ... } # 846| 0: [ReturnStmt] return ... # 846| [CopyConstructor] void PolymorphicDerived::PolymorphicDerived(PolymorphicDerived const&) # 846| params: @@ -7235,7 +7235,7 @@ ir.cpp: #-----| Type = [RValueReferenceType] PolymorphicDerived && # 846| [Destructor,VirtualFunction] void PolymorphicDerived::~PolymorphicDerived() # 846| params: -#-----| body: [Block] { ... } +#-----| body: [BlockStmt] { ... } #-----| 0: [ReturnStmt] return ... # 846| destructions: # 846| 0: [DestructorDirectDestruction] call to ~PolymorphicBase @@ -7243,7 +7243,7 @@ ir.cpp: # 846| ValueCategory = prvalue # 849| [TopLevelFunction] void DynamicCast() # 849| params: -# 849| body: [Block] { ... } +# 849| body: [BlockStmt] { ... } # 850| 0: [DeclStmt] declaration # 850| 0: [VariableDeclarationEntry] definition of b # 850| Type = [Struct] PolymorphicBase @@ -7370,11 +7370,11 @@ ir.cpp: # 868| Type = [ArrayType] const char[1] # 868| Value = [StringLiteral] "" # 868| ValueCategory = lvalue -# 868| body: [Block] { ... } +# 868| body: [BlockStmt] { ... } # 869| 0: [ReturnStmt] return ... # 871| [TopLevelFunction] void ArrayConversions() # 871| params: -# 871| body: [Block] { ... } +# 871| body: [BlockStmt] { ... } # 872| 0: [DeclStmt] declaration # 872| 0: [VariableDeclarationEntry] definition of a # 872| Type = [ArrayType] char[5] @@ -7513,7 +7513,7 @@ ir.cpp: # 883| Type = [FunctionPointerType] ..(*)(..) # 883| 1: [Parameter] p # 883| Type = [VoidPointerType] void * -# 883| body: [Block] { ... } +# 883| body: [BlockStmt] { ... } # 884| 0: [ExprStmt] ExprStmt # 884| 0: [AssignExpr] ... = ... # 884| Type = [VoidPointerType] void * @@ -7549,7 +7549,7 @@ ir.cpp: # 888| Type = [IntType] int # 888| 1: [Parameter] args # 888| Type = [ArrayType] __va_list_tag[1] -# 888| body: [Block] { ... } +# 888| body: [BlockStmt] { ... } # 889| 0: [DeclStmt] declaration # 889| 0: [VariableDeclarationEntry] definition of args2 # 889| Type = [ArrayType] __va_list_tag[1] @@ -7605,7 +7605,7 @@ ir.cpp: # 896| params: # 896| 0: [Parameter] x # 896| Type = [IntType] int -# 896| body: [Block] { ... } +# 896| body: [BlockStmt] { ... } # 897| 0: [DeclStmt] declaration # 897| 0: [VariableDeclarationEntry] definition of args # 897| Type = [ArrayType] __va_list_tag[1] @@ -7709,7 +7709,7 @@ ir.cpp: # 909| params: # 909| 0: [Parameter] x # 909| Type = [IntType] int -# 909| body: [Block] { ... } +# 909| body: [BlockStmt] { ... } # 910| 0: [ExprStmt] ExprStmt # 910| 0: [CStyleCast] (void)... # 910| Conversion = [VoidConversion] conversion to void @@ -7723,7 +7723,7 @@ ir.cpp: # 913| params: # 913| 0: [Parameter] x # 913| Type = [IntType] int -# 913| body: [Block] { ... } +# 913| body: [BlockStmt] { ... } # 914| 0: [DeclStmt] declaration # 914| 0: [VariableDeclarationEntry] definition of a # 914| Type = [BoolType] bool @@ -7876,7 +7876,7 @@ ir.cpp: # 946| Type = [DoubleType] double # 949| [TopLevelFunction] void OperatorNew() # 949| params: -# 949| body: [Block] { ... } +# 949| body: [BlockStmt] { ... } # 950| 0: [ExprStmt] ExprStmt # 950| 0: [NewExpr] new # 950| Type = [IntPointerType] int * @@ -7969,7 +7969,7 @@ ir.cpp: # 959| params: # 959| 0: [Parameter] n # 959| Type = [IntType] int -# 959| body: [Block] { ... } +# 959| body: [BlockStmt] { ... } # 960| 0: [ExprStmt] ExprStmt # 960| 0: [NewArrayExpr] new[] # 960| Type = [IntPointerType] int * @@ -8078,7 +8078,7 @@ ir.cpp: # 968| 8: [ReturnStmt] return ... # 970| [TopLevelFunction] int designatedInit() # 970| params: -# 970| body: [Block] { ... } +# 970| body: [BlockStmt] { ... } # 971| 0: [DeclStmt] declaration # 971| 0: [VariableDeclarationEntry] definition of a1 # 971| Type = [ArrayType] int[1000] @@ -8114,7 +8114,7 @@ ir.cpp: # 975| Type = [IntType] int # 975| 1: [Parameter] y # 975| Type = [IntType] int -# 975| body: [Block] { ... } +# 975| body: [BlockStmt] { ... } # 976| 0: [IfStmt] if (...) ... # 976| 0: [ConditionDeclExpr] (condition decl) # 976| Type = [BoolType] bool @@ -8122,7 +8122,7 @@ ir.cpp: # 976| 0: [VariableAccess] b # 976| Type = [BoolType] bool # 976| ValueCategory = prvalue(load) -# 976| 1: [Block] { ... } +# 976| 1: [BlockStmt] { ... } # 977| 0: [ExprStmt] ExprStmt # 977| 0: [AssignExpr] ... = ... # 977| Type = [IntType] int @@ -8145,7 +8145,7 @@ ir.cpp: # 979| expr: [VariableAccess] z # 979| Type = [IntType] int # 979| ValueCategory = prvalue(load) -# 979| 1: [Block] { ... } +# 979| 1: [BlockStmt] { ... } # 980| 0: [ExprStmt] ExprStmt # 980| 0: [AssignExpr] ... = ... # 980| Type = [IntType] int @@ -8168,7 +8168,7 @@ ir.cpp: # 982| expr: [VariableAccess] p # 982| Type = [IntPointerType] int * # 982| ValueCategory = prvalue(load) -# 982| 1: [Block] { ... } +# 982| 1: [BlockStmt] { ... } # 983| 0: [ExprStmt] ExprStmt # 983| 0: [AssignExpr] ... = ... # 983| Type = [IntType] int @@ -8190,7 +8190,7 @@ ir.cpp: # 987| Type = [IntType] int # 987| 1: [Parameter] y # 987| Type = [IntType] int -# 987| body: [Block] { ... } +# 987| body: [BlockStmt] { ... } # 988| 0: [WhileStmt] while (...) ... # 988| 0: [ConditionDeclExpr] (condition decl) # 988| Type = [BoolType] bool @@ -8198,7 +8198,7 @@ ir.cpp: # 988| 0: [VariableAccess] b # 988| Type = [BoolType] bool # 988| ValueCategory = prvalue(load) -# 988| 1: [Block] { ... } +# 988| 1: [BlockStmt] { ... } # 990| 1: [WhileStmt] while (...) ... # 990| 0: [ConditionDeclExpr] (condition decl) # 990| Type = [BoolType] bool @@ -8210,7 +8210,7 @@ ir.cpp: # 990| expr: [VariableAccess] z # 990| Type = [IntType] int # 990| ValueCategory = prvalue(load) -# 990| 1: [Block] { ... } +# 990| 1: [BlockStmt] { ... } # 992| 2: [WhileStmt] while (...) ... # 992| 0: [ConditionDeclExpr] (condition decl) # 992| Type = [BoolType] bool @@ -8222,7 +8222,7 @@ ir.cpp: # 992| expr: [VariableAccess] p # 992| Type = [IntPointerType] int * # 992| ValueCategory = prvalue(load) -# 992| 1: [Block] { ... } +# 992| 1: [BlockStmt] { ... } # 994| 3: [ReturnStmt] return ... # 996| [TopLevelFunction] int PointerDecay(int[], int(float)) # 996| params: @@ -8230,7 +8230,7 @@ ir.cpp: # 996| Type = [ArrayType] int[] # 996| 1: [Parameter] fn # 996| Type = [RoutineType] ..()(..) -# 996| body: [Block] { ... } +# 996| body: [BlockStmt] { ... } # 997| 0: [ReturnStmt] return ... # 997| 0: [AddExpr] ... + ... # 997| Type = [IntType] int @@ -8268,7 +8268,7 @@ ir.cpp: # 1000| Type = [IntType] int # 1000| 2: [Parameter] z # 1000| Type = [IntType] int -# 1000| body: [Block] { ... } +# 1000| body: [BlockStmt] { ... } # 1001| 0: [DeclStmt] declaration # 1001| 0: [VariableDeclarationEntry] definition of x # 1001| Type = [IntType] int @@ -8282,7 +8282,7 @@ ir.cpp: # 1011| ValueCategory = prvalue # 1015| [TopLevelFunction] void OperatorDelete() # 1015| params: -# 1015| body: [Block] { ... } +# 1015| body: [BlockStmt] { ... } # 1016| 0: [ExprStmt] ExprStmt # 1016| 0: [DeleteExpr] delete # 1016| Type = [VoidType] void @@ -8360,7 +8360,7 @@ ir.cpp: # 1021| 5: [ReturnStmt] return ... # 1024| [TopLevelFunction] void OperatorDeleteArray() # 1024| params: -# 1024| body: [Block] { ... } +# 1024| body: [BlockStmt] { ... } # 1025| 0: [ExprStmt] ExprStmt # 1025| 0: [DeleteArrayExpr] delete[] # 1025| Type = [VoidType] void @@ -8446,7 +8446,7 @@ ir.cpp: #-----| Type = [RValueReferenceType] EmptyStruct && # 1034| [TopLevelFunction] void EmptyStructInit() # 1034| params: -# 1034| body: [Block] { ... } +# 1034| body: [BlockStmt] { ... } # 1035| 0: [DeclStmt] declaration # 1035| 0: [VariableDeclarationEntry] definition of s # 1035| Type = [Struct] EmptyStruct @@ -8473,11 +8473,11 @@ ir.cpp: # 1038| params: # 1038| [ConstMemberFunction] void (lambda [] type at line 1038, col. 12)::operator()() const # 1038| params: -# 1038| body: [Block] { ... } +# 1038| body: [BlockStmt] { ... } # 1038| 0: [ReturnStmt] return ... # 1038| [ConstMemberFunction,ConversionOperator] void(* (lambda [] type at line 1038, col. 12)::operator void (*)()() const)() # 1038| params: -#-----| body: [Block] { ... } +#-----| body: [BlockStmt] { ... } # 1038| 0: [ReturnStmt] return ... # 1038| 0: [FunctionAccess] _FUN # 1038| Type = [FunctionPointerType] ..(*)(..) @@ -8488,7 +8488,7 @@ ir.cpp: # 1040| Type = [IntType] int # 1040| 1: [Parameter] s # 1040| Type = [LValueReferenceType] const String & -# 1040| body: [Block] { ... } +# 1040| body: [BlockStmt] { ... } # 1041| 0: [DeclStmt] declaration # 1041| 0: [VariableDeclarationEntry] definition of lambda_empty # 1041| Type = [Closure,LocalClass] decltype([...](...){...}) @@ -8807,7 +8807,7 @@ ir.cpp: # 1041| params: # 1041| 0: [Parameter] f # 1041| Type = [FloatType] float -# 1041| body: [Block] { ... } +# 1041| body: [BlockStmt] { ... } # 1041| 0: [ReturnStmt] return ... # 1041| 0: [CharLiteral] 65 # 1041| Type = [PlainCharType] char @@ -8815,7 +8815,7 @@ ir.cpp: # 1041| ValueCategory = prvalue # 1041| [ConstMemberFunction,ConversionOperator] char(* (void Lambda(int, String const&))::(lambda [] type at line 1041, col. 23)::operator char (*)(float)() const)(float) # 1041| params: -#-----| body: [Block] { ... } +#-----| body: [BlockStmt] { ... } # 1041| 0: [ReturnStmt] return ... # 1041| 0: [FunctionAccess] _FUN # 1041| Type = [FunctionPointerType] ..(*)(..) @@ -8838,7 +8838,7 @@ ir.cpp: # 1043| params: # 1043| 0: [Parameter] f # 1043| Type = [FloatType] float -# 1043| body: [Block] { ... } +# 1043| body: [BlockStmt] { ... } # 1043| 0: [ReturnStmt] return ... # 1043| 0: [ArrayExpr] access to array # 1043| Type = [PlainCharType] char @@ -8880,7 +8880,7 @@ ir.cpp: # 1045| params: # 1045| [Destructor] void (void Lambda(int, String const&))::(lambda [] type at line 1045, col. 21)::~() # 1045| params: -#-----| body: [Block] { ... } +#-----| body: [BlockStmt] { ... } #-----| 0: [ReturnStmt] return ... # 1045| destructions: # 1045| 0: [DestructorFieldDestruction] destructor field destruction of s @@ -8896,7 +8896,7 @@ ir.cpp: # 1045| params: # 1045| 0: [Parameter] f # 1045| Type = [FloatType] float -# 1045| body: [Block] { ... } +# 1045| body: [BlockStmt] { ... } # 1045| 0: [ReturnStmt] return ... # 1045| 0: [ArrayExpr] access to array # 1045| Type = [PlainCharType] char @@ -8934,7 +8934,7 @@ ir.cpp: # 1047| params: # 1047| 0: [Parameter] f # 1047| Type = [FloatType] float -# 1047| body: [Block] { ... } +# 1047| body: [BlockStmt] { ... } # 1047| 0: [ReturnStmt] return ... # 1047| 0: [ArrayExpr] access to array # 1047| Type = [PlainCharType] char @@ -8971,7 +8971,7 @@ ir.cpp: # 1049| params: # 1049| [Destructor] void (void Lambda(int, String const&))::(lambda [] type at line 1049, col. 30)::~() # 1049| params: -#-----| body: [Block] { ... } +#-----| body: [BlockStmt] { ... } #-----| 0: [ReturnStmt] return ... # 1049| destructions: # 1049| 0: [DestructorFieldDestruction] destructor field destruction of s @@ -8987,7 +8987,7 @@ ir.cpp: # 1049| params: # 1049| 0: [Parameter] f # 1049| Type = [FloatType] float -# 1049| body: [Block] { ... } +# 1049| body: [BlockStmt] { ... } # 1049| 0: [ReturnStmt] return ... # 1049| 0: [ArrayExpr] access to array # 1049| Type = [PlainCharType] char @@ -9023,7 +9023,7 @@ ir.cpp: # 1051| params: # 1051| 0: [Parameter] f # 1051| Type = [FloatType] float -# 1051| body: [Block] { ... } +# 1051| body: [BlockStmt] { ... } # 1051| 0: [ReturnStmt] return ... # 1051| 0: [ArrayExpr] access to array # 1051| Type = [PlainCharType] char @@ -9064,7 +9064,7 @@ ir.cpp: # 1054| params: # 1054| 0: [Parameter] f # 1054| Type = [FloatType] float -# 1054| body: [Block] { ... } +# 1054| body: [BlockStmt] { ... } # 1054| 0: [ReturnStmt] return ... # 1054| 0: [ArrayExpr] access to array # 1054| Type = [PlainCharType] char @@ -9164,7 +9164,7 @@ ir.cpp: # 1077| params: # 1077| 0: [Parameter] v # 1077| Type = [LValueReferenceType] const vector & -# 1077| body: [Block] { ... } +# 1077| body: [BlockStmt] { ... } # 1078| 0: [RangeBasedForStmt] for(...:...) ... # 1078| 0: [DeclStmt] declaration # 1078| 1: [DeclStmt] declaration @@ -9191,7 +9191,7 @@ ir.cpp: # 1078| Type = [NestedStruct] iterator # 1078| ValueCategory = lvalue # 1078| 4: [DeclStmt] declaration -# 1078| 5: [Block] { ... } +# 1078| 5: [BlockStmt] { ... } # 1079| 0: [IfStmt] if (...) ... # 1079| 0: [GTExpr] ... > ... # 1079| Type = [BoolType] bool @@ -9203,7 +9203,7 @@ ir.cpp: # 1079| Type = [IntType] int # 1079| Value = [Literal] 0 # 1079| ValueCategory = prvalue -# 1079| 1: [Block] { ... } +# 1079| 1: [BlockStmt] { ... } # 1080| 0: [ContinueStmt] continue; # 1078| 1: [LabelStmt] label ...: # 1084| 1: [RangeBasedForStmt] for(...:...) ... @@ -9232,7 +9232,7 @@ ir.cpp: # 1084| Type = [NestedStruct] iterator # 1084| ValueCategory = lvalue # 1084| 4: [DeclStmt] declaration -# 1084| 5: [Block] { ... } +# 1084| 5: [BlockStmt] { ... } # 1085| 0: [IfStmt] if (...) ... # 1085| 0: [LTExpr] ... < ... # 1085| Type = [BoolType] bool @@ -9247,7 +9247,7 @@ ir.cpp: # 1085| Type = [IntType] int # 1085| Value = [Literal] 5 # 1085| ValueCategory = prvalue -# 1085| 1: [Block] { ... } +# 1085| 1: [BlockStmt] { ... } # 1086| 0: [BreakStmt] break; # 1088| 2: [LabelStmt] label ...: # 1089| 3: [ReturnStmt] return ... @@ -9255,7 +9255,7 @@ ir.cpp: # 1108| params: # 1108| 0: [Parameter] x # 1108| Type = [IntType] int -# 1108| body: [Block] { ... } +# 1108| body: [BlockStmt] { ... } # 1109| 0: [AsmStmt] asm statement # 1110| 1: [ReturnStmt] return ... # 1110| 0: [VariableAccess] x @@ -9271,7 +9271,7 @@ ir.cpp: # 1113| Type = [LValueReferenceType] unsigned int & # 1113| 3: [Parameter] d # 1113| Type = [IntType] unsigned int -# 1114| body: [Block] { ... } +# 1114| body: [BlockStmt] { ... } # 1115| 0: [AsmStmt] asm statement # 1118| 0: [ReferenceDereferenceExpr] (reference dereference) # 1118| Type = [IntType] unsigned int @@ -9294,7 +9294,7 @@ ir.cpp: # 1120| 1: [ReturnStmt] return ... # 1122| [TopLevelFunction] void ExternDeclarations() # 1122| params: -# 1123| body: [Block] { ... } +# 1123| body: [BlockStmt] { ... } # 1124| 0: [DeclStmt] declaration # 1124| 0: [VariableDeclarationEntry] declaration of g # 1124| Type = [IntType] int @@ -9331,7 +9331,7 @@ ir.cpp: # 1127| Type = [FloatType] float # 1137| [TopLevelFunction] void ExternDeclarationsInMacro() # 1137| params: -# 1138| body: [Block] { ... } +# 1138| body: [BlockStmt] { ... } # 1139| 0: [DeclStmt] declaration # 1139| 0: [VariableDeclarationEntry] declaration of g # 1139| Type = [IntType] int @@ -9360,7 +9360,7 @@ ir.cpp: # 1139| 0: [VariableAccess] i # 1139| Type = [IntType] int # 1139| ValueCategory = lvalue -# 1139| 3: [Block] { ... } +# 1139| 3: [BlockStmt] { ... } # 1139| 0: [DeclStmt] declaration # 1139| 0: [VariableDeclarationEntry] declaration of g # 1139| Type = [IntType] int @@ -9370,9 +9370,9 @@ ir.cpp: # 1142| params: # 1142| 0: [Parameter] b # 1142| Type = [BoolType] bool -# 1142| body: [Block] { ... } +# 1142| body: [BlockStmt] { ... } # 1143| 0: [TryStmt] try { ... } -# 1143| 0: [Block] { ... } +# 1143| 0: [BlockStmt] { ... } # 1144| 0: [DeclStmt] declaration # 1144| 0: [VariableDeclarationEntry] definition of x # 1144| Type = [IntType] int @@ -9385,7 +9385,7 @@ ir.cpp: # 1145| 0: [VariableAccess] b # 1145| Type = [BoolType] bool # 1145| ValueCategory = prvalue(load) -# 1145| 1: [Block] { ... } +# 1145| 1: [BlockStmt] { ... } # 1146| 0: [ExprStmt] ExprStmt # 1146| 0: [ThrowExpr] throw ... # 1146| Type = [PointerType] const char * @@ -9408,7 +9408,7 @@ ir.cpp: # 1148| Type = [IntType] int # 1148| Value = [Literal] 2 # 1148| ValueCategory = prvalue -# 1148| 1: [Block] { ... } +# 1148| 1: [BlockStmt] { ... } # 1149| 0: [ExprStmt] ExprStmt # 1149| 0: [AssignExpr] ... = ... # 1149| Type = [IntType] int @@ -9469,7 +9469,7 @@ ir.cpp: # 1162| params: # 1162| 0: [Parameter] i # 1162| Type = [IntType] int -# 1162| body: [Block] { ... } +# 1162| body: [BlockStmt] { ... } # 1163| 0: [DeclStmt] declaration # 1163| 0: [VariableDeclarationEntry] definition of vi4 # 1163| Type = [SpecifiedType] __attribute((vector_size(16UL))) int @@ -9588,7 +9588,7 @@ ir.cpp: # 1172| params: # 1172| 0: [Parameter] x # 1172| Type = [IntType] int -# 1172| body: [Block] { ... } +# 1172| body: [BlockStmt] { ... } # 1173| 0: [DeclStmt] declaration # 1173| 0: [VariableDeclarationEntry] definition of y # 1173| Type = [IntType] int @@ -9631,7 +9631,7 @@ ir.cpp: # 1175| ValueCategory = prvalue(load) # 1178| [TopLevelFunction] String ReturnObjectImpl() # 1178| params: -# 1178| body: [Block] { ... } +# 1178| body: [BlockStmt] { ... } # 1179| 0: [ReturnStmt] return ... # 1179| 0: [ConstructorCall] call to String # 1179| Type = [Struct] String @@ -9647,7 +9647,7 @@ ir.cpp: # 1182| params: # 1182| 0: [Parameter] x # 1182| Type = [IntType] int -# 1182| body: [Block] { ... } +# 1182| body: [BlockStmt] { ... } # 1183| 0: [DeclStmt] declaration # 1183| 0: [VariableDeclarationEntry] definition of y # 1183| Type = [IntType] int @@ -9660,7 +9660,7 @@ ir.cpp: # 1184| 0: [VariableAccess] x # 1184| Type = [IntType] int # 1184| ValueCategory = prvalue(load) -# 1184| 1: [Block] { ... } +# 1184| 1: [BlockStmt] { ... } # 1185| 0: [SwitchCase] case ...: # 1185| 0: [Literal] 1 # 1185| Type = [IntType] int @@ -9689,7 +9689,7 @@ ir.cpp: # 1191| params: # 1191| 0: [Parameter] x # 1191| Type = [IntType] int -# 1191| body: [Block] { ... } +# 1191| body: [BlockStmt] { ... } # 1192| 0: [DeclStmt] declaration # 1192| 0: [VariableDeclarationEntry] definition of y # 1192| Type = [IntType] int @@ -9702,7 +9702,7 @@ ir.cpp: # 1193| 0: [VariableAccess] x # 1193| Type = [IntType] int # 1193| ValueCategory = prvalue(load) -# 1193| 1: [Block] { ... } +# 1193| 1: [BlockStmt] { ... } # 1194| 0: [SwitchCase] case ...: # 1194| 0: [Literal] 1 # 1194| Type = [IntType] int @@ -9747,7 +9747,7 @@ ir.cpp: # 1202| params: # 1202| 0: [Parameter] x # 1202| Type = [IntType] int -# 1202| body: [Block] { ... } +# 1202| body: [BlockStmt] { ... } # 1203| 0: [DeclStmt] declaration # 1203| 0: [VariableDeclarationEntry] definition of y # 1203| Type = [IntType] int @@ -9760,7 +9760,7 @@ ir.cpp: # 1204| 0: [VariableAccess] x # 1204| Type = [IntType] int # 1204| ValueCategory = prvalue(load) -# 1204| 1: [Block] { ... } +# 1204| 1: [BlockStmt] { ... } # 1205| 0: [SwitchCase] case ...: # 1205| 0: [Literal] 1 # 1205| Type = [IntType] int @@ -9807,7 +9807,7 @@ ir.cpp: # 1214| params: # 1214| 0: [Parameter] x # 1214| Type = [IntType] int -# 1214| body: [Block] { ... } +# 1214| body: [BlockStmt] { ... } # 1215| 0: [DeclStmt] declaration # 1215| 0: [VariableDeclarationEntry] definition of y # 1215| Type = [IntType] int @@ -9820,7 +9820,7 @@ ir.cpp: # 1216| 0: [VariableAccess] x # 1216| Type = [IntType] int # 1216| ValueCategory = prvalue(load) -# 1216| 1: [Block] { ... } +# 1216| 1: [BlockStmt] { ... } # 1217| 0: [SwitchCase] case ...: # 1217| 0: [Literal] 1 # 1217| Type = [IntType] int @@ -9880,7 +9880,7 @@ ir.cpp: # 1231| params: # 1231| 0: [Parameter] x # 1231| Type = [IntType] int -# 1231| body: [Block] { ... } +# 1231| body: [BlockStmt] { ... } # 1232| 0: [DeclStmt] declaration # 1232| 0: [VariableDeclarationEntry] definition of a # 1232| Type = [IntType] int @@ -9944,7 +9944,7 @@ ir.cpp: # 1240| params: # 1240| 0: [Parameter] dynamic # 1240| Type = [PointerType] const char * -# 1240| body: [Block] { ... } +# 1240| body: [BlockStmt] { ... } # 1241| 0: [DeclStmt] declaration # 1241| 0: [VariableDeclarationEntry] definition of a # 1241| Type = [Struct] String @@ -9995,7 +9995,7 @@ ir.cpp: # 1251| Type = [CharPointerType] char * # 1251| 1: [Parameter] s2 # 1251| Type = [CharPointerType] char * -# 1251| body: [Block] { ... } +# 1251| body: [BlockStmt] { ... } # 1252| 0: [DeclStmt] declaration # 1252| 0: [VariableDeclarationEntry] definition of buffer # 1252| Type = [ArrayType] char[1024] @@ -10061,7 +10061,7 @@ ir.cpp: # 1261| Type = [PointerType] A * # 1261| 1: [Parameter] x # 1261| Type = [IntType] int -# 1261| body: [Block] { ... } +# 1261| body: [BlockStmt] { ... } # 1262| 0: [ExprStmt] ExprStmt # 1262| 0: [AssignExpr] ... = ... # 1262| Type = [IntType] int @@ -10086,7 +10086,7 @@ ir.cpp: # 1270| Type = [IntType] int # 1270| 1: [Parameter] a_arg # 1270| Type = [PointerType] A * -# 1270| body: [Block] { ... } +# 1270| body: [BlockStmt] { ... } # 1271| 0: [DeclStmt] declaration # 1271| 0: [VariableDeclarationEntry] definition of c # 1271| Type = [Class] C @@ -10237,12 +10237,12 @@ ir.cpp: # 1289| Type = [BoolType] bool # 1289| 1: [Parameter] x # 1289| Type = [IntType] int -# 1289| body: [Block] { ... } +# 1289| body: [BlockStmt] { ... } # 1290| 0: [IfStmt] if (...) ... # 1290| 0: [VariableAccess] b # 1290| Type = [BoolType] bool # 1290| ValueCategory = prvalue(load) -# 1290| 1: [Block] { ... } +# 1290| 1: [BlockStmt] { ... } # 1291| 0: [ReturnStmt] return ... # 1291| 0: [VariableAccess] x # 1291| Type = [IntType] int @@ -10254,7 +10254,7 @@ ir.cpp: # 1295| Type = [IntType] int # 1295| 1: [Parameter] y # 1295| Type = [IntType] int -# 1295| body: [Block] { ... } +# 1295| body: [BlockStmt] { ... } # 1296| 0: [ReturnStmt] return ... # 1296| 0: [FunctionCall] call to IntegerOps # 1296| Type = [VoidType] void @@ -10273,7 +10273,7 @@ ir.cpp: # 1299| Type = [IntType] int # 1299| 2: [Parameter] y # 1299| Type = [LongType] long -# 1299| body: [Block] { ... } +# 1299| body: [BlockStmt] { ... } # 1300| 0: [DeclStmt] declaration # 1300| 0: [VariableDeclarationEntry] definition of z # 1300| Type = [IntType] int @@ -10463,7 +10463,7 @@ ir.cpp: # 1314| Type = [IntType] int # 1314| 1: [Parameter] y # 1314| Type = [IntType] int -# 1314| body: [Block] { ... } +# 1314| body: [BlockStmt] { ... } # 1315| 0: [ReturnStmt] return ... # 1315| 0: [ConditionalExpr] ... ? ... : ... # 1315| Type = [IntType] int @@ -10493,7 +10493,7 @@ ir.cpp: # 1320| params: # 1320| 0: [Parameter] p # 1320| Type = [IntPointerType] int * -# 1321| body: [Block] { ... } +# 1321| body: [BlockStmt] { ... } # 1322| 0: [ExprStmt] ExprStmt # 1322| 0: [NewExpr] new # 1322| Type = [IntPointerType] int * @@ -10538,11 +10538,11 @@ perf-regression.cpp: # 6| 0: [ArrayAggregateLiteral] {...} # 6| Type = [ArrayType] char[1073741824] # 6| ValueCategory = prvalue -# 6| body: [Block] { ... } +# 6| body: [BlockStmt] { ... } # 6| 0: [ReturnStmt] return ... # 9| [TopLevelFunction] int main() # 9| params: -# 9| body: [Block] { ... } +# 9| body: [BlockStmt] { ... } # 10| 0: [DeclStmt] declaration # 10| 0: [VariableDeclarationEntry] definition of big # 10| Type = [PointerType] Big * @@ -10579,7 +10579,7 @@ struct_init.cpp: # 16| params: # 16| 0: [Parameter] info # 16| Type = [PointerType] Info * -# 16| body: [Block] { ... } +# 16| body: [BlockStmt] { ... } # 17| 0: [ExprStmt] ExprStmt # 17| 0: [AssignExpr] ... = ... # 17| Type = [PointerType] Info * @@ -10593,7 +10593,7 @@ struct_init.cpp: # 18| 1: [ReturnStmt] return ... # 20| [TopLevelFunction] void declare_static_infos() # 20| params: -# 20| body: [Block] { ... } +# 20| body: [BlockStmt] { ... } # 21| 0: [DeclStmt] declaration # 21| 0: [VariableDeclarationEntry] definition of static_infos # 21| Type = [ArrayType] Info[] @@ -10643,7 +10643,7 @@ struct_init.cpp: # 26| 2: [ReturnStmt] return ... # 28| [TopLevelFunction] void declare_local_infos() # 28| params: -# 28| body: [Block] { ... } +# 28| body: [BlockStmt] { ... } # 29| 0: [DeclStmt] declaration # 29| 0: [VariableDeclarationEntry] definition of local_infos # 29| Type = [ArrayType] Info[] @@ -10695,7 +10695,7 @@ struct_init.cpp: # 36| params: # 36| 0: [Parameter] name1 # 36| Type = [PointerType] const char * -# 36| body: [Block] { ... } +# 36| body: [BlockStmt] { ... } # 37| 0: [DeclStmt] declaration # 37| 0: [VariableDeclarationEntry] definition of static_infos # 37| Type = [ArrayType] Info[] diff --git a/cpp/ql/test/library-tests/macros/macros/affectedbymacroexpansion.ql b/cpp/ql/test/library-tests/macros/macros/affectedbymacroexpansion.ql index 4ba665e98cc..1c5b1c4b2de 100644 --- a/cpp/ql/test/library-tests/macros/macros/affectedbymacroexpansion.ql +++ b/cpp/ql/test/library-tests/macros/macros/affectedbymacroexpansion.ql @@ -1,5 +1,5 @@ import cpp -from Block b, MacroAccess m +from BlockStmt b, MacroAccess m where affectedbymacroexpansion(unresolveElement(b), unresolveElement(m)) select b, m diff --git a/cpp/ql/test/library-tests/macros/macros/inmacroexpansion.ql b/cpp/ql/test/library-tests/macros/macros/inmacroexpansion.ql index afed90b56a6..cfaae6f4e8c 100644 --- a/cpp/ql/test/library-tests/macros/macros/inmacroexpansion.ql +++ b/cpp/ql/test/library-tests/macros/macros/inmacroexpansion.ql @@ -1,5 +1,5 @@ import cpp -from Block b, MacroAccess m +from BlockStmt b, MacroAccess m where inmacroexpansion(unresolveElement(b), unresolveElement(m)) select b, m diff --git a/cpp/ql/test/library-tests/switch/blocks.ql b/cpp/ql/test/library-tests/switch/blocks.ql index 794c597d9a9..0c97f65ec3d 100644 --- a/cpp/ql/test/library-tests/switch/blocks.ql +++ b/cpp/ql/test/library-tests/switch/blocks.ql @@ -1,5 +1,5 @@ import cpp -from Function f, Block b +from Function f, BlockStmt b where b = f.getEntryPoint() select f, b, b.getAStmt() diff --git a/cpp/ql/test/library-tests/typedefs/Typedefs2.ql b/cpp/ql/test/library-tests/typedefs/Typedefs2.ql index 11c7e075909..122b826b556 100644 --- a/cpp/ql/test/library-tests/typedefs/Typedefs2.ql +++ b/cpp/ql/test/library-tests/typedefs/Typedefs2.ql @@ -1,6 +1,6 @@ import cpp -from Function f1, Block body, Declaration d +from Function f1, BlockStmt body, Declaration d where body = f1.getBlock() and d = body.getADeclaration() diff --git a/cpp/ql/test/library-tests/vla/blocks.ql b/cpp/ql/test/library-tests/vla/blocks.ql index 4de353e388c..bfd541e0162 100644 --- a/cpp/ql/test/library-tests/vla/blocks.ql +++ b/cpp/ql/test/library-tests/vla/blocks.ql @@ -1,4 +1,4 @@ import cpp -from Block b, int i +from BlockStmt b, int i select b, i, b.getStmt(i) diff --git a/cpp/ql/test/successor-tests/block/emptyblock/emptyblock01.ql b/cpp/ql/test/successor-tests/block/emptyblock/emptyblock01.ql index ecadf57692e..e2a1da4e2ed 100644 --- a/cpp/ql/test/successor-tests/block/emptyblock/emptyblock01.ql +++ b/cpp/ql/test/successor-tests/block/emptyblock/emptyblock01.ql @@ -1,6 +1,6 @@ import cpp -from Block s, int i, Stmt f, boolean succ +from BlockStmt s, int i, Stmt f, boolean succ where s.getParentStmt().hasChild(s, i) and s.getParentStmt().hasChild(f, i + 1) and diff --git a/cpp/ql/test/successor-tests/dostmt/dostmt04.ql b/cpp/ql/test/successor-tests/dostmt/dostmt04.ql index 61c1bb80f26..6b7a8a07178 100644 --- a/cpp/ql/test/successor-tests/dostmt/dostmt04.ql +++ b/cpp/ql/test/successor-tests/dostmt/dostmt04.ql @@ -8,7 +8,7 @@ import cpp from DoStmt ds, ExprStmt last, Expr succ where ds.getEnclosingFunction().hasName("normal") and - last = ds.getStmt().(Block).getLastStmt() and + last = ds.getStmt().(BlockStmt).getLastStmt() and succ = last.getExpr().getASuccessor() and succ = ds.getCondition().getAChild*() and count(last.getExpr().getASuccessor()) = 1 diff --git a/cpp/ql/test/successor-tests/forstmt/shortforstmt/shortforstmt04.ql b/cpp/ql/test/successor-tests/forstmt/shortforstmt/shortforstmt04.ql index a33bcb89808..3e5f4bfbbbe 100644 --- a/cpp/ql/test/successor-tests/forstmt/shortforstmt/shortforstmt04.ql +++ b/cpp/ql/test/successor-tests/forstmt/shortforstmt/shortforstmt04.ql @@ -9,7 +9,7 @@ import cpp from ForStmt fs, ExprStmt last, Expr succ where fs.getEnclosingFunction().hasName("normal") and - last = fs.getStmt().(Block).getLastStmt() and + last = fs.getStmt().(BlockStmt).getLastStmt() and succ = fs.getCondition().getAChild*() and succ = last.getExpr().getASuccessor() and count(last.getExpr().getASuccessor()) = 1 diff --git a/cpp/ql/test/successor-tests/ifstmt/ifelsestmt/ifelsestmt04.ql b/cpp/ql/test/successor-tests/ifstmt/ifelsestmt/ifelsestmt04.ql index c6fbf3c99f7..73f49a135c4 100644 --- a/cpp/ql/test/successor-tests/ifstmt/ifelsestmt/ifelsestmt04.ql +++ b/cpp/ql/test/successor-tests/ifstmt/ifelsestmt/ifelsestmt04.ql @@ -10,7 +10,7 @@ where is.getEnclosingFunction().hasName("normal") and is.getParentStmt().hasChild(is, k) and is.getParentStmt().hasChild(l3, k + 1) and - last = is.getThen().(Block).getLastStmt() and + last = is.getThen().(BlockStmt).getLastStmt() and l3 = last.getASuccessor() and count(last.getASuccessor()) = 1 select last, l3.getName() diff --git a/cpp/ql/test/successor-tests/ifstmt/ifelsestmt/ifelsestmt06.ql b/cpp/ql/test/successor-tests/ifstmt/ifelsestmt/ifelsestmt06.ql index fc6ae7d3bc8..31f213558f0 100644 --- a/cpp/ql/test/successor-tests/ifstmt/ifelsestmt/ifelsestmt06.ql +++ b/cpp/ql/test/successor-tests/ifstmt/ifelsestmt/ifelsestmt06.ql @@ -10,7 +10,7 @@ where is.getEnclosingFunction().hasName("normal") and is.getParentStmt().hasChild(is, k) and is.getParentStmt().hasChild(l3, k + 1) and - last = is.getElse().(Block).getLastStmt() and + last = is.getElse().(BlockStmt).getLastStmt() and l3 = last.getASuccessor() and count(last.getASuccessor()) = 1 select last, l3.getName() diff --git a/cpp/ql/test/successor-tests/ifstmt/ifstmt/ifstmt02.ql b/cpp/ql/test/successor-tests/ifstmt/ifstmt/ifstmt02.ql index 90cfc707daa..d3dc2521aa7 100644 --- a/cpp/ql/test/successor-tests/ifstmt/ifstmt/ifstmt02.ql +++ b/cpp/ql/test/successor-tests/ifstmt/ifstmt/ifstmt02.ql @@ -5,7 +5,7 @@ import cpp -from IfStmt is, Block t +from IfStmt is, BlockStmt t where is.getEnclosingFunction().hasName("normal") and t = is.getThen() and diff --git a/cpp/ql/test/successor-tests/ifstmt/ifstmt/ifstmt04.ql b/cpp/ql/test/successor-tests/ifstmt/ifstmt/ifstmt04.ql index f203b5f0ea2..7051192159c 100644 --- a/cpp/ql/test/successor-tests/ifstmt/ifstmt/ifstmt04.ql +++ b/cpp/ql/test/successor-tests/ifstmt/ifstmt/ifstmt04.ql @@ -10,7 +10,7 @@ where is.getEnclosingFunction().hasName("normal") and is.getParentStmt().hasChild(is, k) and is.getParentStmt().hasChild(l2, k + 1) and - last = is.getThen().(Block).getLastStmt() and + last = is.getThen().(BlockStmt).getLastStmt() and l2 = last.getASuccessor() and count(last.getASuccessor()) = 1 select last, l2.getName() diff --git a/cpp/ql/test/successor-tests/whilestmt/whilestmt04.ql b/cpp/ql/test/successor-tests/whilestmt/whilestmt04.ql index 1ae9f4931a5..1e7c43de993 100644 --- a/cpp/ql/test/successor-tests/whilestmt/whilestmt04.ql +++ b/cpp/ql/test/successor-tests/whilestmt/whilestmt04.ql @@ -8,7 +8,7 @@ import cpp from WhileStmt ws, ExprStmt last, Expr succ where ws.getEnclosingFunction().hasName("normal") and - last = ws.getStmt().(Block).getLastStmt() and + last = ws.getStmt().(BlockStmt).getLastStmt() and succ = last.getExpr().getASuccessor() and succ = ws.getCondition().getAChild*() and count(last.getExpr().getASuccessor()) = 1 diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/BuildAnalysis.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/BuildAnalysis.cs index 2894222ca89..a5038148249 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/BuildAnalysis.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/BuildAnalysis.cs @@ -88,7 +88,7 @@ namespace Semmle.BuildAnalyser nuget = new NugetPackages(sourceDir.FullName, PackageDirectory); ReadNugetFiles(); } - catch(FileNotFoundException) + catch (FileNotFoundException) { progressMonitor.MissingNuGet(); } @@ -97,7 +97,9 @@ namespace Semmle.BuildAnalyser // Find DLLs in the .Net Framework if (options.ScanNetFrameworkDlls) { - dllDirNames.Add(Runtime.Runtimes.First()); + var runtimeLocation = Runtime.GetRuntime(options.UseSelfContainedDotnet); + progressMonitor.Log(Util.Logging.Severity.Debug, $"Runtime location selected: {runtimeLocation}"); + dllDirNames.Add(runtimeLocation); } // These files can sometimes prevent `dotnet restore` from working correctly. @@ -279,7 +281,7 @@ namespace Semmle.BuildAnalyser void AnalyseProject(FileInfo project) { - if(!project.Exists) + if (!project.Exists) { progressMonitor.MissingProject(project.FullName); return; @@ -323,7 +325,7 @@ namespace Semmle.BuildAnalyser void Restore(string projectOrSolution) { int exit = DotNet.RestoreToDirectory(projectOrSolution, PackageDirectory.DirInfo.FullName); - switch(exit) + switch (exit) { case 0: case 1: @@ -342,7 +344,7 @@ namespace Semmle.BuildAnalyser public void AnalyseSolutions(IEnumerable solutions) { - Parallel.ForEach(solutions, new ParallelOptions { MaxDegreeOfParallelism = 4 } , solutionFile => + Parallel.ForEach(solutions, new ParallelOptions { MaxDegreeOfParallelism = 4 }, solutionFile => { try { diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Options.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Options.cs index 89cc18007f0..d20f3d8195a 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Options.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Options.cs @@ -13,7 +13,7 @@ namespace Semmle.Extraction.CSharp.Standalone { public override bool handleFlag(string key, bool value) { - switch(key) + switch (key) { case "silent": Verbosity = value ? Verbosity.Off : Verbosity.Info; @@ -36,6 +36,9 @@ namespace Semmle.Extraction.CSharp.Standalone case "skip-dotnet": ScanNetFrameworkDlls = !value; return true; + case "self-contained-dotnet": + UseSelfContainedDotnet = value; + return true; default: return base.handleFlag(key, value); } @@ -43,7 +46,7 @@ namespace Semmle.Extraction.CSharp.Standalone public override bool handleOption(string key, string value) { - switch(key) + switch (key) { case "exclude": Excludes.Add(value); @@ -134,6 +137,11 @@ namespace Semmle.Extraction.CSharp.Standalone /// public bool Help = false; + /// + /// Whether to use the packaged dotnet runtime. + /// + public bool UseSelfContainedDotnet = false; + /// /// Determine whether the given path should be excluded. /// @@ -162,6 +170,7 @@ namespace Semmle.Extraction.CSharp.Standalone output.WriteLine(" --threads:nnn Specify number of threads (default=CPU cores)"); output.WriteLine(" --verbose Produce more output"); output.WriteLine(" --pdb Cross-reference information from PDBs where available"); + output.WriteLine(" --self-contained-dotnet Use the .Net Framework packaged with the extractor"); } private Options() diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/ProgressMonitor.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/ProgressMonitor.cs index 5bbe1e3a5b2..4405a3dde76 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/ProgressMonitor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/ProgressMonitor.cs @@ -16,7 +16,7 @@ namespace Semmle.BuildAnalyser void NugetInstall(string package); void ResolvedReference(string filename); void Summary(int existingSources, int usedSources, int missingSources, int references, int unresolvedReferences, int resolvedConflicts, int totalProjects, int failedProjects, TimeSpan analysisTime); - void Warning(string message); + void Log(Severity severity, string message); void ResolvedConflict(string asm1, string asm2); void MissingProject(string projectFile); void CommandFailed(string exe, string arguments, int exitCode); @@ -93,9 +93,9 @@ namespace Semmle.BuildAnalyser logger.Log(Severity.Info, "Build analysis completed in {0}", analysisTime); } - public void Warning(string message) + public void Log(Severity severity, string message) { - logger.Log(Severity.Warning, message); + logger.Log(severity, message); } public void ResolvedConflict(string asm1, string asm2) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Runtime.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Runtime.cs index 489d7f95140..6d7aabf9ec4 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Runtime.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Runtime.cs @@ -17,7 +17,7 @@ namespace Semmle.Extraction.CSharp.Standalone /// /// Locates .NET Core Runtimes. /// - public static IEnumerable CoreRuntimes + private static IEnumerable CoreRuntimes { get { @@ -37,7 +37,7 @@ namespace Semmle.Extraction.CSharp.Standalone /// Locates .NET Desktop Runtimes. /// This includes Mono and Microsoft.NET. /// - public static IEnumerable DesktopRuntimes + private static IEnumerable DesktopRuntimes { get { @@ -63,7 +63,12 @@ namespace Semmle.Extraction.CSharp.Standalone } } - public static IEnumerable Runtimes + /// + /// Gets the .NET runtime location to use for extraction + /// + public static string GetRuntime(bool useSelfContained) => useSelfContained ? ExecutingRuntime : Runtimes.First(); + + private static IEnumerable Runtimes { get { diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll index 228b064dc01..820975809f8 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll @@ -14,10 +14,10 @@ private import semmle.code.csharp.frameworks.JsonNET private import semmle.code.csharp.frameworks.WCF /** - * Holds if `node` should be a barrier in all global taint flow configurations + * Holds if `node` should be a sanitizer in all global taint flow configurations * but not in local taint. */ -predicate defaultTaintBarrier(DataFlow::Node node) { none() } +predicate defaultTaintSanitizer(DataFlow::Node node) { none() } deprecated predicate localAdditionalTaintStep = defaultAdditionalTaintStep/2; diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll index af0d0fec53a..b509fad9cd2 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration { final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) or - defaultTaintBarrier(node) + defaultTaintSanitizer(node) } - /** Holds if data flow into `node` is prohibited. */ + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) } - /** Holds if data flow out of `node` is prohibited. */ + /** Holds if taint propagation out of `node` is prohibited. */ predicate isSanitizerOut(DataFlow::Node node) { none() } final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) } - /** Holds if data flow through nodes guarded by `guard` is prohibited. */ + /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */ predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() } final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll index af0d0fec53a..b509fad9cd2 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration { final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) or - defaultTaintBarrier(node) + defaultTaintSanitizer(node) } - /** Holds if data flow into `node` is prohibited. */ + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) } - /** Holds if data flow out of `node` is prohibited. */ + /** Holds if taint propagation out of `node` is prohibited. */ predicate isSanitizerOut(DataFlow::Node node) { none() } final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) } - /** Holds if data flow through nodes guarded by `guard` is prohibited. */ + /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */ predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() } final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll index af0d0fec53a..b509fad9cd2 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll @@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration { final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) or - defaultTaintBarrier(node) + defaultTaintSanitizer(node) } - /** Holds if data flow into `node` is prohibited. */ + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) } - /** Holds if data flow out of `node` is prohibited. */ + /** Holds if taint propagation out of `node` is prohibited. */ predicate isSanitizerOut(DataFlow::Node node) { none() } final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) } - /** Holds if data flow through nodes guarded by `guard` is prohibited. */ + /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */ predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() } final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll index af0d0fec53a..b509fad9cd2 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll @@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration { final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) or - defaultTaintBarrier(node) + defaultTaintSanitizer(node) } - /** Holds if data flow into `node` is prohibited. */ + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) } - /** Holds if data flow out of `node` is prohibited. */ + /** Holds if taint propagation out of `node` is prohibited. */ predicate isSanitizerOut(DataFlow::Node node) { none() } final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) } - /** Holds if data flow through nodes guarded by `guard` is prohibited. */ + /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */ predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() } final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll index af0d0fec53a..b509fad9cd2 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll @@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration { final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) or - defaultTaintBarrier(node) + defaultTaintSanitizer(node) } - /** Holds if data flow into `node` is prohibited. */ + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) } - /** Holds if data flow out of `node` is prohibited. */ + /** Holds if taint propagation out of `node` is prohibited. */ predicate isSanitizerOut(DataFlow::Node node) { none() } final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) } - /** Holds if data flow through nodes guarded by `guard` is prohibited. */ + /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */ predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() } final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) } diff --git a/java/ql/examples/snippets/emptyblock.ql b/java/ql/examples/snippets/emptyblock.ql index 3bba6eda938..72efe38865b 100644 --- a/java/ql/examples/snippets/emptyblock.ql +++ b/java/ql/examples/snippets/emptyblock.ql @@ -9,6 +9,6 @@ import java -from Block blk +from BlockStmt blk where blk.getNumStmt() = 0 select blk diff --git a/java/ql/examples/snippets/emptythen.ql b/java/ql/examples/snippets/emptythen.ql index c3bc44b1215..cf87cbf54f6 100644 --- a/java/ql/examples/snippets/emptythen.ql +++ b/java/ql/examples/snippets/emptythen.ql @@ -13,5 +13,5 @@ import java from IfStmt i -where i.getThen().(Block).getNumStmt() = 0 +where i.getThen().(BlockStmt).getNumStmt() = 0 select i diff --git a/java/ql/examples/snippets/singletonblock.ql b/java/ql/examples/snippets/singletonblock.ql index 1096711e462..65cff1d152b 100644 --- a/java/ql/examples/snippets/singletonblock.ql +++ b/java/ql/examples/snippets/singletonblock.ql @@ -8,6 +8,6 @@ import java -from Block b +from BlockStmt b where b.getNumStmt() = 1 select b diff --git a/java/ql/src/Advisory/Statements/OneStatementPerLine.ql b/java/ql/src/Advisory/Statements/OneStatementPerLine.ql index da8d7e3275a..99ab9003e60 100644 --- a/java/ql/src/Advisory/Statements/OneStatementPerLine.ql +++ b/java/ql/src/Advisory/Statements/OneStatementPerLine.ql @@ -27,7 +27,7 @@ predicate oneLineStatement(Stmt s, File f, int line, int col) { col = l.getStartColumn() ) and // Exclude blocks: `{break;}` is not really a violation. - not s instanceof Block and + not s instanceof BlockStmt and // Exclude implicit super constructor invocations. not s instanceof SuperConstructorInvocationStmt and // Java enums are desugared to a whole bunch of generated statements. diff --git a/java/ql/src/Complexity/BlockWithTooManyStatements.ql b/java/ql/src/Complexity/BlockWithTooManyStatements.ql index f1bdce1f0ab..c47d96f6a2d 100644 --- a/java/ql/src/Complexity/BlockWithTooManyStatements.ql +++ b/java/ql/src/Complexity/BlockWithTooManyStatements.ql @@ -20,6 +20,6 @@ class ComplexStmt extends Stmt { } } -from Block b, int n +from BlockStmt b, int n where n = count(ComplexStmt s | s = b.getAStmt()) and n > 3 select b, "Block with too many statements (" + n.toString() + " complex statements in the block)." diff --git a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UnusedBean.ql b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UnusedBean.ql index de3761e6175..79a8427cc50 100644 --- a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UnusedBean.ql +++ b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UnusedBean.ql @@ -51,9 +51,9 @@ class ImpureStmt extends Stmt { /** * Get any non-block stmt in the block, including those nested within blocks. */ -private Stmt getANestedStmt(Block block) { +private Stmt getANestedStmt(BlockStmt block) { // Any non-block statement - not result instanceof Block and result = block.getAStmt() + not result instanceof BlockStmt and result = block.getAStmt() or // Or any statement nested in a block result = getANestedStmt(block.getAStmt()) diff --git a/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql b/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql index eacba3ad4ec..25dec899af1 100644 --- a/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql +++ b/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql @@ -42,7 +42,7 @@ predicate hasTypeTest(Variable v) { */ class ReferenceEquals extends EqualsMethod { ReferenceEquals() { - exists(Block b, ReturnStmt ret, EQExpr eq | + exists(BlockStmt b, ReturnStmt ret, EQExpr eq | this.getBody() = b and b.getStmt(0) = ret and ret.getResult() = eq and diff --git a/java/ql/src/Likely Bugs/Statements/EmptyBlock.ql b/java/ql/src/Likely Bugs/Statements/EmptyBlock.ql index 993f808e252..4dd2c397a87 100644 --- a/java/ql/src/Likely Bugs/Statements/EmptyBlock.ql +++ b/java/ql/src/Likely Bugs/Statements/EmptyBlock.ql @@ -13,7 +13,7 @@ import semmle.code.java.Statement /** A block without statements or comments. */ -private Block emptyBlock() { +private BlockStmt emptyBlock() { result.getNumStmt() = 0 and result.getLocation().getNumberOfCommentLines() = 0 } @@ -48,8 +48,8 @@ predicate blockParent(Stmt empty, string msg) { or empty.getParent() instanceof LoopStmt and msg = "The body of a loop should not be empty." or - empty.getParent() instanceof Block and - empty instanceof Block and + empty.getParent() instanceof BlockStmt and + empty instanceof BlockStmt and msg = "This block should not be empty." ) } diff --git a/java/ql/src/Likely Bugs/Statements/UseBraces.ql b/java/ql/src/Likely Bugs/Statements/UseBraces.ql index a9900556ccf..1d844cfe913 100644 --- a/java/ql/src/Likely Bugs/Statements/UseBraces.ql +++ b/java/ql/src/Likely Bugs/Statements/UseBraces.ql @@ -15,11 +15,11 @@ import java /** * A control structure for which the trailing body (the syntactically last part) - * is not a `Block`. This is either an `IfStmt` or a `LoopStmt`, but not a + * is not a `BlockStmt`. This is either an `IfStmt` or a `LoopStmt`, but not a * `DoStmt`, since do-while statements don't have a trailing body. */ predicate unbracedTrailingBody(Stmt ctrlStructure, Stmt trailingBody) { - not trailingBody instanceof Block and + not trailingBody instanceof BlockStmt and ( exists(IfStmt c | c = ctrlStructure | trailingBody = c.getElse() and not trailingBody instanceof IfStmt @@ -33,15 +33,15 @@ predicate unbracedTrailingBody(Stmt ctrlStructure, Stmt trailingBody) { /* * The body of a `SwitchStmt` is a block, but it isn't represented explicitly - * in the AST as a `Block`, so we have to take it into account directly in the + * in the AST as a `BlockStmt`, so we have to take it into account directly in the * following two predicates. */ /** - * Two consecutive statements in a `Block` statement or `SwitchStmt`. + * Two consecutive statements in a `BlockStmt` statement or `SwitchStmt`. */ Stmt nextInBlock(Stmt s) { - exists(Block b, int i | + exists(BlockStmt b, int i | b.getStmt(i) = s and b.getStmt(i + 1) = result ) @@ -52,10 +52,10 @@ Stmt nextInBlock(Stmt s) { ) } -/** The `Stmt.getParent()` relation restricted to not pass through `Block`s or `SwitchStmt`s. */ +/** The `Stmt.getParent()` relation restricted to not pass through `BlockStmt`s or `SwitchStmt`s. */ Stmt nonBlockParent(Stmt s) { result = s.getParent() and - not result instanceof Block and + not result instanceof BlockStmt and not result instanceof SwitchStmt } @@ -64,7 +64,7 @@ predicate ifElseIf(IfStmt s, IfStmt elseif) { s.getElse() = elseif } /** * The statement `body` is an unbraced trailing body of a control structure and - * `succ` is the next statement in the surrounding `Block` (or `SwitchStmt`). + * `succ` is the next statement in the surrounding `BlockStmt` (or `SwitchStmt`). */ predicate shouldOutdent( Stmt ctrl, Stmt body, Stmt succ, int bodycol, int succcol, int bodyline, int succline @@ -79,7 +79,7 @@ predicate shouldOutdent( /** * The statement `body` is an unbraced trailing body of a control structure and - * `succ` is the next statement in the surrounding `Block` (or `SwitchStmt`). + * `succ` is the next statement in the surrounding `BlockStmt` (or `SwitchStmt`). * The indentation of statement `succ` is suspect because it is indented * the same way as `body` and thus visually suggests to be part of the same * syntactic scope as `body`. diff --git a/java/ql/src/Likely Bugs/Termination/SpinOnField.ql b/java/ql/src/Likely Bugs/Termination/SpinOnField.ql index a32f237234c..b5fd248a535 100644 --- a/java/ql/src/Likely Bugs/Termination/SpinOnField.ql +++ b/java/ql/src/Likely Bugs/Termination/SpinOnField.ql @@ -25,7 +25,7 @@ class ComparisonOrEqTestExpr extends Expr { class Empty extends Stmt { Empty() { this instanceof EmptyStmt or - this.(Block).getNumStmt() = 0 + this.(BlockStmt).getNumStmt() = 0 } } diff --git a/java/ql/src/Metrics/Callables/StatementNestingDepth.ql b/java/ql/src/Metrics/Callables/StatementNestingDepth.ql index 441395cb678..4dfb0f8f64c 100644 --- a/java/ql/src/Metrics/Callables/StatementNestingDepth.ql +++ b/java/ql/src/Metrics/Callables/StatementNestingDepth.ql @@ -26,7 +26,7 @@ predicate skipParent(Stmt s) { exists(Stmt parent | parent = s.getParent() | s instanceof IfStmt and parent.(IfStmt).getElse() = s or - parent instanceof Block + parent instanceof BlockStmt ) } diff --git a/java/ql/src/Security/CWE/CWE-089/SqlInjectionLib.qll b/java/ql/src/Security/CWE/CWE-089/SqlInjectionLib.qll index 71b0133bdd5..febee9bcef9 100644 --- a/java/ql/src/Security/CWE/CWE-089/SqlInjectionLib.qll +++ b/java/ql/src/Security/CWE/CWE-089/SqlInjectionLib.qll @@ -4,22 +4,6 @@ import java import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.QueryInjection -/** A sink for MongoDB injection vulnerabilities. */ -class MongoDbInjectionSink extends QueryInjectionSink { - MongoDbInjectionSink() { - exists(MethodAccess call | - call.getMethod().getDeclaringType().hasQualifiedName("com.mongodb", "BasicDBObject") and - call.getMethod().hasName("parse") and - this.asExpr() = call.getArgument(0) - ) - or - exists(CastExpr c | - c.getExpr() = this.asExpr() and - c.getTypeExpr().getType().(RefType).hasQualifiedName("com.mongodb", "DBObject") - ) - } -} - private class QueryInjectionFlowConfig extends TaintTracking::Configuration { QueryInjectionFlowConfig() { this = "SqlInjectionLib::QueryInjectionFlowConfig" } @@ -34,7 +18,7 @@ private class QueryInjectionFlowConfig extends TaintTracking::Configuration { } override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - mongoJsonStep(node1, node2) + any(AdditionalQueryInjectionTaintStep s).step(node1, node2) } } @@ -47,12 +31,3 @@ predicate queryTaintedBy( ) { exists(QueryInjectionFlowConfig conf | conf.hasFlowPath(source, sink) and sink.getNode() = query) } - -predicate mongoJsonStep(DataFlow::Node node1, DataFlow::Node node2) { - exists(MethodAccess ma | - ma.getMethod().getDeclaringType().hasQualifiedName("com.mongodb.util", "JSON") and - ma.getMethod().hasName("parse") and - ma.getArgument(0) = node1.asExpr() and - ma = node2.asExpr() - ) -} diff --git a/java/ql/src/Security/CWE/CWE-089/SqlTaintedLocal.ql b/java/ql/src/Security/CWE/CWE-089/SqlTaintedLocal.ql index c27c69be25d..34930c5ce59 100644 --- a/java/ql/src/Security/CWE/CWE-089/SqlTaintedLocal.ql +++ b/java/ql/src/Security/CWE/CWE-089/SqlTaintedLocal.ql @@ -27,7 +27,7 @@ class LocalUserInputToQueryInjectionFlowConfig extends TaintTracking::Configurat } override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - mongoJsonStep(node1, node2) + any(AdditionalQueryInjectionTaintStep s).step(node1, node2) } } diff --git a/java/ql/src/Security/CWE/CWE-129/ArraySizing.qll b/java/ql/src/Security/CWE/CWE-129/ArraySizing.qll index 59db7d4f87f..65fb6681412 100644 --- a/java/ql/src/Security/CWE/CWE-129/ArraySizing.qll +++ b/java/ql/src/Security/CWE/CWE-129/ArraySizing.qll @@ -44,7 +44,7 @@ class PointlessLoop extends WhileStmt { getCondition().(BooleanLiteral).getBooleanValue() = true and // The only `break` must be the last statement. forall(BreakStmt break | break.(JumpStmt).getTarget() = this | - this.getStmt().(Block).getLastStmt() = break + this.getStmt().(BlockStmt).getLastStmt() = break ) and // No `continue` statements. not exists(ContinueStmt continue | continue.(JumpStmt).getTarget() = this) diff --git a/java/ql/src/Violations of Best Practice/Dead Code/EmptyFinalize.ql b/java/ql/src/Violations of Best Practice/Dead Code/EmptyFinalize.ql index 42018f9d4ef..5e972af78f8 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/EmptyFinalize.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/EmptyFinalize.ql @@ -16,5 +16,5 @@ import java from FinalizeMethod finalize where finalize.fromSource() and - not exists(Stmt s | s.getEnclosingCallable() = finalize | not s instanceof Block) + not exists(Stmt s | s.getEnclosingCallable() = finalize | not s instanceof BlockStmt) select finalize, "Empty finalize method." diff --git a/java/ql/src/Violations of Best Practice/legacy/FinallyMayNotComplete.ql b/java/ql/src/Violations of Best Practice/legacy/FinallyMayNotComplete.ql index bf2e0a0a7ac..3051debd5f5 100644 --- a/java/ql/src/Violations of Best Practice/legacy/FinallyMayNotComplete.ql +++ b/java/ql/src/Violations of Best Practice/legacy/FinallyMayNotComplete.ql @@ -14,14 +14,14 @@ import java -Block finallyBlock() { exists(TryStmt try | try.getFinally() = result) } +BlockStmt finallyBlock() { exists(TryStmt try | try.getFinally() = result) } -Stmt statementIn(Block finally) { +Stmt statementIn(BlockStmt finally) { finallyBlock() = finally and result.getParent+() = finally } -predicate banned(Stmt s, Block finally) { +predicate banned(Stmt s, BlockStmt finally) { s = statementIn(finally) and ( s instanceof ReturnStmt @@ -32,6 +32,6 @@ predicate banned(Stmt s, Block finally) { ) } -from Stmt s, Block finally +from Stmt s, BlockStmt finally where banned(s, finally) select s, "Leaving a finally-block with this statement can cause exceptions to silently disappear." diff --git a/java/ql/src/external/CodeDuplication.qll b/java/ql/src/external/CodeDuplication.qll index fb96e996046..98782463a0e 100644 --- a/java/ql/src/external/CodeDuplication.qll +++ b/java/ql/src/external/CodeDuplication.qll @@ -77,7 +77,7 @@ private predicate blockCoversStatement(int equivClass, int first, int last, Stmt private Stmt statementInMethod(Method m) { result.getEnclosingCallable() = m and - not result instanceof Block + not result instanceof BlockStmt } private predicate duplicateStatement(Method m1, Method m2, Stmt s1, Stmt s2) { diff --git a/java/ql/src/java.qll b/java/ql/src/java.qll index 6454a0d282b..9c52e1696ad 100644 --- a/java/ql/src/java.qll +++ b/java/ql/src/java.qll @@ -3,6 +3,7 @@ import Customizations import semmle.code.FileSystem import semmle.code.Location +import semmle.code.Unit import semmle.code.java.Annotation import semmle.code.java.CompilationUnit import semmle.code.java.ControlFlowGraph diff --git a/java/ql/src/semmle/code/Unit.qll b/java/ql/src/semmle/code/Unit.qll new file mode 100644 index 00000000000..e9611ed3df4 --- /dev/null +++ b/java/ql/src/semmle/code/Unit.qll @@ -0,0 +1,10 @@ +/** Provides the `Unit` class. */ + +/** The unit type. */ +private newtype TUnit = TMkUnit() + +/** The trivial type with a single element. */ +class Unit extends TUnit { + /** Gets a textual representation of this element. */ + string toString() { result = "unit" } +} diff --git a/java/ql/src/semmle/code/java/ControlFlowGraph.qll b/java/ql/src/semmle/code/java/ControlFlowGraph.qll index f482398a74f..016f2bd6874 100644 --- a/java/ql/src/semmle/code/java/ControlFlowGraph.qll +++ b/java/ql/src/semmle/code/java/ControlFlowGraph.qll @@ -338,7 +338,7 @@ private module ControlFlowGraphImpl { /** Holds if a call to `m` indicates that `m` is expected to return. */ private predicate expectedReturn(EffectivelyNonVirtualMethod m) { - exists(Stmt s, Block b | + exists(Stmt s, BlockStmt b | m.getAnAccess().getEnclosingStmt() = s and b.getAStmt() = s and not b.getLastStmt() = s @@ -352,7 +352,7 @@ private module ControlFlowGraphImpl { result instanceof MethodExit or not result.isOverridable() and - exists(Block body | + exists(BlockStmt body | body = result.getBody() and not exists(ReturnStmt ret | ret.getEnclosingCallable() = result) | @@ -388,7 +388,7 @@ private module ControlFlowGraphImpl { or result.(ExprStmt).getExpr() = nonReturningMethodAccess() or - result.(Block).getLastStmt() = nonReturningStmt() + result.(BlockStmt).getLastStmt() = nonReturningStmt() or exists(IfStmt ifstmt | ifstmt = result | ifstmt.getThen() = nonReturningStmt() and @@ -450,7 +450,7 @@ private module ControlFlowGraphImpl { or this instanceof SuperAccess or - this.(Block).getNumStmt() = 0 + this.(BlockStmt).getNumStmt() = 0 or this instanceof SwitchCase and not this.(SwitchCase).isRule() or @@ -723,7 +723,7 @@ private module ControlFlowGraphImpl { or // The last statement in a block is any statement that does not complete normally, // or the last statement. - exists(Block blk | blk = n | + exists(BlockStmt blk | blk = n | last(blk.getAStmt(), last, completion) and completion != NormalCompletion() or last(blk.getStmt(blk.getNumStmt() - 1), last, completion) @@ -943,9 +943,9 @@ private module ControlFlowGraphImpl { ) or // Statements within a block execute sequentially. - result = first(n.(Block).getStmt(0)) and completion = NormalCompletion() + result = first(n.(BlockStmt).getStmt(0)) and completion = NormalCompletion() or - exists(Block blk, int i | + exists(BlockStmt blk, int i | last(blk.getStmt(i), n, completion) and completion = NormalCompletion() and result = first(blk.getStmt(i + 1)) diff --git a/java/ql/src/semmle/code/java/Expr.qll b/java/ql/src/semmle/code/java/Expr.qll index cb3fcae1873..070cb45783c 100755 --- a/java/ql/src/semmle/code/java/Expr.qll +++ b/java/ql/src/semmle/code/java/Expr.qll @@ -1022,7 +1022,7 @@ class LambdaExpr extends FunctionalExpr, @lambdaexpr { } /** Gets the body of this lambda expression, if it is a statement. */ - Block getStmtBody() { hasStmtBody() and result = asMethod().getBody() } + BlockStmt getStmtBody() { hasStmtBody() and result = asMethod().getBody() } /** Gets a printable representation of this expression. */ override string toString() { result = "...->..." } diff --git a/java/ql/src/semmle/code/java/Member.qll b/java/ql/src/semmle/code/java/Member.qll index 766c334bbf6..a5fa37b7e1f 100755 --- a/java/ql/src/semmle/code/java/Member.qll +++ b/java/ql/src/semmle/code/java/Member.qll @@ -215,7 +215,7 @@ class Callable extends StmtParent, Member, @callable { Call getAReference() { result.getCallee() = this } /** Gets the body of this callable, if any. */ - Block getBody() { result.getParent() = this } + BlockStmt getBody() { result.getParent() = this } /** * Gets the source declaration of this callable. diff --git a/java/ql/src/semmle/code/java/PrintAst.qll b/java/ql/src/semmle/code/java/PrintAst.qll index 0a22ab13f29..770cac13ec1 100644 --- a/java/ql/src/semmle/code/java/PrintAst.qll +++ b/java/ql/src/semmle/code/java/PrintAst.qll @@ -469,7 +469,7 @@ private class PpWildcardTypeAccess extends PpAst, WildcardTypeAccess { * Statements */ -private class PpBlock extends PpAst, Block { +private class PpBlock extends PpAst, BlockStmt { override string getPart(int i) { i = 0 and result = "{" or @@ -493,26 +493,26 @@ private class PpIfStmt extends PpAst, IfStmt { or i = 2 and result = ")" or - i = 3 and result = " " and this.getThen() instanceof Block + i = 3 and result = " " and this.getThen() instanceof BlockStmt or exists(this.getElse()) and ( - i = 5 and result = " " and this.getThen() instanceof Block + i = 5 and result = " " and this.getThen() instanceof BlockStmt or i = 6 and result = "else" or - i = 7 and result = " " and this.getElse() instanceof Block + i = 7 and result = " " and this.getElse() instanceof BlockStmt ) } override predicate newline(int i) { - i = 3 and not this.getThen() instanceof Block + i = 3 and not this.getThen() instanceof BlockStmt or exists(this.getElse()) and ( - i = 5 and not this.getThen() instanceof Block + i = 5 and not this.getThen() instanceof BlockStmt or - i = 7 and not this.getElse() instanceof Block + i = 7 and not this.getElse() instanceof BlockStmt ) } @@ -525,9 +525,9 @@ private class PpIfStmt extends PpAst, IfStmt { } override predicate indents(int i) { - i = 4 and not this.getThen() instanceof Block + i = 4 and not this.getThen() instanceof BlockStmt or - i = 8 and not this.getElse() instanceof Block + i = 8 and not this.getElse() instanceof BlockStmt } } @@ -549,7 +549,7 @@ private class PpForStmt extends PpAst, ForStmt { or i = 1 + lastUpdateIndex() and result = ")" or - i = 2 + lastUpdateIndex() and result = " " and this.getStmt() instanceof Block + i = 2 + lastUpdateIndex() and result = " " and this.getStmt() instanceof BlockStmt } private int lastInitIndex() { result = 3 + 2 * max(int j | exists(this.getInit(j))) } @@ -559,7 +559,7 @@ private class PpForStmt extends PpAst, ForStmt { } override predicate newline(int i) { - i = 2 + lastUpdateIndex() and not this.getStmt() instanceof Block + i = 2 + lastUpdateIndex() and not this.getStmt() instanceof BlockStmt } override PpAst getChild(int i) { @@ -575,7 +575,7 @@ private class PpForStmt extends PpAst, ForStmt { } override predicate indents(int i) { - i = 3 + lastUpdateIndex() and not this.getStmt() instanceof Block + i = 3 + lastUpdateIndex() and not this.getStmt() instanceof BlockStmt } } @@ -588,7 +588,7 @@ private class PpEnhancedForStmt extends PpAst, EnhancedForStmt { i = 4 and result = " : " or i = 6 and - if this.getStmt() instanceof Block then result = ") " else result = ")" + if this.getStmt() instanceof BlockStmt then result = ") " else result = ")" } override PpAst getChild(int i) { @@ -601,7 +601,7 @@ private class PpEnhancedForStmt extends PpAst, EnhancedForStmt { i = 7 and result = this.getStmt() } - override predicate indents(int i) { i = 7 and not this.getStmt() instanceof Block } + override predicate indents(int i) { i = 7 and not this.getStmt() instanceof BlockStmt } } private class PpWhileStmt extends PpAst, WhileStmt { @@ -610,10 +610,10 @@ private class PpWhileStmt extends PpAst, WhileStmt { or i = 2 and result = ")" or - i = 3 and result = " " and this.getStmt() instanceof Block + i = 3 and result = " " and this.getStmt() instanceof BlockStmt } - override predicate newline(int i) { i = 3 and not this.getStmt() instanceof Block } + override predicate newline(int i) { i = 3 and not this.getStmt() instanceof BlockStmt } override PpAst getChild(int i) { i = 1 and result = this.getCondition() @@ -621,21 +621,21 @@ private class PpWhileStmt extends PpAst, WhileStmt { i = 4 and result = this.getStmt() } - override predicate indents(int i) { i = 4 and not this.getStmt() instanceof Block } + override predicate indents(int i) { i = 4 and not this.getStmt() instanceof BlockStmt } } private class PpDoStmt extends PpAst, DoStmt { override string getPart(int i) { i = 0 and result = "do" or - i in [1, 3] and result = " " and this.getStmt() instanceof Block + i in [1, 3] and result = " " and this.getStmt() instanceof BlockStmt or i = 4 and result = "while (" or i = 6 and result = ");" } - override predicate newline(int i) { i in [1, 3] and not this.getStmt() instanceof Block } + override predicate newline(int i) { i in [1, 3] and not this.getStmt() instanceof BlockStmt } override PpAst getChild(int i) { i = 2 and result = this.getStmt() @@ -643,7 +643,7 @@ private class PpDoStmt extends PpAst, DoStmt { i = 5 and result = this.getCondition() } - override predicate indents(int i) { i = 2 and not this.getStmt() instanceof Block } + override predicate indents(int i) { i = 2 and not this.getStmt() instanceof BlockStmt } } private class PpTryStmt extends PpAst, TryStmt { diff --git a/java/ql/src/semmle/code/java/Statement.qll b/java/ql/src/semmle/code/java/Statement.qll index bfde273e2cb..fbc86440788 100755 --- a/java/ql/src/semmle/code/java/Statement.qll +++ b/java/ql/src/semmle/code/java/Statement.qll @@ -60,7 +60,7 @@ class Stmt extends StmtParent, ExprParent, @stmt { class StmtParent extends @stmtparent, Top { } /** A block of statements. */ -class Block extends Stmt, @block { +class BlockStmt extends Stmt, @block { /** Gets a statement that is an immediate child of this block. */ Stmt getAStmt() { result.getParent() = this } @@ -77,11 +77,17 @@ class Block extends Stmt, @block { override string pp() { result = "{ ... }" } /** This statement's Halstead ID (used to compute Halstead metrics). */ - override string getHalsteadID() { result = "Block" } + override string getHalsteadID() { result = "BlockStmt" } } +/** + * DEPRECATED: This is now called `BlockStmt` to avoid confusion with + * `BasicBlock`. + */ +deprecated class Block = BlockStmt; + /** A block with only a single statement. */ -class SingletonBlock extends Block { +class SingletonBlock extends BlockStmt { SingletonBlock() { this.getNumStmt() = 1 } /** Gets the single statement in this block. */ @@ -304,7 +310,7 @@ class TryStmt extends Stmt, @trystmt { } /** Gets the `finally` block, if any. */ - Block getFinally() { result.isNthChildOf(this, -2) } + BlockStmt getFinally() { result.isNthChildOf(this, -2) } /** Gets a resource variable declaration, if any. */ LocalVariableDeclStmt getAResourceDecl() { result.getParent() = this and result.getIndex() <= -3 } @@ -348,7 +354,7 @@ class TryStmt extends Stmt, @trystmt { /** A `catch` clause in a `try` statement. */ class CatchClause extends Stmt, @catchclause { /** Gets the block of this `catch` clause. */ - Block getBlock() { result.getParent() = this } + BlockStmt getBlock() { result.getParent() = this } /** Gets the `try` statement in which this `catch` clause occurs. */ TryStmt getTry() { this = result.getACatchClause() } diff --git a/java/ql/src/semmle/code/java/controlflow/Dominance.qll b/java/ql/src/semmle/code/java/controlflow/Dominance.qll index 89f65b5684a..cbc16022d25 100644 --- a/java/ql/src/semmle/code/java/controlflow/Dominance.qll +++ b/java/ql/src/semmle/code/java/controlflow/Dominance.qll @@ -14,7 +14,7 @@ private predicate flowEntry(Stmt entry) { exists(Callable c | entry = c.getBody()) or // This disjunct is technically superfluous, but safeguards against extractor problems. - entry instanceof Block and + entry instanceof BlockStmt and not exists(entry.getEnclosingCallable()) and not entry.getParent() instanceof Stmt } diff --git a/java/ql/src/semmle/code/java/dataflow/Nullness.qll b/java/ql/src/semmle/code/java/dataflow/Nullness.qll index 56433cb009f..5e90693b0f1 100644 --- a/java/ql/src/semmle/code/java/dataflow/Nullness.qll +++ b/java/ql/src/semmle/code/java/dataflow/Nullness.qll @@ -293,7 +293,7 @@ private predicate impossibleEdge(BasicBlock bb1, BasicBlock bb2) { /** A control flow edge that leaves a finally-block. */ private predicate leavingFinally(BasicBlock bb1, BasicBlock bb2, boolean normaledge) { - exists(TryStmt try, Block finally | + exists(TryStmt try, BlockStmt finally | try.getFinally() = finally and bb1.getABBSuccessor() = bb2 and bb1.getEnclosingStmt().getEnclosingStmt*() = finally and diff --git a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index b9ae1e7ecd1..eaf7c9d26dc 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -54,12 +54,6 @@ predicate localAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) { ) } -private newtype TUnit = TMkUnit() - -class Unit extends TUnit { - string toString() { result = "unit" } -} - /** * A unit class for adding additional taint steps. * @@ -84,10 +78,10 @@ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) { } /** - * Holds if `node` should be a barrier in all global taint flow configurations + * Holds if `node` should be a sanitizer in all global taint flow configurations * but not in local taint. */ -predicate defaultTaintBarrier(DataFlow::Node node) { +predicate defaultTaintSanitizer(DataFlow::Node node) { // Ignore paths through test code. node.getEnclosingCallable().getDeclaringType() instanceof NonSecurityTestClass or node.asExpr() instanceof ValidatedVariableAccess diff --git a/java/ql/src/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/java/ql/src/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll index af0d0fec53a..b509fad9cd2 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration { final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) or - defaultTaintBarrier(node) + defaultTaintSanitizer(node) } - /** Holds if data flow into `node` is prohibited. */ + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) } - /** Holds if data flow out of `node` is prohibited. */ + /** Holds if taint propagation out of `node` is prohibited. */ predicate isSanitizerOut(DataFlow::Node node) { none() } final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) } - /** Holds if data flow through nodes guarded by `guard` is prohibited. */ + /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */ predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() } final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll index af0d0fec53a..b509fad9cd2 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration { final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) or - defaultTaintBarrier(node) + defaultTaintSanitizer(node) } - /** Holds if data flow into `node` is prohibited. */ + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) } - /** Holds if data flow out of `node` is prohibited. */ + /** Holds if taint propagation out of `node` is prohibited. */ predicate isSanitizerOut(DataFlow::Node node) { none() } final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) } - /** Holds if data flow through nodes guarded by `guard` is prohibited. */ + /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */ predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() } final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) } diff --git a/java/ql/src/semmle/code/java/deadcode/DeadCode.qll b/java/ql/src/semmle/code/java/deadcode/DeadCode.qll index 9749413a23c..48ee3d5563b 100644 --- a/java/ql/src/semmle/code/java/deadcode/DeadCode.qll +++ b/java/ql/src/semmle/code/java/deadcode/DeadCode.qll @@ -93,8 +93,8 @@ class SuppressedConstructor extends Constructor { not isDefaultConstructor() and // Verify that there is only one statement, which is the `super()` call. This exists // even for empty constructors. - getBody().(Block).getNumStmt() = 1 and - getBody().(Block).getAStmt().(SuperConstructorInvocationStmt).getNumArgument() = 0 and + getBody().(BlockStmt).getNumStmt() = 1 and + getBody().(BlockStmt).getAStmt().(SuperConstructorInvocationStmt).getNumArgument() = 0 and // A constructor that is called is not acting to suppress the default constructor. We permit // calls from suppressed and default constructors - in both cases, they can only come from // sub-class constructors. diff --git a/java/ql/src/semmle/code/java/security/LdapInjection.qll b/java/ql/src/semmle/code/java/security/LdapInjection.qll index 45e7d548734..2c1f493c691 100644 --- a/java/ql/src/semmle/code/java/security/LdapInjection.qll +++ b/java/ql/src/semmle/code/java/security/LdapInjection.qll @@ -18,7 +18,7 @@ abstract class LdapInjectionSanitizer extends DataFlow::Node { } * * Extend this class to add additional taint steps that should apply to the `LdapInjectionFlowConfig`. */ -class LdapInjectionAdditionalTaintStep extends TaintTracking::Unit { +class LdapInjectionAdditionalTaintStep extends Unit { /** * Holds if the step from `node1` to `node2` should be considered a taint * step for the `LdapInjectionFlowConfig` configuration. diff --git a/java/ql/src/semmle/code/java/security/QueryInjection.qll b/java/ql/src/semmle/code/java/security/QueryInjection.qll index a81e19a2c28..574229a5ae4 100644 --- a/java/ql/src/semmle/code/java/security/QueryInjection.qll +++ b/java/ql/src/semmle/code/java/security/QueryInjection.qll @@ -13,6 +13,20 @@ import semmle.code.java.frameworks.Hibernate /** A sink for database query language injection vulnerabilities. */ abstract class QueryInjectionSink extends DataFlow::Node { } +/** + * A unit class for adding additional taint steps. + * + * Extend this class to add additional taint steps that should apply to the SQL + * injection taint configuration. + */ +class AdditionalQueryInjectionTaintStep extends Unit { + /** + * Holds if the step from `node1` to `node2` should be considered a taint + * step for SQL injection taint configurations. + */ + abstract predicate step(DataFlow::Node node1, DataFlow::Node node2); +} + /** A sink for SQL injection vulnerabilities. */ private class SqlInjectionSink extends QueryInjectionSink { SqlInjectionSink() { @@ -49,3 +63,30 @@ private class PersistenceQueryInjectionSink extends QueryInjectionSink { ) } } + +/** A sink for MongoDB injection vulnerabilities. */ +private class MongoDbInjectionSink extends QueryInjectionSink { + MongoDbInjectionSink() { + exists(MethodAccess call | + call.getMethod().getDeclaringType().hasQualifiedName("com.mongodb", "BasicDBObject") and + call.getMethod().hasName("parse") and + this.asExpr() = call.getArgument(0) + ) + or + exists(CastExpr c | + c.getExpr() = this.asExpr() and + c.getTypeExpr().getType().(RefType).hasQualifiedName("com.mongodb", "DBObject") + ) + } +} + +private class MongoJsonStep extends AdditionalQueryInjectionTaintStep { + override predicate step(DataFlow::Node node1, DataFlow::Node node2) { + exists(MethodAccess ma | + ma.getMethod().getDeclaringType().hasQualifiedName("com.mongodb.util", "JSON") and + ma.getMethod().hasName("parse") and + ma.getArgument(0) = node1.asExpr() and + ma = node2.asExpr() + ) + } +} diff --git a/java/ql/src/semmle/code/java/security/XSS.qll b/java/ql/src/semmle/code/java/security/XSS.qll index fda7d9d9eab..a9141965f9b 100644 --- a/java/ql/src/semmle/code/java/security/XSS.qll +++ b/java/ql/src/semmle/code/java/security/XSS.qll @@ -20,7 +20,7 @@ abstract class XssSanitizer extends DataFlow::Node { } * Extend this class to add additional taint steps that should apply to the XSS * taint configuration. */ -abstract class XssAdditionalTaintStep extends TaintTracking2::Unit { +class XssAdditionalTaintStep extends Unit { /** * Holds if the step from `node1` to `node2` should be considered a taint * step for XSS taint configurations. diff --git a/java/ql/test/library-tests/controlflow/dominance/dominanceBad.ql b/java/ql/test/library-tests/controlflow/dominance/dominanceBad.ql index 847b0347d37..26d33d9d07b 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominanceBad.ql +++ b/java/ql/test/library-tests/controlflow/dominance/dominanceBad.ql @@ -1,7 +1,7 @@ import java import semmle.code.java.controlflow.Dominance -from IfStmt i, Block b +from IfStmt i, BlockStmt b where b = i.getThen() and dominates(i.getThen(), b) and diff --git a/javascript/ql/src/semmle/javascript/Aliases.qll b/javascript/ql/src/semmle/javascript/Aliases.qll index 33ad90dcb89..3211145517a 100644 --- a/javascript/ql/src/semmle/javascript/Aliases.qll +++ b/javascript/ql/src/semmle/javascript/Aliases.qll @@ -13,7 +13,10 @@ class ArrayAccess = IndexExpr; class AssignOp = CompoundAssignExpr; -class Block = BlockStmt; +/** + * DEPRECATED: The name `BlockStmt` is now preferred in all languages. + */ +deprecated class Block = BlockStmt; class BoolLiteral = BooleanLiteral; diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll index c13915cf76b..e1f1955723f 100644 --- a/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll +++ b/javascript/ql/src/semmle/javascript/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll @@ -85,7 +85,7 @@ module UnsafeShellCommandConstruction { this = root.getALeaf() and root = isExecutedAsShellCommand(DataFlow::TypeBackTracker::end(), sys) and exists(string prev | prev = this.getPreviousLeaf().getStringValue() | - prev.regexpMatch(".* ('|\")?[0-9a-zA-Z/]*") + prev.regexpMatch(".* ('|\")?[0-9a-zA-Z/:_-]*") ) } @@ -132,7 +132,7 @@ module UnsafeShellCommandConstruction { this = call.getFormatArgument(_) and call = isExecutedAsShellCommand(DataFlow::TypeBackTracker::end(), sys) and exists(string formatString | call.getFormatString().mayHaveStringValue(formatString) | - formatString.regexpMatch(".* ('|\")?[0-9a-zA-Z/]*%.*") + formatString.regexpMatch(".* ('|\")?[0-9a-zA-Z/:_-]*%.*") ) } diff --git a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction.expected index b4f1bb5839a..5fb29929f66 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/UnsafeShellCommandConstruction.expected @@ -176,6 +176,10 @@ nodes | lib/lib.js:315:22:315:25 | name | | lib/lib.js:320:23:320:26 | name | | lib/lib.js:320:23:320:26 | name | +| lib/lib.js:324:40:324:42 | arg | +| lib/lib.js:324:40:324:42 | arg | +| lib/lib.js:325:49:325:51 | arg | +| lib/lib.js:325:49:325:51 | arg | edges | lib/lib2.js:3:28:3:31 | name | lib/lib2.js:4:22:4:25 | name | | lib/lib2.js:3:28:3:31 | name | lib/lib2.js:4:22:4:25 | name | @@ -388,6 +392,10 @@ edges | lib/lib.js:314:40:314:43 | name | lib/lib.js:320:23:320:26 | name | | lib/lib.js:314:40:314:43 | name | lib/lib.js:320:23:320:26 | name | | lib/lib.js:314:40:314:43 | name | lib/lib.js:320:23:320:26 | name | +| lib/lib.js:324:40:324:42 | arg | lib/lib.js:325:49:325:51 | arg | +| lib/lib.js:324:40:324:42 | arg | lib/lib.js:325:49:325:51 | arg | +| lib/lib.js:324:40:324:42 | arg | lib/lib.js:325:49:325:51 | arg | +| lib/lib.js:324:40:324:42 | arg | lib/lib.js:325:49:325:51 | arg | #select | lib/lib2.js:4:10:4:25 | "rm -rf " + name | lib/lib2.js:3:28:3:31 | name | lib/lib2.js:4:22:4:25 | name | $@ based on library input is later used in $@. | lib/lib2.js:4:10:4:25 | "rm -rf " + name | String concatenation | lib/lib2.js:4:2:4:26 | cp.exec ... + name) | shell command | | lib/lib2.js:8:10:8:25 | "rm -rf " + name | lib/lib2.js:7:32:7:35 | name | lib/lib2.js:8:22:8:25 | name | $@ based on library input is later used in $@. | lib/lib2.js:8:10:8:25 | "rm -rf " + name | String concatenation | lib/lib2.js:8:2:8:26 | cp.exec ... + name) | shell command | @@ -441,3 +449,4 @@ edges | lib/lib.js:308:11:308:26 | "rm -rf " + name | lib/lib.js:307:39:307:42 | name | lib/lib.js:308:23:308:26 | name | $@ based on library input is later used in $@. | lib/lib.js:308:11:308:26 | "rm -rf " + name | String concatenation | lib/lib.js:308:3:308:27 | cp.exec ... + name) | shell command | | lib/lib.js:315:10:315:25 | "rm -rf " + name | lib/lib.js:314:40:314:43 | name | lib/lib.js:315:22:315:25 | name | $@ based on library input is later used in $@. | lib/lib.js:315:10:315:25 | "rm -rf " + name | String concatenation | lib/lib.js:315:2:315:26 | cp.exec ... + name) | shell command | | lib/lib.js:320:11:320:26 | "rm -rf " + name | lib/lib.js:314:40:314:43 | name | lib/lib.js:320:23:320:26 | name | $@ based on library input is later used in $@. | lib/lib.js:320:11:320:26 | "rm -rf " + name | String concatenation | lib/lib.js:320:3:320:27 | cp.exec ... + name) | shell command | +| lib/lib.js:325:12:325:51 | "MyWind ... " + arg | lib/lib.js:324:40:324:42 | arg | lib/lib.js:325:49:325:51 | arg | $@ based on library input is later used in $@. | lib/lib.js:325:12:325:51 | "MyWind ... " + arg | String concatenation | lib/lib.js:326:2:326:13 | cp.exec(cmd) | shell command | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/lib/lib.js b/javascript/ql/test/query-tests/Security/CWE-078/lib/lib.js index 55c3ca067e2..e91c01cfcce 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/lib/lib.js +++ b/javascript/ql/test/query-tests/Security/CWE-078/lib/lib.js @@ -319,4 +319,9 @@ module.exports.typeofcheck = function (name) { } else { cp.exec("rm -rf " + name); // NOT OK } +} + +module.exports.typeofcheck = function (arg) { + var cmd = "MyWindowCommand | findstr /i /c:" + arg; // NOT OK + cp.exec(cmd); } \ No newline at end of file diff --git a/python/ql/src/experimental/dataflow/internal/TaintTrackingPrivate.qll b/python/ql/src/experimental/dataflow/internal/TaintTrackingPrivate.qll index 1e689fb59f6..64bdd3bb3ab 100644 --- a/python/ql/src/experimental/dataflow/internal/TaintTrackingPrivate.qll +++ b/python/ql/src/experimental/dataflow/internal/TaintTrackingPrivate.qll @@ -4,10 +4,10 @@ private import experimental.dataflow.internal.DataFlowPrivate private import experimental.dataflow.internal.TaintTrackingPublic /** - * Holds if `node` should be a barrier in all global taint flow configurations + * Holds if `node` should be a sanitizer in all global taint flow configurations * but not in local taint. */ -predicate defaultTaintBarrier(DataFlow::Node node) { none() } +predicate defaultTaintSanitizer(DataFlow::Node node) { none() } /** * Holds if the additional step from `nodeFrom` to `nodeTo` should be included in all diff --git a/python/ql/src/experimental/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/python/ql/src/experimental/dataflow/internal/tainttracking1/TaintTrackingImpl.qll index af0d0fec53a..b509fad9cd2 100644 --- a/python/ql/src/experimental/dataflow/internal/tainttracking1/TaintTrackingImpl.qll +++ b/python/ql/src/experimental/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration { final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) or - defaultTaintBarrier(node) + defaultTaintSanitizer(node) } - /** Holds if data flow into `node` is prohibited. */ + /** Holds if taint propagation into `node` is prohibited. */ predicate isSanitizerIn(DataFlow::Node node) { none() } final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) } - /** Holds if data flow out of `node` is prohibited. */ + /** Holds if taint propagation out of `node` is prohibited. */ predicate isSanitizerOut(DataFlow::Node node) { none() } final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) } - /** Holds if data flow through nodes guarded by `guard` is prohibited. */ + /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */ predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() } final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) } diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/TestTaint.expected b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/TestTaint.expected new file mode 100644 index 00000000000..bbd5ac7fd40 --- /dev/null +++ b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/TestTaint.expected @@ -0,0 +1,9 @@ +test_taint +| test.py:22 | fail | test_custom_sanitizer | s | +| test.py:36 | fail | test_custom_sanitizer_guard | s | +| test.py:38 | ok | test_custom_sanitizer_guard | s | +| test.py:49 | ok | test_escape | s2 | +isSanitizer +| TestTaintTrackingConfiguration | test.py:21:39:21:39 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test.py:48:10:48:29 | ControlFlowNode for emulated_escaping() | +isSanitizerGuard diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/TestTaint.ql b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/TestTaint.ql new file mode 100644 index 00000000000..c7fde1afee0 --- /dev/null +++ b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/TestTaint.ql @@ -0,0 +1,30 @@ +import experimental.dataflow.tainttracking.TestTaintLib + +class CustomSanitizerOverrides extends TestTaintTrackingConfiguration { + override predicate isSanitizer(DataFlow::Node node) { + exists(Call call | + call.getFunc().(Name).getId() = "emulated_authentication_check" and + call.getArg(0) = node.asExpr() + ) + or + node.asExpr().(Call).getFunc().(Name).getId() = "emulated_escaping" + } + + override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { + // TODO: Future work for when BarrierGuard is implemented properly + // exists(Call call | + // call.getFunc().(Name).getId() = "emulated_is_safe" and + // ) + none() + } +} + +query predicate isSanitizer(TestTaintTrackingConfiguration conf, DataFlow::Node node) { + exists(node.getLocation().getFile().getRelativePath()) and + conf.isSanitizer(node) +} + +query predicate isSanitizerGuard(TestTaintTrackingConfiguration conf, DataFlow::BarrierGuard guard) { + exists(guard.getLocation().getFile().getRelativePath()) and + conf.isSanitizerGuard(guard) +} diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test.py b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test.py new file mode 100644 index 00000000000..1c9026ab1ae --- /dev/null +++ b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test.py @@ -0,0 +1,56 @@ +import sys; import os; sys.path.append(os.path.dirname(os.path.dirname((__file__)))) +from taintlib import * + +# This has no runtime impact, but allows autocomplete to work +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from ..taintlib import * + + +# Actual tests + +def emulated_authentication_check(arg): + if not arg == "safe": + raise Exception("user unauthenticated") + + +def test_custom_sanitizer(): + s = TAINTED_STRING + + try: + emulated_authentication_check(s) + ensure_not_tainted(s) + except: + pass + + +def emulated_is_safe(arg): + # emulating something we won't be able to look at source code for + return eval("False") + + +def test_custom_sanitizer_guard(): + s = TAINTED_STRING + + if emulated_is_safe(s): + ensure_not_tainted(s) + else: + ensure_tainted(s) + + +def emulated_escaping(arg): + return arg.replace("<", "?").replace(">", "?").replace("'", "?").replace("\"", "?") + + +def test_escape(): + s = TAINTED_STRING + + s2 = emulated_escaping(s) + ensure_not_tainted(s2) + + +# Make tests runable + +test_custom_sanitizer() +test_custom_sanitizer_guard() +test_escape() diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultSanitizer/TestTaint.expected b/python/ql/test/experimental/dataflow/tainttracking/defaultSanitizer/TestTaint.expected index a5ce4c08735..9149e6663c4 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/defaultSanitizer/TestTaint.expected +++ b/python/ql/test/experimental/dataflow/tainttracking/defaultSanitizer/TestTaint.expected @@ -1,5 +1,37 @@ -| test.py:16 | fail | const_eq_clears_taint | ts | -| test.py:18 | ok | const_eq_clears_taint | ts | -| test.py:24 | fail | const_eq_clears_taint2 | ts | -| test.py:29 | ok | non_const_eq_preserves_taint | ts | -| test.py:31 | ok | non_const_eq_preserves_taint | ts | +| test_logical.py:30 | fail | test_basic | s | +| test_logical.py:32 | ok | test_basic | s | +| test_logical.py:35 | ok | test_basic | s | +| test_logical.py:37 | fail | test_basic | s | +| test_logical.py:45 | ok | test_or | s | +| test_logical.py:47 | ok | test_or | s | +| test_logical.py:51 | ok | test_or | s | +| test_logical.py:53 | ok | test_or | s | +| test_logical.py:57 | ok | test_or | s | +| test_logical.py:59 | ok | test_or | s | +| test_logical.py:67 | fail | test_and | s | +| test_logical.py:69 | ok | test_and | s | +| test_logical.py:73 | ok | test_and | s | +| test_logical.py:75 | fail | test_and | s | +| test_logical.py:79 | ok | test_and | s | +| test_logical.py:81 | fail | test_and | s | +| test_logical.py:89 | fail | test_tricky | s | +| test_logical.py:93 | fail | test_tricky | s_ | +| test_logical.py:100 | fail | test_nesting_not | s | +| test_logical.py:102 | ok | test_nesting_not | s | +| test_logical.py:105 | ok | test_nesting_not | s | +| test_logical.py:107 | fail | test_nesting_not | s | +| test_logical.py:116 | ok | test_nesting_not_with_and_true | s | +| test_logical.py:118 | fail | test_nesting_not_with_and_true | s | +| test_logical.py:121 | fail | test_nesting_not_with_and_true | s | +| test_logical.py:123 | ok | test_nesting_not_with_and_true | s | +| test_logical.py:126 | ok | test_nesting_not_with_and_true | s | +| test_logical.py:128 | fail | test_nesting_not_with_and_true | s | +| test_string_eq.py:16 | fail | const_eq_clears_taint | ts | +| test_string_eq.py:18 | ok | const_eq_clears_taint | ts | +| test_string_eq.py:20 | ok | const_eq_clears_taint | ts | +| test_string_eq.py:27 | fail | const_eq_clears_taint2 | ts | +| test_string_eq.py:33 | ok | non_const_eq_preserves_taint | ts | +| test_string_eq.py:35 | ok | non_const_eq_preserves_taint | ts | +| test_string_eq.py:45 | fail | const_eq_through_func | ts | +| test_string_eq.py:47 | ok | const_eq_through_func | ts | +| test_string_eq.py:49 | ok | const_eq_through_func | ts | diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultSanitizer/test_logical.py b/python/ql/test/experimental/dataflow/tainttracking/defaultSanitizer/test_logical.py new file mode 100644 index 00000000000..ec78cfa2f60 --- /dev/null +++ b/python/ql/test/experimental/dataflow/tainttracking/defaultSanitizer/test_logical.py @@ -0,0 +1,138 @@ +import sys; import os; sys.path.append(os.path.dirname(os.path.dirname((__file__)))) +from taintlib import * + +# This has no runtime impact, but allows autocomplete to work +from typing import TYPE_CHECKING +if TYPE_CHECKING: + from ..taintlib import * + + +# Actual tests + +"""Testing logical constructs not/and/or works out of the box. +""" + +import random + + +def random_choice(): + return bool(random.randint(0, 1)) + + +def is_safe(arg): + return arg == "safe" + + +def test_basic(): + s = TAINTED_STRING + + if is_safe(s): + ensure_not_tainted(s) + else: + ensure_tainted(s) + + if not is_safe(s): + ensure_tainted(s) + else: + ensure_not_tainted(s) + + +def test_or(): + s = TAINTED_STRING + + # x or y + if is_safe(s) or random_choice(): + ensure_tainted(s) # might be tainted + else: + ensure_tainted(s) # must be tainted + + # not (x or y) + if not(is_safe(s) or random_choice()): + ensure_tainted(s) # must be tainted + else: + ensure_tainted(s) # might be tainted + + # not (x or y) == not x and not y [de Morgan's laws] + if not is_safe(s) and not random_choice(): + ensure_tainted(s) # must be tainted + else: + ensure_tainted(s) # might be tainted + + +def test_and(): + s = TAINTED_STRING + + # x and y + if is_safe(s) and random_choice(): + ensure_not_tainted(s) # must not be tainted + else: + ensure_tainted(s) # might be tainted + + # not (x and y) + if not(is_safe(s) and random_choice()): + ensure_tainted(s) # might be tainted + else: + ensure_not_tainted(s) + + # not (x and y) == not x or not y [de Morgan's laws] + if not is_safe(s) or not random_choice(): + ensure_tainted(s) # might be tainted + else: + ensure_not_tainted(s) + + +def test_tricky(): + s = TAINTED_STRING + + x = is_safe(s) + if x: + ensure_not_tainted(s) # FP + + s_ = s + if is_safe(s): + ensure_not_tainted(s_) # FP + + +def test_nesting_not(): + s = TAINTED_STRING + + if not(not(is_safe(s))): + ensure_not_tainted(s) + else: + ensure_tainted(s) + + if not(not(not(is_safe(s)))): + ensure_tainted(s) + else: + ensure_not_tainted(s) + + +# Adding `and True` makes the sanitizer trigger when it would otherwise not. See output in +# SanitizedEdges.expected and compare with `test_nesting_not` and `test_basic` +def test_nesting_not_with_and_true(): + s = TAINTED_STRING + + if not(is_safe(s) and True): + ensure_tainted(s) + else: + ensure_not_tainted(s) + + if not(not(is_safe(s) and True)): + ensure_not_tainted(s) + else: + ensure_tainted(s) + + if not(not(not(is_safe(s) and True))): + ensure_tainted(s) + else: + ensure_not_tainted(s) + + +# Make tests runable + +test_basic() +test_or() +test_and() +test_tricky() +test_nesting_not() +test_nesting_not_with_and_true() diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultSanitizer/test.py b/python/ql/test/experimental/dataflow/tainttracking/defaultSanitizer/test_string_eq.py similarity index 74% rename from python/ql/test/experimental/dataflow/tainttracking/defaultSanitizer/test.py rename to python/ql/test/experimental/dataflow/tainttracking/defaultSanitizer/test_string_eq.py index baaa3fb2b8f..270e1d99093 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/defaultSanitizer/test.py +++ b/python/ql/test/experimental/dataflow/tainttracking/defaultSanitizer/test_string_eq.py @@ -14,15 +14,19 @@ def const_eq_clears_taint(): ts = TAINTED_STRING if ts == "safe": ensure_not_tainted(ts) + else: + ensure_tainted(ts) # ts should still be tainted after exiting the if block ensure_tainted(ts) + def const_eq_clears_taint2(): ts = TAINTED_STRING if ts != "safe": return ensure_not_tainted(ts) + def non_const_eq_preserves_taint(x="foo"): ts = TAINTED_STRING if ts == ts: @@ -31,6 +35,20 @@ def non_const_eq_preserves_taint(x="foo"): ensure_tainted(ts) +def is_safe(x): + return x == "safe" + + +def const_eq_through_func(): + ts = TAINTED_STRING + if is_safe(ts): + ensure_not_tainted(ts) + else: + ensure_tainted(ts) + # ts should still be tainted after exiting the if block + ensure_tainted(ts) + + # Make tests runable const_eq_clears_taint()