Merge remote-tracking branch 'upstream/main' into SimpleRangeAnalysis-NotExpr

This commit is contained in:
Jonas Jensen
2020-09-09 14:50:00 +02:00
462 changed files with 19819 additions and 10311 deletions

View File

@@ -13,12 +13,14 @@ The following changes in version 1.26 affect C/C++ analysis in all applications.
| **Query** | **Expected impact** | **Change** |
|----------------------------|------------------------|------------------------------------------------------------------|
| Declaration hides parameter (`cpp/declaration-hides-parameter`) | Fewer false positive results | False positives involving template functions have been fixed. |
| Inconsistent direction of for loop (`cpp/inconsistent-loop-direction`) | Fewer false positive results | The query now accounts for intentional wrapping of an unsigned loop counter. |
| Overflow in uncontrolled allocation size (`cpp/uncontrolled-allocation-size`) | | The precision of this query has been decreased from "high" to "medium". As a result, the query is still run but results are no longer displayed on LGTM by default. |
| Comparison result is always the same (`cpp/constant-comparison`) | More correct results | Bounds on expressions involving multiplication can now be determined in more cases. |
## 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 `SimpleRangeAnalysis` library now supports multiplications of the form

View File

@@ -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`.

View File

@@ -30,6 +30,9 @@
| 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. |
## Changes to libraries
* The predicate `TypeAnnotation.hasQualifiedName` now works in more cases when the imported library was not present during extraction.

View File

@@ -9,6 +9,6 @@
import cpp
from Block blk
from BlockStmt blk
where blk.getNumStmt() = 0
select blk

View File

@@ -13,5 +13,5 @@
import cpp
from IfStmt i
where i.getThen().(Block).getNumStmt() = 0
where i.getThen().(BlockStmt).getNumStmt() = 0
select i

View File

@@ -8,6 +8,6 @@
import cpp
from Block b
from BlockStmt b
where b.getNumStmt() = 1
select b

View File

@@ -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

View File

@@ -11,6 +11,17 @@
import cpp
/**
* Gets the template that a function `f` is constructed from, or just `f` if it
* is not from a template instantiation.
*/
Function getConstructedFrom(Function f) {
f.isConstructedFrom(result)
or
not f.isConstructedFrom(_) and
result = f
}
/**
* Gets the parameter of `f` with name `name`, which has to come from the
* _definition_ of `f` and not a prototype declaration.
@@ -18,13 +29,17 @@ import cpp
* This should not happen in a single application but since we
* have a system wide view it is likely to happen for instance for
* the main function.
*
* Note: we use `getConstructedFrom` to ensure that we look at template
* functions rather than their instantiations. We get better results this way
* as the instantiation is artificial and may have inherited parameter names
* from the declaration rather than the definition.
*/
ParameterDeclarationEntry functionParameterNames(Function f, string name) {
exists(FunctionDeclarationEntry fe |
result.getFunctionDeclarationEntry() = fe and
fe.getFunction() = f and
getConstructedFrom(f).getDefinition() = fe and
fe.getLocation() = f.getDefinitionLocation() and
result.getFile() = fe.getFile() and // Work around CPP-331
strictcount(f.getDefinitionLocation()) = 1 and
result.getName() = name
)

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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()]

View File

@@ -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()

View File

@@ -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()

View File

@@ -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...

View File

@@ -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()

View File

@@ -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()
}

View File

@@ -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(

View File

@@ -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

View File

@@ -45,6 +45,16 @@ predicate dereferenceThis(Expr e) {
or
// `*this = ...` (where `=` is not overloaded, so an `AssignExpr`)
dereferenceThis(e.(AssignExpr).getLValue())
or
// `e ? ... : ... `
exists(ConditionalExpr cond |
cond = e and
dereferenceThis(cond.getThen()) and
dereferenceThis(cond.getElse())
)
or
// `..., ... `
dereferenceThis(e.(CommaExpr).getRightOperand())
}
/**

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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."

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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. */

View File

@@ -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.

View File

@@ -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)

View File

@@ -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).

View File

@@ -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

View File

@@ -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())
}
/**
@@ -1268,3 +1268,31 @@ class SpaceshipExpr extends BinaryOperation, @spaceshipexpr {
override string getOperator() { result = "<=>" }
}
/**
* A C/C++ `co_await` expression.
* ```
* co_await foo();
* ```
*/
class CoAwaitExpr extends UnaryOperation, @co_await {
override string getAPrimaryQlClass() { result = "CoAwaitExpr" }
override string getOperator() { result = "co_await" }
override int getPrecedence() { result = 16 }
}
/**
* A C/C++ `co_yield` expression.
* ```
* co_yield 1;
* ```
*/
class CoYieldExpr extends UnaryOperation, @co_yield {
override string getAPrimaryQlClass() { result = "CoYieldExpr" }
override string getOperator() { result = "co_yield" }
override int getPrecedence() { result = 2 }
}

View File

@@ -11,6 +11,7 @@ private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.controlflow.IRGuards
private import semmle.code.cpp.models.interfaces.DataFlow
cached
private newtype TIRDataFlowNode =
TInstructionNode(Instruction i) or
TOperandNode(Operand op) or
@@ -533,11 +534,11 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFr
* data flow. It may have less flow than the `localFlowStep` predicate.
*/
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
// Instruction -> Instruction flow
simpleInstructionLocalFlowStep(nodeFrom.asInstruction(), nodeTo.asInstruction())
or
// Operand -> Instruction flow
simpleOperandLocalFlowStep(nodeFrom.asOperand(), nodeTo.asInstruction())
simpleInstructionLocalFlowStep(nodeFrom.asOperand(), nodeTo.asInstruction())
or
// Instruction -> Operand flow
simpleOperandLocalFlowStep(nodeFrom.asInstruction(), nodeTo.asOperand())
}
pragma[noinline]
@@ -549,26 +550,20 @@ private predicate getFieldSizeOfClass(Class c, Type type, int size) {
)
}
private predicate simpleOperandLocalFlowStep(Operand opFrom, Instruction iTo) {
// Certain dataflow steps (for instance `PostUpdateNode.getPreUpdateNode()`) generates flow to
// operands, so we include dataflow from those operands to the "result" of the instruction (i.e., to
// the instruction itself).
exists(PostUpdateNode post |
opFrom = post.getPreUpdateNode().asOperand() and
iTo.getAnOperand() = opFrom
private predicate isSingleFieldClass(Type type, Class cTo) {
exists(int size |
cTo.getSize() = size and
getFieldSizeOfClass(cTo, type, size)
)
}
cached
private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction iTo) {
iTo.(CopyInstruction).getSourceValue() = iFrom
private predicate simpleOperandLocalFlowStep(Instruction iFrom, Operand opTo) {
// Propagate flow from an instruction to its exact uses.
opTo.getDef() = iFrom
or
iTo.(PhiInstruction).getAnOperand().getDef() = iFrom
or
// A read side effect is almost never exact since we don't know exactly how
// much memory the callee will read.
iTo.(ReadSideEffectInstruction).getSideEffectOperand().getAnyDef() = iFrom and
not iFrom.isResultConflated()
opTo = any(ReadSideEffectInstruction read).getSideEffectOperand() and
not iFrom.isResultConflated() and
iFrom = opTo.getAnyDef()
or
// Loading a single `int` from an `int *` parameter is not an exact load since
// the parameter may point to an entire array rather than a single `int`. The
@@ -582,20 +577,38 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
// leads to a phi node.
exists(InitializeIndirectionInstruction init |
iFrom = init and
iTo.(LoadInstruction).getSourceValueOperand().getAnyDef() = init and
opTo.(LoadOperand).getAnyDef() = init and
// Check that the types match. Otherwise we can get flow from an object to
// its fields, which leads to field conflation when there's flow from other
// fields to the object elsewhere.
init.getParameter().getType().getUnspecifiedType().(DerivedType).getBaseType() =
iTo.getResultType().getUnspecifiedType()
opTo.getType().getUnspecifiedType()
)
or
// Flow from stores to structs with a single field to a load of that field.
exists(LoadInstruction load |
load.getSourceValueOperand() = opTo and
opTo.getAnyDef() = iFrom and
isSingleFieldClass(iFrom.getResultType(), opTo.getType())
)
}
cached
private predicate simpleInstructionLocalFlowStep(Operand opFrom, Instruction iTo) {
iTo.(CopyInstruction).getSourceValueOperand() = opFrom
or
iTo.(PhiInstruction).getAnInputOperand() = opFrom
or
// A read side effect is almost never exact since we don't know exactly how
// much memory the callee will read.
iTo.(ReadSideEffectInstruction).getSideEffectOperand() = opFrom
or
// Treat all conversions as flow, even conversions between different numeric types.
iTo.(ConvertInstruction).getUnary() = iFrom
iTo.(ConvertInstruction).getUnaryOperand() = opFrom
or
iTo.(CheckedConvertOrNullInstruction).getUnary() = iFrom
iTo.(CheckedConvertOrNullInstruction).getUnaryOperand() = opFrom
or
iTo.(InheritanceConversionInstruction).getUnary() = iFrom
iTo.(InheritanceConversionInstruction).getUnaryOperand() = opFrom
or
// A chi instruction represents a point where a new value (the _partial_
// operand) may overwrite an old value (the _total_ operand), but the alias
@@ -608,7 +621,7 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
//
// Flow through the partial operand belongs in the taint-tracking libraries
// for now.
iTo.getAnOperand().(ChiTotalOperand).getDef() = iFrom
iTo.getAnOperand().(ChiTotalOperand) = opFrom
or
// Add flow from write side-effects to non-conflated chi instructions through their
// partial operands. From there, a `readStep` will find subsequent reads of that field.
@@ -623,24 +636,16 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
// Here, a `WriteSideEffectInstruction` will provide a new definition for `p->x` after the call to
// `setX`, which will be melded into `p` through a chi instruction.
exists(ChiInstruction chi | chi = iTo |
chi.getPartialOperand().getDef() = iFrom.(WriteSideEffectInstruction) and
opFrom.getAnyDef() instanceof WriteSideEffectInstruction and
chi.getPartialOperand() = opFrom and
not chi.isResultConflated()
)
or
// Flow from stores to structs with a single field to a load of that field.
iTo.(LoadInstruction).getSourceValueOperand().getAnyDef() = iFrom and
exists(int size, Type type, Class cTo |
type = iFrom.getResultType() and
cTo = iTo.getResultType() and
cTo.getSize() = size and
getFieldSizeOfClass(cTo, type, size)
)
or
// Flow through modeled functions
modelFlow(iFrom, iTo)
modelFlow(opFrom, iTo)
}
private predicate modelFlow(Instruction iFrom, Instruction iTo) {
private predicate modelFlow(Operand opFrom, Instruction iTo) {
exists(
CallInstruction call, DataFlowFunction func, FunctionInput modelIn, FunctionOutput modelOut
|
@@ -665,17 +670,17 @@ private predicate modelFlow(Instruction iFrom, Instruction iTo) {
(
exists(int index |
modelIn.isParameter(index) and
iFrom = call.getPositionalArgument(index)
opFrom = call.getPositionalArgumentOperand(index)
)
or
exists(int index, ReadSideEffectInstruction read |
modelIn.isParameterDeref(index) and
read = getSideEffectFor(call, index) and
iFrom = read.getSideEffectOperand().getAnyDef()
opFrom = read.getSideEffectOperand()
)
or
modelIn.isQualifierAddress() and
iFrom = call.getThisArgument()
opFrom = call.getThisArgumentOperand()
// TODO: add read side effects for qualifiers
)
)

View File

@@ -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)

View File

@@ -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) }

View File

@@ -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

View File

@@ -1,6 +1,6 @@
/**
* Provides implementation classes modeling `std::string` and other
* instantiations of`std::basic_string`. See `semmle.code.cpp.models.Models`
* instantiations of `std::basic_string`. See `semmle.code.cpp.models.Models`
* for usage information.
*/
@@ -82,6 +82,32 @@ class StdStringData extends TaintFunction {
}
}
/**
* The `std::string` function `push_back`.
*/
class StdStringPush extends TaintFunction {
StdStringPush() { this.hasQualifiedName("std", "basic_string", "push_back") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from parameter to qualifier
input.isParameterDeref(0) and
output.isQualifierObject()
}
}
/**
* The `std::string` functions `front` and `back`.
*/
class StdStringFrontBack extends TaintFunction {
StdStringFrontBack() { this.hasQualifiedName("std", "basic_string", ["front", "back"]) }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from object to returned reference
input.isQualifierObject() and
output.isReturnValueDeref()
}
}
/**
* The `std::string` function `operator+`.
*/
@@ -138,6 +164,11 @@ class StdStringAppend extends TaintFunction {
output.isQualifierObject() or
output.isReturnValueDeref()
)
or
// reverse flow from returned reference to the qualifier (for writes to
// the result)
input.isReturnValueDeref() and
output.isQualifierObject()
}
}
@@ -173,6 +204,11 @@ class StdStringAssign extends TaintFunction {
output.isQualifierObject() or
output.isReturnValueDeref()
)
or
// reverse flow from returned reference to the qualifier (for writes to
// the result)
input.isReturnValueDeref() and
output.isQualifierObject()
}
}

View File

@@ -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;

View File

@@ -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; }
* ```
@@ -662,6 +662,67 @@ class LabelStmt extends Stmt, @stmt_label {
override predicate mayBeGloballyImpure() { none() }
}
/**
* A C/C++ `co_return` statement.
*
* For example:
* ```
* co_return 1+2;
* ```
* or
* ```
* co_return;
* ```
*/
class CoReturnStmt extends Stmt, @stmt_co_return {
override string getAPrimaryQlClass() { result = "CoReturnStmt" }
/**
* Gets the operand of this 'co_return' statement.
*
* For example, for
* ```
* co_return 1+2;
* ```
* the operand is a function call `return_value(1+2)`, and for
* ```
* co_return;
* ```
* the operand is a function call `return_void()`.
*/
FunctionCall getOperand() { result = this.getChild(0) }
/**
* Gets the expression of this 'co_return' statement, if any.
*
* For example, for
* ```
* co_return 1+2;
* ```
* the result is `1+2`, and there is no result for
* ```
* co_return;
* ```
*/
Expr getExpr() { result = this.getOperand().getArgument(0) }
/**
* Holds if this 'co_return' statement has an expression.
*
* For example, this holds for
* ```
* co_return 1+2;
* ```
* but not for
* ```
* co_return;
* ```
*/
predicate hasExpr() { exists(this.getExpr()) }
override string toString() { result = "co_return ..." }
}
/**
* A C/C++ 'return' statement.
*
@@ -781,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) }
@@ -1168,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
@@ -1189,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)
@@ -1270,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
@@ -1309,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
)
}
@@ -1467,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
@@ -1798,7 +1859,7 @@ class FunctionTryStmt extends TryStmt {
* }
* ```
*/
class CatchBlock extends Block {
class CatchBlock extends BlockStmt {
override string getAPrimaryQlClass() { result = "CatchBlock" }
CatchBlock() { ishandler(underlyingElement(this)) }
@@ -1864,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" }
@@ -1888,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" }
@@ -2047,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 -
@@ -2064,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)
)

View File

@@ -1228,6 +1228,8 @@ funbind(
| @builtinaddressof
| @vec_fill
| @un_log_op_expr
| @co_await
| @co_yield
;
@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
@@ -1647,6 +1649,8 @@ case @expr.kind of
| 324 = @builtinconvertvector
| 325 = @builtincomplex
| 326 = @spaceshipexpr
| 327 = @co_await
| 328 = @co_yield
;
@var_args_expr = @vastartexpr
@@ -1851,6 +1855,7 @@ case @stmt.kind of
| 33 = @stmt_handler
// ... 34 @stmt_finally_end deprecated
| 35 = @stmt_constexpr_if
| 37 = @stmt_co_return
;
type_vla(

View File

@@ -848,6 +848,14 @@
<v>1</v>
</e>
<e>
<k>@co_await</k>
<v>6</v>
</e>
<e>
<k>@co_yield</k>
<v>1</v>
</e>
<e>
<k>@lambdacapture</k>
<v>21652</v>
</e>
@@ -948,6 +956,10 @@
<v>3</v>
</e>
<e>
<k>@stmt_co_return</k>
<v>2</v>
</e>
<e>
<k>@ppd_if</k>
<v>156097</v>
</e>
@@ -1524,7 +1536,7 @@
</e>
<e>
<k>seconds</k>
<v>12239</v>
<v>11965</v>
</e>
</columnsizes>
<dependencies>
@@ -1568,19 +1580,14 @@
<budget>12</budget>
<bs>
<b>
<a>2</a>
<b>3</b>
<v>10</v>
</b>
<b>
<a>3</a>
<b>4</b>
<v>2588</v>
<v>2719</v>
</b>
<b>
<a>4</a>
<b>5</b>
<v>6931</v>
<v>6810</v>
</b>
</bs>
</hist>
@@ -1626,8 +1633,8 @@
<budget>12</budget>
<bs>
<b>
<a>1116</a>
<b>1117</b>
<a>1091</a>
<b>1092</b>
<v>10</v>
</b>
</bs>
@@ -1674,8 +1681,8 @@
<budget>12</budget>
<bs>
<b>
<a>6</a>
<b>7</b>
<a>7</a>
<b>8</b>
<v>10</v>
</b>
<b>
@@ -1684,13 +1691,13 @@
<v>10</v>
</b>
<b>
<a>574</a>
<b>575</b>
<a>572</a>
<b>573</b>
<v>10</v>
</b>
<b>
<a>681</a>
<b>682</b>
<a>666</a>
<b>667</b>
<v>10</v>
</b>
</bs>
@@ -1707,22 +1714,22 @@
<b>
<a>1</a>
<b>2</b>
<v>7907</v>
<v>7863</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>2665</v>
<v>2237</v>
</b>
<b>
<a>3</a>
<b>4</b>
<v>965</v>
<v>1107</v>
</b>
<b>
<a>4</a>
<b>621</b>
<v>701</v>
<b>641</b>
<v>756</v>
</b>
</bs>
</hist>
@@ -1738,7 +1745,7 @@
<b>
<a>1</a>
<b>2</b>
<v>12239</v>
<v>11965</v>
</b>
</bs>
</hist>
@@ -1754,17 +1761,17 @@
<b>
<a>1</a>
<b>2</b>
<v>10528</v>
<v>10144</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>1688</v>
<v>1809</v>
</b>
<b>
<a>3</a>
<b>4</b>
<v>21</v>
<v>10</v>
</b>
</bs>
</hist>
@@ -2143,11 +2150,11 @@
</e>
<e>
<k>cpu_seconds</k>
<v>8203</v>
<v>8159</v>
</e>
<e>
<k>elapsed_seconds</k>
<v>186</v>
<v>197</v>
</e>
</columnsizes>
<dependencies>
@@ -2193,17 +2200,17 @@
<b>
<a>1</a>
<b>2</b>
<v>7161</v>
<v>7106</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>800</v>
<v>833</v>
</b>
<b>
<a>3</a>
<b>5</b>
<v>241</v>
<b>7</b>
<v>219</v>
</b>
</bs>
</hist>
@@ -2219,12 +2226,12 @@
<b>
<a>1</a>
<b>2</b>
<v>7764</v>
<v>7677</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>438</v>
<v>482</v>
</b>
</bs>
</hist>
@@ -2240,12 +2247,12 @@
<b>
<a>1</a>
<b>2</b>
<v>32</v>
<v>43</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>32</v>
<v>21</v>
</b>
<b>
<a>4</a>
@@ -2253,8 +2260,13 @@
<v>10</v>
</b>
<b>
<a>7</a>
<b>8</b>
<a>6</a>
<b>7</b>
<v>10</v>
</b>
<b>
<a>9</a>
<b>10</b>
<v>10</v>
</b>
<b>
@@ -2263,43 +2275,43 @@
<v>10</v>
</b>
<b>
<a>18</a>
<b>19</b>
<a>13</a>
<b>14</b>
<v>10</v>
</b>
<b>
<a>26</a>
<b>27</b>
<a>31</a>
<b>32</b>
<v>10</v>
</b>
<b>
<a>29</a>
<b>30</b>
<a>32</a>
<b>33</b>
<v>10</v>
</b>
<b>
<a>108</a>
<b>109</b>
<a>99</a>
<b>100</b>
<v>10</v>
</b>
<b>
<a>126</a>
<b>127</b>
<a>106</a>
<b>107</b>
<v>10</v>
</b>
<b>
<a>151</a>
<b>152</b>
<a>149</a>
<b>150</b>
<v>10</v>
</b>
<b>
<a>162</a>
<b>163</b>
<a>191</a>
<b>192</b>
<v>10</v>
</b>
<b>
<a>219</a>
<b>220</b>
<a>211</a>
<b>212</b>
<v>10</v>
</b>
</bs>
@@ -2316,12 +2328,12 @@
<b>
<a>1</a>
<b>2</b>
<v>32</v>
<v>43</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>32</v>
<v>21</v>
</b>
<b>
<a>4</a>
@@ -2329,8 +2341,13 @@
<v>10</v>
</b>
<b>
<a>7</a>
<b>8</b>
<a>6</a>
<b>7</b>
<v>10</v>
</b>
<b>
<a>9</a>
<b>10</b>
<v>10</v>
</b>
<b>
@@ -2339,43 +2356,43 @@
<v>10</v>
</b>
<b>
<a>17</a>
<b>18</b>
<a>13</a>
<b>14</b>
<v>10</v>
</b>
<b>
<a>26</a>
<b>27</b>
<a>31</a>
<b>32</b>
<v>10</v>
</b>
<b>
<a>29</a>
<b>30</b>
<a>32</a>
<b>33</b>
<v>10</v>
</b>
<b>
<a>86</a>
<b>87</b>
<a>87</a>
<b>88</b>
<v>10</v>
</b>
<b>
<a>119</a>
<b>120</b>
<a>90</a>
<b>91</b>
<v>10</v>
</b>
<b>
<a>130</a>
<b>131</b>
<a>138</a>
<b>139</b>
<v>10</v>
</b>
<b>
<a>139</a>
<b>140</b>
<a>178</a>
<b>179</b>
<v>10</v>
</b>
<b>
<a>210</a>
<b>211</b>
<a>180</a>
<b>181</b>
<v>10</v>
</b>
</bs>

View File

@@ -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 *

View File

@@ -149,3 +149,63 @@ void test_conflated_fields2() {
taint_x(&p);
y_to_sink(&p);
}
void sink(Point*);
void sink(Point);
void test_field_to_obj_taint_object(Point p) {
p.x = getenv("VAR")[0];
sink(p); // not tainted
sink(p.x); // tainted
}
void test_field_to_obj_taint_object_addrof(Point p) {
taint_x(&p);
sink(p); // tainted [field -> object]
sink(&p); // tainted [field -> object]
sink(p.x); // tainted
}
void test_field_to_obj_taint_pointer(Point* pp) {
pp->x = getenv("VAR")[0];
sink(pp); // tainted [field -> object]
sink(*pp); // not tainted
}
void call_sink_on_object(Point* pp) {
sink(pp); // tainted [field -> object]
sink(*pp); // tainted [field -> object]
}
void test_field_to_obj_taint_call_sink(Point* pp) {
pp->x = getenv("VAR")[0];
call_sink_on_object(pp);
}
void test_field_to_obj_taint_through_setter(Point* pp) {
taint_x(pp);
sink(pp); // tainted [field -> object]
sink(*pp); // not tainted
}
Point* getPoint();
void test_field_to_obj_local_variable() {
Point* pp = getPoint();
pp->x = getenv("VAR")[0];
sink(pp); // not tainted
sink(*pp); // not tainted
}
void test_field_to_obj_taint_array(Point* pp, int i) {
pp[0].x = getenv("VAR")[0];
sink(pp[i]); // not tainted
sink(pp); // tainted [field -> object]
sink(*pp); // not tainted
}
void test_field_to_obj_test_pointer_arith(Point* pp) {
(pp + sizeof(*pp))->x = getenv("VAR")[0];
sink(pp); // tainted [field -> object]
sink(pp + sizeof(*pp)); // tainted [field -> object]
}

View File

@@ -115,6 +115,48 @@
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:143:23:143:24 | pp |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:144:8:144:9 | pp |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:150:13:150:14 | & ... |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:154:11:154:15 | p#0 |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:162:50:162:50 | p |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:164:8:164:8 | p |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:165:8:165:9 | & ... |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:166:10:166:10 | x |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:187:8:187:9 | pp |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | shared.h:6:15:6:23 | sinkparam |
| defaulttainttracking.cpp:157:9:157:14 | call to getenv | defaulttainttracking.cpp:157:9:157:14 | call to getenv |
| defaulttainttracking.cpp:157:9:157:14 | call to getenv | defaulttainttracking.cpp:157:9:157:24 | (int)... |
| defaulttainttracking.cpp:157:9:157:14 | call to getenv | defaulttainttracking.cpp:157:9:157:24 | access to array |
| defaulttainttracking.cpp:157:9:157:14 | call to getenv | defaulttainttracking.cpp:159:10:159:10 | x |
| defaulttainttracking.cpp:157:9:157:14 | call to getenv | shared.h:6:15:6:23 | sinkparam |
| defaulttainttracking.cpp:170:11:170:16 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 |
| defaulttainttracking.cpp:170:11:170:16 | call to getenv | defaulttainttracking.cpp:170:11:170:16 | call to getenv |
| defaulttainttracking.cpp:170:11:170:16 | call to getenv | defaulttainttracking.cpp:170:11:170:26 | (int)... |
| defaulttainttracking.cpp:170:11:170:16 | call to getenv | defaulttainttracking.cpp:170:11:170:26 | access to array |
| defaulttainttracking.cpp:170:11:170:16 | call to getenv | defaulttainttracking.cpp:171:8:171:9 | pp |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:154:11:154:15 | p#0 |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:175:33:175:34 | pp |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:176:8:176:9 | pp |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:177:8:177:10 | * ... |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:177:9:177:10 | pp |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:181:11:181:16 | call to getenv |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:181:11:181:26 | (int)... |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:181:11:181:26 | access to array |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:182:23:182:24 | pp |
| defaulttainttracking.cpp:195:11:195:16 | call to getenv | defaulttainttracking.cpp:195:11:195:16 | call to getenv |
| defaulttainttracking.cpp:195:11:195:16 | call to getenv | defaulttainttracking.cpp:195:11:195:26 | (int)... |
| defaulttainttracking.cpp:195:11:195:16 | call to getenv | defaulttainttracking.cpp:195:11:195:26 | access to array |
| defaulttainttracking.cpp:201:13:201:18 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 |
| defaulttainttracking.cpp:201:13:201:18 | call to getenv | defaulttainttracking.cpp:201:13:201:18 | call to getenv |
| defaulttainttracking.cpp:201:13:201:18 | call to getenv | defaulttainttracking.cpp:201:13:201:28 | (int)... |
| defaulttainttracking.cpp:201:13:201:18 | call to getenv | defaulttainttracking.cpp:201:13:201:28 | access to array |
| defaulttainttracking.cpp:201:13:201:18 | call to getenv | defaulttainttracking.cpp:203:8:203:9 | pp |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:208:27:208:32 | call to getenv |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:208:27:208:42 | (int)... |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:208:27:208:42 | access to array |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:209:8:209:9 | pp |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:210:8:210:23 | ... + ... |
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:24:28:27 | call to atoi |
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:29:28:34 | call to getenv |
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:29:28:45 | (const char *)... |

View File

@@ -29,6 +29,36 @@
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:143:23:143:24 | pp | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:144:8:144:9 | pp | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:150:13:150:14 | & ... | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:154:11:154:15 | p#0 | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:162:50:162:50 | p | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:164:8:164:8 | p | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:165:8:165:9 | & ... | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:166:10:166:10 | x | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | defaulttainttracking.cpp:187:8:187:9 | pp | IR only |
| defaulttainttracking.cpp:140:11:140:16 | call to getenv | shared.h:6:15:6:23 | sinkparam | IR only |
| defaulttainttracking.cpp:157:9:157:14 | call to getenv | defaulttainttracking.cpp:157:5:157:5 | x | AST only |
| defaulttainttracking.cpp:157:9:157:14 | call to getenv | defaulttainttracking.cpp:159:10:159:10 | x | IR only |
| defaulttainttracking.cpp:157:9:157:14 | call to getenv | shared.h:6:15:6:23 | sinkparam | IR only |
| defaulttainttracking.cpp:170:11:170:16 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 | IR only |
| defaulttainttracking.cpp:170:11:170:16 | call to getenv | defaulttainttracking.cpp:170:7:170:7 | x | AST only |
| defaulttainttracking.cpp:170:11:170:16 | call to getenv | defaulttainttracking.cpp:171:8:171:9 | pp | IR only |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 | IR only |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:154:11:154:15 | p#0 | IR only |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:175:33:175:34 | pp | IR only |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:176:8:176:9 | pp | IR only |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:177:8:177:10 | * ... | IR only |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:177:9:177:10 | pp | IR only |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:181:7:181:7 | x | AST only |
| defaulttainttracking.cpp:181:11:181:16 | call to getenv | defaulttainttracking.cpp:182:23:182:24 | pp | IR only |
| defaulttainttracking.cpp:195:11:195:16 | call to getenv | defaulttainttracking.cpp:195:7:195:7 | x | AST only |
| defaulttainttracking.cpp:201:13:201:18 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 | IR only |
| defaulttainttracking.cpp:201:13:201:18 | call to getenv | defaulttainttracking.cpp:201:9:201:9 | x | AST only |
| defaulttainttracking.cpp:201:13:201:18 | call to getenv | defaulttainttracking.cpp:203:8:203:9 | pp | IR only |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:153:11:153:15 | p#0 | IR only |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:208:23:208:23 | x | AST only |
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:209:8:209:9 | pp | IR only |
| 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:62:7:62:12 | source | AST only |

View File

@@ -461,12 +461,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:172:30:172:40 | call to allocator | stl.h:172:21:172:41 | noexcept(...) | TAINT |
| stl.h:172:30:172:40 | call to allocator | stl.h:172:21:172:41 | noexcept(...) | TAINT |
| stl.h:172:30:172:40 | call to allocator | stl.h:172:21:172:41 | noexcept(...) | TAINT |
| stl.h:172:30:172:40 | call to allocator | stl.h:172:21:172:41 | noexcept(...) | TAINT |
| stl.h:172:30:172:40 | call to allocator | stl.h:172:21:172:41 | noexcept(...) | TAINT |
| stl.h:172:53:172:63 | 0 | stl.h:172:46:172:64 | (no string representation) | 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: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 |
| 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 | |
@@ -624,32 +624,32 @@
| string.cpp:153:18:153:23 | call to basic_string | string.cpp:173:8:173:9 | s3 | |
| string.cpp:154:18:154:23 | call to source | string.cpp:154:18:154:26 | call to basic_string | TAINT |
| string.cpp:154:18:154:26 | call to basic_string | string.cpp:157:13:157:14 | s4 | |
| string.cpp:154:18:154:26 | call to basic_string | string.cpp:161:9:161:10 | s4 | |
| string.cpp:154:18:154:26 | call to basic_string | string.cpp:161:14:161:15 | s4 | |
| string.cpp:154:18:154:26 | call to basic_string | string.cpp:170:13:170:14 | s4 | |
| string.cpp:157:8:157:9 | s3 | string.cpp:157:11:157:11 | call to operator+ | TAINT |
| string.cpp:157:11:157:11 | call to operator+ | string.cpp:157:3:157:14 | ... = ... | |
| string.cpp:157:11:157:11 | call to operator+ | string.cpp:158:8:158:9 | s5 | |
| string.cpp:157:13:157:14 | s4 | string.cpp:157:11:157:11 | call to operator+ | TAINT |
| string.cpp:160:8:160:9 | s3 | string.cpp:160:3:160:9 | ... = ... | |
| string.cpp:160:8:160:9 | s3 | string.cpp:161:3:161:4 | s6 | |
| string.cpp:160:8:160:9 | s3 | string.cpp:161:8:161:9 | s6 | |
| string.cpp:160:8:160:9 | s3 | string.cpp:162:8:162:9 | s6 | |
| string.cpp:161:3:161:4 | ref arg s6 | string.cpp:162:8:162:9 | s6 | |
| string.cpp:161:3:161:4 | s6 | string.cpp:161:6:161:6 | call to operator+= | TAINT |
| string.cpp:161:9:161:10 | s4 | string.cpp:161:3:161:4 | ref arg s6 | TAINT |
| string.cpp:161:9:161:10 | s4 | string.cpp:161:6:161:6 | call to operator+= | TAINT |
| string.cpp:161:8:161:9 | ref arg s6 | string.cpp:162:8:162:9 | s6 | |
| string.cpp:161:8:161:9 | s6 | string.cpp:161:11:161:11 | call to operator+= | TAINT |
| string.cpp:161:14:161:15 | s4 | string.cpp:161:8:161:9 | ref arg s6 | TAINT |
| string.cpp:161:14:161:15 | s4 | string.cpp:161:11:161:11 | call to operator+= | TAINT |
| string.cpp:164:8:164:9 | s3 | string.cpp:164:3:164:9 | ... = ... | |
| string.cpp:164:8:164:9 | s3 | string.cpp:165:3:165:4 | s7 | |
| string.cpp:164:8:164:9 | s3 | string.cpp:166:3:166:4 | s7 | |
| string.cpp:164:8:164:9 | s3 | string.cpp:165:8:165:9 | s7 | |
| string.cpp:164:8:164:9 | s3 | string.cpp:166:8:166:9 | s7 | |
| string.cpp:164:8:164:9 | s3 | string.cpp:167:8:167:9 | s7 | |
| string.cpp:165:3:165:4 | ref arg s7 | string.cpp:166:3:166:4 | s7 | |
| string.cpp:165:3:165:4 | ref arg s7 | string.cpp:167:8:167:9 | s7 | |
| string.cpp:165:3:165:4 | s7 | string.cpp:165:6:165:6 | call to operator+= | TAINT |
| string.cpp:165:9:165:14 | call to source | string.cpp:165:3:165:4 | ref arg s7 | TAINT |
| string.cpp:165:9:165:14 | call to source | string.cpp:165:6:165:6 | call to operator+= | TAINT |
| string.cpp:166:3:166:4 | ref arg s7 | string.cpp:167:8:167:9 | s7 | |
| string.cpp:166:3:166:4 | s7 | string.cpp:166:6:166:6 | call to operator+= | TAINT |
| string.cpp:166:9:166:11 | | string.cpp:166:3:166:4 | ref arg s7 | TAINT |
| string.cpp:166:9:166:11 | | string.cpp:166:6:166:6 | call to operator+= | TAINT |
| string.cpp:165:8:165:9 | ref arg s7 | string.cpp:166:8:166:9 | s7 | |
| string.cpp:165:8:165:9 | ref arg s7 | string.cpp:167:8:167:9 | s7 | |
| string.cpp:165:8:165:9 | s7 | string.cpp:165:11:165:11 | call to operator+= | TAINT |
| string.cpp:165:14:165:19 | call to source | string.cpp:165:8:165:9 | ref arg s7 | TAINT |
| string.cpp:165:14:165:19 | call to source | string.cpp:165:11:165:11 | call to operator+= | TAINT |
| string.cpp:166:8:166:9 | ref arg s7 | string.cpp:167:8:167:9 | s7 | |
| string.cpp:166:8:166:9 | s7 | string.cpp:166:11:166:11 | call to operator+= | TAINT |
| string.cpp:166:14:166:16 | | string.cpp:166:8:166:9 | ref arg s7 | TAINT |
| string.cpp:166:14:166:16 | | string.cpp:166:11:166:11 | call to operator+= | TAINT |
| string.cpp:169:8:169:9 | s3 | string.cpp:169:3:169:9 | ... = ... | |
| string.cpp:169:8:169:9 | s3 | string.cpp:170:3:170:4 | s8 | |
| string.cpp:169:8:169:9 | s3 | string.cpp:171:8:171:9 | s8 | |
@@ -1237,6 +1237,125 @@
| string.cpp:501:29:501:30 | ref arg s2 | string.cpp:504:7:504:8 | s2 | |
| string.cpp:501:29:501:30 | s2 | string.cpp:501:32:501:34 | call to end | TAINT |
| string.cpp:501:32:501:34 | call to end | string.cpp:501:17:501:37 | call to basic_string | TAINT |
| string.cpp:510:16:510:19 | aa | string.cpp:510:16:510:20 | call to basic_string | TAINT |
| string.cpp:510:16:510:20 | call to basic_string | string.cpp:512:7:512:7 | a | |
| string.cpp:510:16:510:20 | call to basic_string | string.cpp:513:7:513:7 | a | |
| string.cpp:510:16:510:20 | call to basic_string | string.cpp:514:2:514:2 | a | |
| string.cpp:510:16:510:20 | call to basic_string | string.cpp:515:7:515:7 | a | |
| string.cpp:510:16:510:20 | call to basic_string | string.cpp:516:7:516:7 | a | |
| string.cpp:512:7:512:7 | a | string.cpp:512:9:512:13 | call to front | TAINT |
| string.cpp:512:7:512:7 | ref arg a | string.cpp:513:7:513:7 | a | |
| string.cpp:512:7:512:7 | ref arg a | string.cpp:514:2:514:2 | a | |
| string.cpp:512:7:512:7 | ref arg a | string.cpp:515:7:515:7 | a | |
| string.cpp:512:7:512:7 | ref arg a | string.cpp:516:7:516:7 | a | |
| string.cpp:513:7:513:7 | a | string.cpp:513:9:513:12 | call to back | TAINT |
| string.cpp:513:7:513:7 | ref arg a | string.cpp:514:2:514:2 | a | |
| string.cpp:513:7:513:7 | ref arg a | string.cpp:515:7:515:7 | a | |
| string.cpp:513:7:513:7 | ref arg a | string.cpp:516:7:516:7 | a | |
| string.cpp:514:2:514:2 | ref arg a | string.cpp:515:7:515:7 | a | |
| string.cpp:514:2:514:2 | ref arg a | string.cpp:516:7:516:7 | a | |
| string.cpp:514:14:514:28 | call to source | string.cpp:514:2:514:2 | ref arg a | TAINT |
| string.cpp:515:7:515:7 | a | string.cpp:515:9:515:13 | call to front | TAINT |
| string.cpp:515:7:515:7 | ref arg a | string.cpp:516:7:516:7 | a | |
| string.cpp:516:7:516:7 | a | string.cpp:516:9:516:12 | call to back | TAINT |
| string.cpp:521:17:521:20 | aa | string.cpp:521:17:521:21 | call to basic_string | TAINT |
| string.cpp:521:17:521:21 | call to basic_string | string.cpp:528:9:528:9 | a | |
| string.cpp:521:17:521:21 | call to basic_string | string.cpp:532:8:532:8 | a | |
| string.cpp:522:17:522:20 | bb | string.cpp:522:17:522:21 | call to basic_string | TAINT |
| string.cpp:522:17:522:21 | call to basic_string | string.cpp:528:15:528:15 | b | |
| string.cpp:522:17:522:21 | call to basic_string | string.cpp:533:8:533:8 | b | |
| string.cpp:523:17:523:20 | cc | string.cpp:523:17:523:21 | call to basic_string | TAINT |
| string.cpp:523:17:523:21 | call to basic_string | string.cpp:529:9:529:9 | c | |
| string.cpp:523:17:523:21 | call to basic_string | string.cpp:534:8:534:8 | c | |
| string.cpp:524:17:524:20 | dd | string.cpp:524:17:524:21 | call to basic_string | TAINT |
| string.cpp:524:17:524:21 | call to basic_string | string.cpp:529:15:529:15 | d | |
| string.cpp:524:17:524:21 | call to basic_string | string.cpp:535:8:535:8 | d | |
| string.cpp:525:17:525:20 | ee | string.cpp:525:17:525:21 | call to basic_string | TAINT |
| string.cpp:525:17:525:21 | call to basic_string | string.cpp:530:10:530:10 | e | |
| string.cpp:525:17:525:21 | call to basic_string | string.cpp:536:8:536:8 | e | |
| string.cpp:526:17:526:20 | ff | string.cpp:526:17:526:21 | call to basic_string | TAINT |
| string.cpp:526:17:526:21 | call to basic_string | string.cpp:531:10:531:10 | f | |
| string.cpp:526:17:526:21 | call to basic_string | string.cpp:537:8:537:8 | f | |
| string.cpp:528:9:528:9 | a | string.cpp:528:11:528:11 | call to operator+= | TAINT |
| string.cpp:528:9:528:9 | ref arg a | string.cpp:532:8:532:8 | a | |
| string.cpp:528:15:528:15 | b | string.cpp:528:17:528:17 | call to operator+= | TAINT |
| string.cpp:528:15:528:15 | ref arg b | string.cpp:533:8:533:8 | b | |
| string.cpp:528:17:528:17 | call to operator+= | string.cpp:528:9:528:9 | ref arg a | TAINT |
| string.cpp:528:17:528:17 | call to operator+= | string.cpp:528:11:528:11 | call to operator+= | TAINT |
| string.cpp:528:20:528:23 | bb | string.cpp:528:15:528:15 | ref arg b | TAINT |
| string.cpp:528:20:528:23 | bb | string.cpp:528:17:528:17 | call to operator+= | TAINT |
| string.cpp:529:9:529:9 | c | string.cpp:529:11:529:11 | call to operator+= | TAINT |
| string.cpp:529:9:529:9 | ref arg c | string.cpp:534:8:534:8 | c | |
| string.cpp:529:15:529:15 | d | string.cpp:529:17:529:17 | call to operator+= | TAINT |
| string.cpp:529:15:529:15 | ref arg d | string.cpp:535:8:535:8 | d | |
| string.cpp:529:17:529:17 | call to operator+= | string.cpp:529:9:529:9 | ref arg c | TAINT |
| string.cpp:529:17:529:17 | call to operator+= | string.cpp:529:11:529:11 | call to operator+= | TAINT |
| string.cpp:529:20:529:25 | call to source | string.cpp:529:15:529:15 | ref arg d | TAINT |
| string.cpp:529:20:529:25 | call to source | string.cpp:529:17:529:17 | call to operator+= | TAINT |
| string.cpp:530:10:530:10 | e | string.cpp:530:12:530:12 | call to operator+= | TAINT |
| string.cpp:530:10:530:10 | ref arg e | string.cpp:536:8:536:8 | e | |
| string.cpp:530:12:530:12 | call to operator+= | string.cpp:530:21:530:21 | call to operator+= | TAINT |
| string.cpp:530:12:530:12 | ref arg call to operator+= | string.cpp:530:10:530:10 | ref arg e | TAINT |
| string.cpp:530:15:530:18 | ee | string.cpp:530:10:530:10 | ref arg e | TAINT |
| string.cpp:530:15:530:18 | ee | string.cpp:530:12:530:12 | call to operator+= | TAINT |
| string.cpp:530:24:530:29 | call to source | string.cpp:530:12:530:12 | ref arg call to operator+= | TAINT |
| string.cpp:530:24:530:29 | call to source | string.cpp:530:21:530:21 | call to operator+= | TAINT |
| string.cpp:531:10:531:10 | f | string.cpp:531:12:531:12 | call to operator+= | TAINT |
| string.cpp:531:10:531:10 | ref arg f | string.cpp:537:8:537:8 | f | |
| string.cpp:531:12:531:12 | call to operator+= | string.cpp:531:25:531:25 | call to operator+= | TAINT |
| string.cpp:531:12:531:12 | ref arg call to operator+= | string.cpp:531:10:531:10 | ref arg f | TAINT |
| string.cpp:531:15:531:20 | call to source | string.cpp:531:10:531:10 | ref arg f | TAINT |
| string.cpp:531:15:531:20 | call to source | string.cpp:531:12:531:12 | call to operator+= | TAINT |
| string.cpp:531:28:531:31 | ff | string.cpp:531:12:531:12 | ref arg call to operator+= | TAINT |
| string.cpp:531:28:531:31 | ff | string.cpp:531:25:531:25 | call to operator+= | TAINT |
| string.cpp:541:17:541:20 | aa | string.cpp:541:17:541:21 | call to basic_string | TAINT |
| string.cpp:541:17:541:21 | call to basic_string | string.cpp:548:9:548:9 | a | |
| string.cpp:541:17:541:21 | call to basic_string | string.cpp:552:8:552:8 | a | |
| string.cpp:542:17:542:20 | bb | string.cpp:542:17:542:21 | call to basic_string | TAINT |
| string.cpp:542:17:542:21 | call to basic_string | string.cpp:548:18:548:18 | b | |
| string.cpp:542:17:542:21 | call to basic_string | string.cpp:553:8:553:8 | b | |
| string.cpp:543:17:543:20 | cc | string.cpp:543:17:543:21 | call to basic_string | TAINT |
| string.cpp:543:17:543:21 | call to basic_string | string.cpp:549:9:549:9 | c | |
| string.cpp:543:17:543:21 | call to basic_string | string.cpp:554:8:554:8 | c | |
| string.cpp:544:17:544:20 | dd | string.cpp:544:17:544:21 | call to basic_string | TAINT |
| string.cpp:544:17:544:21 | call to basic_string | string.cpp:549:18:549:18 | d | |
| string.cpp:544:17:544:21 | call to basic_string | string.cpp:555:8:555:8 | d | |
| string.cpp:545:17:545:20 | ee | string.cpp:545:17:545:21 | call to basic_string | TAINT |
| string.cpp:545:17:545:21 | call to basic_string | string.cpp:550:9:550:9 | e | |
| string.cpp:545:17:545:21 | call to basic_string | string.cpp:556:8:556:8 | e | |
| string.cpp:546:17:546:20 | ff | string.cpp:546:17:546:21 | call to basic_string | TAINT |
| string.cpp:546:17:546:21 | call to basic_string | string.cpp:551:9:551:9 | f | |
| string.cpp:546:17:546:21 | call to basic_string | string.cpp:557:8:557:8 | f | |
| string.cpp:548:9:548:9 | ref arg a | string.cpp:552:8:552:8 | a | |
| string.cpp:548:18:548:18 | ref arg b | string.cpp:553:8:553:8 | b | |
| string.cpp:548:20:548:25 | call to assign | string.cpp:548:9:548:9 | ref arg a | TAINT |
| string.cpp:548:20:548:25 | call to assign | string.cpp:548:11:548:16 | call to assign | TAINT |
| string.cpp:548:27:548:30 | bb | string.cpp:548:27:548:30 | call to basic_string | TAINT |
| string.cpp:548:27:548:30 | call to basic_string | string.cpp:548:18:548:18 | ref arg b | TAINT |
| string.cpp:548:27:548:30 | call to basic_string | string.cpp:548:20:548:25 | call to assign | TAINT |
| string.cpp:549:9:549:9 | ref arg c | string.cpp:554:8:554:8 | c | |
| string.cpp:549:18:549:18 | ref arg d | string.cpp:555:8:555:8 | d | |
| string.cpp:549:20:549:25 | call to assign | string.cpp:549:9:549:9 | ref arg c | TAINT |
| string.cpp:549:20:549:25 | call to assign | string.cpp:549:11:549:16 | call to assign | TAINT |
| string.cpp:549:27:549:32 | call to source | string.cpp:549:27:549:34 | call to basic_string | TAINT |
| string.cpp:549:27:549:34 | call to basic_string | string.cpp:549:18:549:18 | ref arg d | TAINT |
| string.cpp:549:27:549:34 | call to basic_string | string.cpp:549:20:549:25 | call to assign | TAINT |
| string.cpp:550:9:550:9 | ref arg e | string.cpp:556:8:556:8 | e | |
| string.cpp:550:11:550:16 | ref arg call to assign | string.cpp:550:9:550:9 | ref arg e | TAINT |
| string.cpp:550:18:550:21 | call to basic_string | string.cpp:550:9:550:9 | ref arg e | TAINT |
| string.cpp:550:18:550:21 | call to basic_string | string.cpp:550:11:550:16 | call to assign | TAINT |
| string.cpp:550:18:550:21 | ee | string.cpp:550:18:550:21 | call to basic_string | TAINT |
| string.cpp:550:31:550:36 | call to source | string.cpp:550:31:550:38 | call to basic_string | TAINT |
| string.cpp:550:31:550:38 | call to basic_string | string.cpp:550:11:550:16 | ref arg call to assign | TAINT |
| string.cpp:550:31:550:38 | call to basic_string | string.cpp:550:24:550:29 | call to assign | TAINT |
| string.cpp:551:9:551:9 | ref arg f | string.cpp:557:8:557:8 | f | |
| string.cpp:551:11:551:16 | ref arg call to assign | string.cpp:551:9:551:9 | ref arg f | TAINT |
| string.cpp:551:18:551:23 | call to source | string.cpp:551:18:551:25 | call to basic_string | TAINT |
| string.cpp:551:18:551:25 | call to basic_string | string.cpp:551:9:551:9 | ref arg f | TAINT |
| string.cpp:551:18:551:25 | call to basic_string | string.cpp:551:11:551:16 | call to assign | TAINT |
| 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 | |

View File

@@ -91,6 +91,13 @@ namespace std
const_iterator cbegin() const;
const_iterator cend() const;
void push_back(charT c);
const charT& front() const;
charT& front();
const charT& back() const;
charT& back();
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
const_reference at(size_type n) const;

View File

@@ -158,12 +158,12 @@ void test_string_append() {
sink(s5); // tainted
s6 = s3;
s6 += s4;
sink(s6 += s4); // tainted
sink(s6); // tainted
s7 = s3;
s7 += source();
s7 += " ";
sink(s7 += source()); // tainted
sink(s7 += " "); // tainted
sink(s7); // tainted
s8 = s3;
@@ -505,3 +505,55 @@ void test_constructors_more() {
sink(s3);
sink(s4); // tainted
}
void test_string_front_back() {
std::string a("aa");
sink(a.front());
sink(a.back());
a.push_back(ns_char::source());
sink(a.front()); // [FALSE POSITIVE]
sink(a.back()); // tainted
}
void test_string_return_assign() {
{
std::string a("aa");
std::string b("bb");
std::string c("cc");
std::string d("dd");
std::string e("ee");
std::string f("ff");
sink( a += (b += "bb") );
sink( c += (d += source()) ); // tainted
sink( (e += "ee") += source() ); // tainted
sink( (f += source()) += "ff" ); // tainted
sink(a);
sink(b);
sink(c); // tainted
sink(d); // tainted
sink(e); // tainted
sink(f); // tainted
}
{
std::string a("aa");
std::string b("bb");
std::string c("cc");
std::string d("dd");
std::string e("ee");
std::string f("ff");
sink( a.assign(b.assign("bb")) );
sink( c.assign(d.assign(source())) ); // tainted
sink( e.assign("ee").assign(source()) ); // tainted
sink( f.assign(source()).assign("ff") );
sink(a);
sink(b);
sink(c); // tainted
sink(d); // tainted
sink(e); // tainted
sink(f); // [FALSE POSITIVE]
}
}

View File

@@ -67,8 +67,11 @@
| string.cpp:146:11:146:11 | call to operator+ | string.cpp:141:18:141:23 | call to source |
| string.cpp:149:11:149:11 | call to operator+ | string.cpp:149:13:149:18 | call to source |
| string.cpp:158:8:158:9 | s5 | string.cpp:154:18:154:23 | call to source |
| string.cpp:161:11:161:11 | call to operator+= | string.cpp:154:18:154:23 | call to source |
| string.cpp:162:8:162:9 | s6 | string.cpp:154:18:154:23 | call to source |
| string.cpp:167:8:167:9 | s7 | string.cpp:165:9:165:14 | call to source |
| string.cpp:165:11:165:11 | call to operator+= | string.cpp:165:14:165:19 | call to source |
| string.cpp:166:11:166:11 | call to operator+= | string.cpp:165:14:165:19 | call to source |
| string.cpp:167:8:167:9 | s7 | string.cpp:165:14:165:19 | call to source |
| string.cpp:171:8:171:9 | s8 | string.cpp:154:18:154:23 | call to source |
| string.cpp:176:8:176:9 | s9 | string.cpp:174:13:174:18 | call to source |
| string.cpp:184:8:184:10 | s10 | string.cpp:181:12:181:26 | call to source |
@@ -138,6 +141,21 @@
| string.cpp:491:8:491:9 | s6 | string.cpp:482:18:482:23 | call to source |
| string.cpp:504:7:504:8 | s2 | string.cpp:497:14:497:19 | call to source |
| string.cpp:506:7:506:8 | s4 | string.cpp:497:14:497:19 | call to source |
| string.cpp:515:9:515:13 | call to front | string.cpp:514:14:514:28 | call to source |
| string.cpp:516:9:516:12 | call to back | string.cpp:514:14:514:28 | call to source |
| string.cpp:529:11:529:11 | call to operator+= | string.cpp:529:20:529:25 | call to source |
| string.cpp:530:21:530:21 | call to operator+= | string.cpp:530:24:530:29 | call to source |
| string.cpp:531:25:531:25 | call to operator+= | string.cpp:531:15:531:20 | call to source |
| string.cpp:534:8:534:8 | c | string.cpp:529:20:529:25 | call to source |
| string.cpp:535:8:535:8 | d | string.cpp:529:20:529:25 | call to source |
| string.cpp:536:8:536:8 | e | string.cpp:530:24:530:29 | call to source |
| string.cpp:537:8:537:8 | f | string.cpp:531:15:531:20 | call to source |
| string.cpp:549:11:549:16 | call to assign | string.cpp:549:27:549:32 | call to source |
| string.cpp:550:24:550:29 | call to assign | string.cpp:550:31:550:36 | call to source |
| string.cpp:554:8:554:8 | c | string.cpp:549:27:549:32 | call to source |
| 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 |
| 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 |

View File

@@ -77,8 +77,11 @@
| string.cpp:146:11:146:11 | string.cpp:141:18:141:23 | AST only |
| string.cpp:149:11:149:11 | string.cpp:149:13:149:18 | AST only |
| string.cpp:158:8:158:9 | string.cpp:154:18:154:23 | AST only |
| string.cpp:161:11:161:11 | string.cpp:154:18:154:23 | AST only |
| string.cpp:162:8:162:9 | string.cpp:154:18:154:23 | AST only |
| string.cpp:167:8:167:9 | string.cpp:165:9:165:14 | AST only |
| string.cpp:165:11:165:11 | string.cpp:165:14:165:19 | AST only |
| string.cpp:166:11:166:11 | string.cpp:165:14:165:19 | AST only |
| string.cpp:167:8:167:9 | string.cpp:165:14:165:19 | AST only |
| string.cpp:171:8:171:9 | string.cpp:154:18:154:23 | AST only |
| string.cpp:176:8:176:9 | string.cpp:174:13:174:18 | AST only |
| string.cpp:184:8:184:10 | string.cpp:181:12:181:26 | AST only |
@@ -148,6 +151,21 @@
| string.cpp:491:8:491:9 | string.cpp:482:18:482:23 | AST only |
| string.cpp:504:7:504:8 | string.cpp:497:14:497:19 | AST only |
| string.cpp:506:7:506:8 | string.cpp:497:14:497:19 | AST only |
| string.cpp:515:9:515:13 | string.cpp:514:14:514:28 | AST only |
| string.cpp:516:9:516:12 | string.cpp:514:14:514:28 | AST only |
| string.cpp:529:11:529:11 | string.cpp:529:20:529:25 | AST only |
| string.cpp:530:21:530:21 | string.cpp:530:24:530:29 | AST only |
| string.cpp:531:25:531:25 | string.cpp:531:15:531:20 | AST only |
| string.cpp:534:8:534:8 | string.cpp:529:20:529:25 | AST only |
| string.cpp:535:8:535:8 | string.cpp:529:20:529:25 | AST only |
| string.cpp:536:8:536:8 | string.cpp:530:24:530:29 | AST only |
| string.cpp:537:8:537:8 | string.cpp:531:15:531:20 | AST only |
| string.cpp:549:11:549:16 | string.cpp:549:27:549:32 | AST only |
| string.cpp:550:24:550:29 | string.cpp:550:31:550:36 | AST only |
| string.cpp:554:8:554:8 | string.cpp:549:27:549:32 | AST only |
| 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 |
| 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 |

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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()

View File

@@ -1,4 +1,4 @@
import cpp
from Block b, int i
from BlockStmt b, int i
select b, i, b.getStmt(i)

View File

@@ -1,2 +1,7 @@
| hiding.cpp:4:17:4:18 | ii | Local variable 'ii' hides a $@. | hiding.cpp:2:12:2:13 | definition of ii | parameter of the same name |
| hiding.cpp:15:15:15:16 | kk | Local variable 'kk' hides a $@. | hiding.cpp:12:25:12:26 | definition of kk | parameter of the same name |
| hiding.cpp:28:7:28:7 | a | Local variable 'a' hides a $@. | hiding.cpp:26:21:26:21 | definition of a | parameter of the same name |
| hiding.cpp:45:7:45:7 | a | Local variable 'a' hides a $@. | hiding.cpp:43:41:43:41 | definition of a | parameter of the same name |
| hiding.cpp:64:11:64:11 | i | Local variable 'i' hides a $@. | hiding.cpp:61:20:61:20 | definition of i | parameter of the same name |
| hiding.cpp:78:7:78:10 | arg1 | Local variable 'arg1' hides a $@. | hiding.cpp:74:28:74:31 | definition of arg1 | parameter of the same name |
| hiding.cpp:79:5:79:8 | arg2 | Local variable 'arg2' hides a $@. | hiding.cpp:74:36:74:39 | definition of arg2 | parameter of the same name |

View File

@@ -1,7 +1,7 @@
void f(int ii) {
if (1) {
for(int ii = 1; ii < 10; ii++) {
for(int ii = 1; ii < 10; ii++) { // local variable hides parameter of the same name
;
}
}
@@ -12,7 +12,7 @@ namespace foo {
void f2(int ii, int kk) {
try {
for (ii = 0; ii < 3; ii++) {
int kk;
int kk; // local variable hides parameter of the same name
}
}
catch (int ee) {
@@ -21,4 +21,61 @@ namespace foo {
}
}
void myFunction(int a, int b, int c);
void myFunction(int a, int b, int _c) {
{
int a = a; // local variable hides parameter of the same name
int _b = b;
int c = _c;
// ...
}
}
template<class T>
class MyTemplateClass {
public:
void myMethod(int a, int b, int c);
};
template<class T>
void MyTemplateClass<T> :: myMethod(int a, int b, int _c) {
{
int a = a; // local variable hides parameter of the same name
int _b = b;
int c = _c;
// ...
}
}
MyTemplateClass<int> mtc_i;
void test() {
mtc_i.myMethod(0, 0, 0);
}
#define MYMACRO for (int i = 0; i < 10; i++) {}
void testMacro(int i) {
MYMACRO;
for (int i = 0; i < 10; i++) {}; // local variable hides parameter of the same name
}
#include "hiding.h"
void myClass::myCaller(void) {
this->myMethod(5, 6);
}
template <typename T>
void myClass::myMethod(int arg1, T arg2) {
{
int protoArg1;
T protoArg2;
int arg1; // local variable hides parameter of the same name
T arg2; // local variable hides parameter of the same name
}
}

View File

@@ -0,0 +1,7 @@
class myClass {
public:
template <typename T>
void myMethod(int protoArg1, T protoArg2);
void myCaller(void);
};

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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()

View File

@@ -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

View File

@@ -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()

View File

@@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
description: Add some coroutines types (@co_await, @co_yield, @stmt_co_return)
compatibility: backwards

View File

@@ -332,11 +332,12 @@ final class DeclarationWithAccessorsNode extends ElementNode {
result.(ElementNode).getElement() = declaration.(Property).getInitializer().getParent()
or
result.(ElementNode).getElement() =
rank[childIndex - 2](Element a, string file, int line, int column |
rank[childIndex - 2](Element a, string file, int line, int column, string name |
a = declaration.getAnAccessor() and
locationSortKeys(a, file, line, column)
locationSortKeys(a, file, line, column) and
name = a.toString()
|
a order by file, line, column
a order by file, line, column, name
)
}
}

View File

@@ -312,7 +312,7 @@ events.cs:
# 6| 3: [AddEventAccessor] add_MyEvent
#-----| 2: (Parameters)
# 6| 0: [Parameter] value
# 6| 3: [RemoveEventAccessor] remove_MyEvent
# 6| 4: [RemoveEventAccessor] remove_MyEvent
#-----| 2: (Parameters)
# 6| 0: [Parameter] value
# 8| 7: [InstanceConstructor] Events

View File

@@ -50,6 +50,6 @@ Assignments.cs:
# 23| 3: [AddEventAccessor] add_Event
#-----| 2: (Parameters)
# 23| 0: [Parameter] value
# 23| 3: [RemoveEventAccessor] remove_Event
# 23| 4: [RemoveEventAccessor] remove_Event
#-----| 2: (Parameters)
# 23| 0: [Parameter] value

View File

@@ -189,7 +189,7 @@ NullableRefTypes.cs:
# 48| 3: [AddEventAccessor] add_P
#-----| 2: (Parameters)
# 48| 0: [Parameter] value
# 48| 3: [RemoveEventAccessor] remove_P
# 48| 4: [RemoveEventAccessor] remove_P
#-----| 2: (Parameters)
# 48| 0: [Parameter] value
# 51| 25: [Method] Q

View File

@@ -178,7 +178,7 @@ definitions.cs:
# 101| 3: [AddEventAccessor] add_Click
#-----| 2: (Parameters)
# 101| 0: [Parameter] value
# 101| 3: [RemoveEventAccessor] remove_Click
# 101| 4: [RemoveEventAccessor] remove_Click
#-----| 2: (Parameters)
# 101| 0: [Parameter] value
# 103| 7: [Method] M
@@ -257,7 +257,7 @@ definitions.cs:
# 145| 3: [AddEventAccessor] add_EH
#-----| 2: (Parameters)
# 145| 0: [Parameter] value
# 145| 3: [RemoveEventAccessor] remove_EH
# 145| 4: [RemoveEventAccessor] remove_EH
#-----| 2: (Parameters)
# 145| 0: [Parameter] value
# 146| 5: [Method] M

View File

@@ -9,7 +9,7 @@ events.cs:
# 13| 3: [AddEventAccessor] add_Click
#-----| 2: (Parameters)
# 13| 0: [Parameter] value
# 13| 3: [RemoveEventAccessor] remove_Click
# 13| 4: [RemoveEventAccessor] remove_Click
#-----| 2: (Parameters)
# 13| 0: [Parameter] value
# 15| 6: [Method] OnClick

View File

@@ -941,7 +941,7 @@ expressions.cs:
# 229| 3: [AddEventAccessor] add_Click
#-----| 2: (Parameters)
# 229| 0: [Parameter] value
# 229| 3: [RemoveEventAccessor] remove_Click
# 229| 4: [RemoveEventAccessor] remove_Click
#-----| 2: (Parameters)
# 229| 0: [Parameter] value
# 231| 6: [Method] OnClick

View File

@@ -229,7 +229,7 @@ generics.cs:
# 37| 3: [AddEventAccessor] add_myEvent
#-----| 2: (Parameters)
# 37| 0: [Parameter] value
# 37| 3: [RemoveEventAccessor] remove_myEvent
# 37| 4: [RemoveEventAccessor] remove_myEvent
#-----| 2: (Parameters)
# 37| 0: [Parameter] value
# 39| 12: [IncrementOperator] ++

View File

@@ -36,7 +36,7 @@ Members.cs:
# 20| 3: [AddEventAccessor] add_Event
#-----| 2: (Parameters)
# 20| 0: [Parameter] value
# 20| 3: [RemoveEventAccessor] remove_Event
# 20| 4: [RemoveEventAccessor] remove_Event
#-----| 2: (Parameters)
# 20| 0: [Parameter] value
# 24| 6: [Method] Method
@@ -64,7 +64,7 @@ Members.cs:
# 32| 3: [AddEventAccessor] add_Event
#-----| 2: (Parameters)
# 32| 0: [Parameter] value
# 32| 3: [RemoveEventAccessor] remove_Event
# 32| 4: [RemoveEventAccessor] remove_Event
#-----| 2: (Parameters)
# 32| 0: [Parameter] value
# 35| 3: [Class] Class2
@@ -99,7 +99,7 @@ Members.cs:
# 43| 3: [AddEventAccessor] add_Event
#-----| 2: (Parameters)
# 43| 0: [Parameter] value
# 43| 3: [RemoveEventAccessor] remove_Event
# 43| 4: [RemoveEventAccessor] remove_Event
#-----| 2: (Parameters)
# 43| 0: [Parameter] value
# 46| 6: [Method] Method
@@ -127,7 +127,7 @@ Members.cs:
# 50| 3: [AddEventAccessor] add_Event
#-----| 2: (Parameters)
# 50| 0: [Parameter] value
# 50| 3: [RemoveEventAccessor] remove_Event
# 50| 4: [RemoveEventAccessor] remove_Event
#-----| 2: (Parameters)
# 50| 0: [Parameter] value
# 54| 4: [Interface] Interface
@@ -151,7 +151,7 @@ Members.cs:
# 59| 3: [AddEventAccessor] add_Event
#-----| 2: (Parameters)
# 59| 0: [Parameter] value
# 59| 3: [RemoveEventAccessor] remove_Event
# 59| 4: [RemoveEventAccessor] remove_Event
#-----| 2: (Parameters)
# 59| 0: [Parameter] value
# 62| 5: [Interface] Interface2
@@ -175,7 +175,7 @@ Members.cs:
# 67| 3: [AddEventAccessor] add_Event
#-----| 2: (Parameters)
# 67| 0: [Parameter] value
# 67| 3: [RemoveEventAccessor] remove_Event
# 67| 4: [RemoveEventAccessor] remove_Event
#-----| 2: (Parameters)
# 67| 0: [Parameter] value
# 71| 6: [Enum] Enum

View File

@@ -9,6 +9,6 @@
import java
from Block blk
from BlockStmt blk
where blk.getNumStmt() = 0
select blk

View File

@@ -13,5 +13,5 @@
import java
from IfStmt i
where i.getThen().(Block).getNumStmt() = 0
where i.getThen().(BlockStmt).getNumStmt() = 0
select i

View File

@@ -8,6 +8,6 @@
import java
from Block b
from BlockStmt b
where b.getNumStmt() = 1
select b

View File

@@ -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.

View File

@@ -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)."

View File

@@ -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())

View File

@@ -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

View File

@@ -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."
)
}

View File

@@ -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`.

View File

@@ -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
}
}

View File

@@ -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
)
}

View File

@@ -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()
)
}

View File

@@ -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)
}
}

View File

@@ -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)

View File

@@ -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."

View File

@@ -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."

View File

@@ -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) {

View File

@@ -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

View File

@@ -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" }
}

View File

@@ -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))

Some files were not shown because too many files have changed in this diff Show More