Merge branch 'main' into mathiasvp/make_shared_make_unique-models

This commit is contained in:
Mathias Vorreiter Pedersen
2020-09-09 20:51:56 +02:00
123 changed files with 1679 additions and 624 deletions

View File

@@ -20,8 +20,10 @@ The following changes in version 1.26 affect C/C++ analysis in all applications.
## Changes to libraries
* The QL class `Block`, denoting the `{ ... }` statement, is renamed to `BlockStmt`.
* The models library now models many taint flows through `std::array`, `std::vector`, `std::deque`, `std::list` and `std::forward_list`.
* The models library now models many more taint flows through `std::string`.
* The models library now models some taint flows through `std::ostream`.
* The models library now models some taint flows through `std::shared_ptr`, `std::unique_ptr`, `std::make_shared` and `std::make_unique`.
* The `SimpleRangeAnalysis` library now supports multiplications of the form
`e1 * e2` and `x *= e2` when `e1` and `e2` are unsigned or constant.

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,7 @@
| Incomplete URL substring sanitization (`js/incomplete-url-substring-sanitization`) | More results | This query now recognizes additional URLs when the substring check is an inclusion check. |
| Ambiguous HTML id attribute (`js/duplicate-html-id`) | Results no longer shown | Precision tag reduced to "low". The query is no longer run by default. |
| Unused loop iteration variable (`js/unused-loop-variable`) | Fewer results | This query no longer flags variables in a destructuring array assignment that are not the last variable in the destructed array. |
| Unsafe shell command constructed from library input (`js/shell-command-constructed-from-input`) | More results | This query now recognizes more commands where colon, dash, and underscore are used. |
| Unsafe jQuery plugin (`js/unsafe-jquery-plugin`) | More results | This query now detects more unsafe uses of nested option properties. |

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

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

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

@@ -33,10 +33,10 @@ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
}
/**
* Holds if `node` should be a barrier in all global taint flow configurations
* Holds if `node` should be a sanitizer in all global taint flow configurations
* but not in local taint.
*/
predicate defaultTaintBarrier(DataFlow::Node node) { none() }
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
/**
* Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding
@@ -90,10 +90,17 @@ predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeT
exists(TaintFunction f, Call call, FunctionInput inModel, FunctionOutput outModel |
call.getTarget() = f and
inModel.isReturnValueDeref() and
outModel.isQualifierObject() and
f.hasTaintFlow(inModel, outModel) and
nodeFrom.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() = call and
nodeTo.asDefiningArgument() = call.getQualifier()
f.hasTaintFlow(inModel, outModel) and
(
outModel.isQualifierObject() and
nodeTo.asDefiningArgument() = call.getQualifier()
or
exists(int argOutIndex |
outModel.isParameterDeref(argOutIndex) and
nodeTo.asDefiningArgument() = call.getArgument(argOutIndex)
)
)
)
}

View File

@@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrier(DataFlow::Node node) {
isSanitizer(node) or
defaultTaintBarrier(node)
defaultTaintSanitizer(node)
}
/** Holds if data flow into `node` is prohibited. */
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
/** Holds if data flow out of `node` is prohibited. */
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }

View File

@@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrier(DataFlow::Node node) {
isSanitizer(node) or
defaultTaintBarrier(node)
defaultTaintSanitizer(node)
}
/** Holds if data flow into `node` is prohibited. */
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
/** Holds if data flow out of `node` is prohibited. */
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }

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())
}
/**

View File

@@ -100,10 +100,10 @@ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
}
/**
* Holds if `node` should be a barrier in all global taint flow configurations
* Holds if `node` should be a sanitizer in all global taint flow configurations
* but not in local taint.
*/
predicate defaultTaintBarrier(DataFlow::Node node) { none() }
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
/**
* Holds if taint can flow from `instrIn` to `instrOut` through a call to a

View File

@@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrier(DataFlow::Node node) {
isSanitizer(node) or
defaultTaintBarrier(node)
defaultTaintSanitizer(node)
}
/** Holds if data flow into `node` is prohibited. */
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
/** Holds if data flow out of `node` is prohibited. */
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }

View File

@@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrier(DataFlow::Node node) {
isSanitizer(node) or
defaultTaintBarrier(node)
defaultTaintSanitizer(node)
}
/** Holds if data flow into `node` is prohibited. */
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
/** Holds if data flow out of `node` is prohibited. */
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }

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,7 +1,7 @@
/**
* Provides implementation classes modeling `std::string` and other
* instantiations of `std::basic_string`. See `semmle.code.cpp.models.Models`
* for usage information.
* Provides implementation classes modeling `std::string` (and other
* instantiations of `std::basic_string`) and `std::ostream`. See
* `semmle.code.cpp.models.Models` for usage information.
*/
import semmle.code.cpp.models.interfaces.Taint
@@ -287,3 +287,68 @@ class StdStringAt extends TaintFunction {
output.isQualifierObject()
}
}
/**
* The `std::basic_ostream` template class.
*/
class StdBasicOStream extends TemplateClass {
StdBasicOStream() { this.hasQualifiedName("std", "basic_ostream") }
}
/**
* The `std::ostream` function `operator<<` (defined as a member function).
*/
class StdOStreamOut extends DataFlowFunction, TaintFunction {
StdOStreamOut() { this.hasQualifiedName("std", "basic_ostream", "operator<<") }
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to return value
input.isQualifierAddress() and
output.isReturnValue()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from parameter to qualifier
input.isParameter(0) and
output.isQualifierObject()
or
// flow from parameter to return value
input.isParameter(0) and
output.isReturnValueDeref()
or
// reverse flow from returned reference to the qualifier
input.isReturnValueDeref() and
output.isQualifierObject()
}
}
/**
* The `std::ostream` function `operator<<` (defined as a non-member function).
*/
class StdOStreamOutNonMember extends DataFlowFunction, TaintFunction {
StdOStreamOutNonMember() {
this.hasQualifiedName("std", "operator<<") and
this.getUnspecifiedType().(ReferenceType).getBaseType() =
any(StdBasicOStream s).getAnInstantiation()
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// flow from first parameter to return value
input.isParameter(0) and
output.isReturnValue()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from second parameter to first parameter
input.isParameter(1) and
output.isParameterDeref(0)
or
// flow from second parameter to return value
input.isParameter(1) and
output.isReturnValueDeref()
or
// reverse flow from returned reference to the first parameter
input.isReturnValueDeref() and
output.isParameterDeref(0)
}
}

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; }
* ```
@@ -842,7 +842,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
* ```
* for (int x : xs) { y += x; }
* ```
* the result is the `Block` `{ y += x; }`.
* the result is the `BlockStmt` `{ y += x; }`.
*/
override Stmt getStmt() { result = this.getChild(5) }
@@ -1229,7 +1229,7 @@ class SwitchCase extends Stmt, @stmt_switch_case {
* DEPRECATED: use `SwitchCase.getAStmt` or `ControlFlowNode.getASuccessor`
* rather than this predicate.
*
* Gets the `Block` statement immediately following this 'switch case'
* Gets the `BlockStmt` statement immediately following this 'switch case'
* statement, if any.
*
* For example, for
@@ -1250,7 +1250,7 @@ class SwitchCase extends Stmt, @stmt_switch_case {
* the `case 7:` has result `{ x = 2; break; }`, `default:` has result
* `{ x = 3; }`, and the others have no result.
*/
deprecated Block getLabelledStmt() {
deprecated BlockStmt getLabelledStmt() {
exists(int i, Stmt parent |
this = parent.getChild(i) and
result = parent.getChild(i + 1)
@@ -1331,7 +1331,7 @@ class SwitchCase extends Stmt, @stmt_switch_case {
* `default:` has results `{ x = 3; }, `x = 4;` and `break;`.
*/
Stmt getAStmt() {
exists(Block b, int i, int j |
exists(BlockStmt b, int i, int j |
b.getStmt(i) = this and
b.getStmt(j) = result and
i < j and
@@ -1370,8 +1370,8 @@ class SwitchCase extends Stmt, @stmt_switch_case {
exists(Stmt lastStmt |
lastStmt = this.getAStmt() and
not lastStmt.getFollowingStmt() = this.getAStmt() and
if lastStmt instanceof Block
then result = lastStmt.(Block).getLastStmtIn()
if lastStmt instanceof BlockStmt
then result = lastStmt.(BlockStmt).getLastStmtIn()
else result = lastStmt
)
}
@@ -1528,7 +1528,7 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
/**
* Gets the body statement of this 'switch' statement.
*
* In almost all cases the result will be a `Block`, but there are
* In almost all cases the result will be a `BlockStmt`, but there are
* other syntactically valid constructions.
*
* For example, for
@@ -1859,7 +1859,7 @@ class FunctionTryStmt extends TryStmt {
* }
* ```
*/
class CatchBlock extends Block {
class CatchBlock extends BlockStmt {
override string getAPrimaryQlClass() { result = "CatchBlock" }
CatchBlock() { ishandler(underlyingElement(this)) }
@@ -1925,7 +1925,7 @@ class MicrosoftTryExceptStmt extends MicrosoftTryStmt {
/** Gets the expression guarding the `__except` statement. */
Expr getCondition() { result = getChild(1) }
/** Gets the `__except` statement (usually a `Block`). */
/** Gets the `__except` statement (usually a `BlockStmt`). */
Stmt getExcept() { result = getChild(2) }
override string getAPrimaryQlClass() { result = "MicrosoftTryExceptStmt" }
@@ -1949,7 +1949,7 @@ class MicrosoftTryFinallyStmt extends MicrosoftTryStmt {
override string toString() { result = "__try { ... } __finally { ... }" }
/** Gets the `__finally` statement (usually a `Block`). */
/** Gets the `__finally` statement (usually a `BlockStmt`). */
Stmt getFinally() { result = getChild(1) }
override string getAPrimaryQlClass() { result = "MicrosoftTryFinallyStmt" }
@@ -2108,7 +2108,7 @@ class VlaDeclStmt extends Stmt, @stmt_vla_decl {
* declaration statement.
*/
int getNumberOfVlaDimensionStmts() {
exists(Block b, int j |
exists(BlockStmt b, int j |
this = b.getStmt(j) and
result =
j - 1 -
@@ -2125,7 +2125,7 @@ class VlaDeclStmt extends Stmt, @stmt_vla_decl {
*/
VlaDimensionStmt getVlaDimensionStmt(int i) {
i in [0 .. this.getNumberOfVlaDimensionStmts() - 1] and
exists(Block b, int j |
exists(BlockStmt b, int j |
this = b.getStmt(j) and
result = b.getStmt(j - this.getNumberOfVlaDimensionStmts() + i)
)

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

@@ -88,14 +88,14 @@ void test_stringstream()
ss5 << t;
sink(ss1);
sink(ss2); // tainted [NOT DETECTED]
sink(ss2); // tainted
sink(ss3); // tainted [NOT DETECTED]
sink(ss4); // tainted [NOT DETECTED]
sink(ss4); // tainted
sink(ss5); // tainted [NOT DETECTED]
sink(ss1.str());
sink(ss2.str()); // tainted [NOT DETECTED]
sink(ss2.str()); // tainted
sink(ss3.str()); // tainted [NOT DETECTED]
sink(ss4.str()); // tainted [NOT DETECTED]
sink(ss4.str()); // tainted
sink(ss5.str()); // tainted [NOT DETECTED]
}

View File

@@ -197,8 +197,10 @@
| globals.cpp:23:15:23:20 | call to getenv | globals.cpp:23:15:23:20 | call to getenv |
| stl.cpp:62:25:62:30 | call to getenv | shared.h:5:23:5:31 | sinkparam |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:21:29:21:29 | s |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:43:78:43:104 | p#0 |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:43:114:43:118 | p#1 |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:62:25:62:30 | call to getenv |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:64:36:64:36 | s |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:68:8:68:8 | a |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:68:12:68:17 | call to source |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:70:16:70:21 | call to source |
@@ -209,12 +211,31 @@
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:82:16:82:21 | call to source |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:82:16:82:23 | (const char *)... |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:82:16:82:24 | call to basic_string |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:85:6:85:6 | call to operator<< |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:85:6:85:17 | (reference dereference) |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:85:9:85:14 | call to source |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:85:9:85:16 | (const char *)... |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:86:15:86:15 | call to operator<< |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:86:15:86:26 | (reference dereference) |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:86:18:86:23 | call to source |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:86:18:86:25 | (const char *)... |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:6:87:6 | call to operator<< |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:6:87:19 | (reference dereference) |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:6:87:19 | (reference to) |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:9:87:14 | call to source |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:9:87:16 | (const char *)... |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:18:87:18 | call to operator<< |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:18:87:26 | (reference dereference) |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:91:7:91:9 | (const stringstream)... |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:91:7:91:9 | (reference to) |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:91:7:91:9 | ss2 |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:93:7:93:9 | (const stringstream)... |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:93:7:93:9 | (reference to) |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:93:7:93:9 | ss4 |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:96:7:96:9 | (const basic_stringstream<char, char_traits<char>, allocator<char>>)... |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:96:7:96:9 | ss2 |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:98:7:98:9 | (const basic_stringstream<char, char_traits<char>, allocator<char>>)... |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:98:7:98:9 | ss4 |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:118:10:118:15 | call to source |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:125:16:125:28 | call to basic_string |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:125:17:125:26 | call to user_input |

View File

@@ -61,10 +61,31 @@
| defaulttainttracking.cpp:208:27:208:32 | call to getenv | defaulttainttracking.cpp:210:8:210:23 | ... + ... | IR only |
| globals.cpp:13:15:13:20 | call to getenv | globals.cpp:13:5:13:11 | global1 | AST only |
| globals.cpp:23:15:23:20 | call to getenv | globals.cpp:23:5:23:11 | global2 | AST only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:43:78:43:104 | p#0 | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:62:7:62:12 | source | AST only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:64:36:64:36 | s | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:70:16:70:24 | call to basic_string | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:82:16:82:24 | call to basic_string | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:85:6:85:6 | call to operator<< | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:85:6:85:17 | (reference dereference) | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:86:15:86:15 | call to operator<< | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:86:15:86:26 | (reference dereference) | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:6:87:6 | call to operator<< | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:6:87:19 | (reference dereference) | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:6:87:19 | (reference to) | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:9:87:16 | (const char *)... | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:18:87:18 | call to operator<< | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:18:87:26 | (reference dereference) | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:91:7:91:9 | (const stringstream)... | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:91:7:91:9 | (reference to) | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:91:7:91:9 | ss2 | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:93:7:93:9 | (const stringstream)... | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:93:7:93:9 | (reference to) | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:93:7:93:9 | ss4 | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:96:7:96:9 | (const basic_stringstream<char, char_traits<char>, allocator<char>>)... | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:96:7:96:9 | ss2 | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:98:7:98:9 | (const basic_stringstream<char, char_traits<char>, allocator<char>>)... | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:98:7:98:9 | ss4 | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:117:7:117:16 | user_input | AST only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:125:16:125:28 | call to basic_string | IR only |
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:128:9:128:13 | path2 | IR only |

View File

@@ -501,12 +501,12 @@
| standalone_iterators.cpp:51:37:51:43 | source1 | standalone_iterators.cpp:53:12:53:18 | source1 | |
| standalone_iterators.cpp:51:37:51:43 | source1 | standalone_iterators.cpp:54:14:54:20 | source1 | |
| standalone_iterators.cpp:53:12:53:18 | ref arg source1 | standalone_iterators.cpp:54:14:54:20 | source1 | |
| stl.h:179:30:179:40 | call to allocator | stl.h:179:21:179:41 | noexcept(...) | TAINT |
| stl.h:179:30:179:40 | call to allocator | stl.h:179:21:179:41 | noexcept(...) | TAINT |
| stl.h:179:30:179:40 | call to allocator | stl.h:179:21:179:41 | noexcept(...) | TAINT |
| stl.h:179:30:179:40 | call to allocator | stl.h:179:21:179:41 | noexcept(...) | TAINT |
| stl.h:179:30:179:40 | call to allocator | stl.h:179:21:179:41 | noexcept(...) | TAINT |
| stl.h:179:53:179:63 | 0 | stl.h:179:46:179:64 | (no string representation) | TAINT |
| stl.h:204:30:204:40 | call to allocator | stl.h:204:21:204:41 | noexcept(...) | TAINT |
| stl.h:204:30:204:40 | call to allocator | stl.h:204:21:204:41 | noexcept(...) | TAINT |
| stl.h:204:30:204:40 | call to allocator | stl.h:204:21:204:41 | noexcept(...) | TAINT |
| stl.h:204:30:204:40 | call to allocator | stl.h:204:21:204:41 | noexcept(...) | TAINT |
| stl.h:204:30:204:40 | call to allocator | stl.h:204:21:204:41 | noexcept(...) | TAINT |
| stl.h:204:53:204:63 | 0 | stl.h:204:46:204:64 | (no string representation) | TAINT |
| string.cpp:24:12:24:17 | call to source | string.cpp:28:7:28:7 | a | |
| string.cpp:25:16:25:20 | 123 | string.cpp:25:16:25:21 | call to basic_string | TAINT |
| string.cpp:25:16:25:21 | call to basic_string | string.cpp:29:7:29:7 | b | |
@@ -1396,44 +1396,372 @@
| string.cpp:551:35:551:38 | call to basic_string | string.cpp:551:11:551:16 | ref arg call to assign | TAINT |
| string.cpp:551:35:551:38 | call to basic_string | string.cpp:551:28:551:33 | call to assign | TAINT |
| string.cpp:551:35:551:38 | ff | string.cpp:551:35:551:38 | call to basic_string | TAINT |
| stringstream.cpp:13:20:13:22 | call to basic_stringstream | stringstream.cpp:16:2:16:4 | ss1 | |
| stringstream.cpp:13:20:13:22 | call to basic_stringstream | stringstream.cpp:22:7:22:9 | ss1 | |
| stringstream.cpp:13:20:13:22 | call to basic_stringstream | stringstream.cpp:27:7:27:9 | ss1 | |
| stringstream.cpp:13:25:13:27 | call to basic_stringstream | stringstream.cpp:17:2:17:4 | ss2 | |
| stringstream.cpp:13:25:13:27 | call to basic_stringstream | stringstream.cpp:23:7:23:9 | ss2 | |
| stringstream.cpp:13:25:13:27 | call to basic_stringstream | stringstream.cpp:28:7:28:9 | ss2 | |
| stringstream.cpp:13:30:13:32 | call to basic_stringstream | stringstream.cpp:18:2:18:4 | ss3 | |
| stringstream.cpp:13:30:13:32 | call to basic_stringstream | stringstream.cpp:24:7:24:9 | ss3 | |
| stringstream.cpp:13:30:13:32 | call to basic_stringstream | stringstream.cpp:29:7:29:9 | ss3 | |
| stringstream.cpp:13:35:13:37 | call to basic_stringstream | stringstream.cpp:19:2:19:4 | ss4 | |
| stringstream.cpp:13:35:13:37 | call to basic_stringstream | stringstream.cpp:25:7:25:9 | ss4 | |
| stringstream.cpp:13:35:13:37 | call to basic_stringstream | stringstream.cpp:30:7:30:9 | ss4 | |
| stringstream.cpp:13:40:13:42 | call to basic_stringstream | stringstream.cpp:20:2:20:4 | ss5 | |
| stringstream.cpp:13:40:13:42 | call to basic_stringstream | stringstream.cpp:26:7:26:9 | ss5 | |
| stringstream.cpp:13:40:13:42 | call to basic_stringstream | stringstream.cpp:31:7:31:9 | ss5 | |
| stringstream.cpp:14:16:14:21 | call to source | stringstream.cpp:14:16:14:24 | call to basic_string | TAINT |
| stringstream.cpp:14:16:14:24 | call to basic_string | stringstream.cpp:20:9:20:9 | t | |
| stringstream.cpp:16:2:16:4 | ref arg ss1 | stringstream.cpp:22:7:22:9 | ss1 | |
| stringstream.cpp:16:2:16:4 | ref arg ss1 | stringstream.cpp:27:7:27:9 | ss1 | |
| stringstream.cpp:17:2:17:4 | ref arg ss2 | stringstream.cpp:23:7:23:9 | ss2 | |
| stringstream.cpp:17:2:17:4 | ref arg ss2 | stringstream.cpp:28:7:28:9 | ss2 | |
| stringstream.cpp:18:2:18:4 | ref arg ss3 | stringstream.cpp:24:7:24:9 | ss3 | |
| stringstream.cpp:18:2:18:4 | ref arg ss3 | stringstream.cpp:29:7:29:9 | ss3 | |
| stringstream.cpp:19:2:19:4 | ref arg ss4 | stringstream.cpp:25:7:25:9 | ss4 | |
| stringstream.cpp:19:2:19:4 | ref arg ss4 | stringstream.cpp:30:7:30:9 | ss4 | |
| stringstream.cpp:20:2:20:4 | ref arg ss5 | stringstream.cpp:26:7:26:9 | ss5 | |
| stringstream.cpp:20:2:20:4 | ref arg ss5 | stringstream.cpp:31:7:31:9 | ss5 | |
| stringstream.cpp:34:32:34:37 | source | stringstream.cpp:39:9:39:14 | source | |
| stringstream.cpp:36:20:36:22 | call to basic_stringstream | stringstream.cpp:38:2:38:4 | ss1 | |
| stringstream.cpp:36:20:36:22 | call to basic_stringstream | stringstream.cpp:41:7:41:9 | ss1 | |
| stringstream.cpp:36:20:36:22 | call to basic_stringstream | stringstream.cpp:43:7:43:9 | ss1 | |
| stringstream.cpp:36:25:36:27 | call to basic_stringstream | stringstream.cpp:39:2:39:4 | ss2 | |
| stringstream.cpp:36:25:36:27 | call to basic_stringstream | stringstream.cpp:42:7:42:9 | ss2 | |
| stringstream.cpp:36:25:36:27 | call to basic_stringstream | stringstream.cpp:44:7:44:9 | ss2 | |
| stringstream.cpp:38:2:38:4 | ref arg ss1 | stringstream.cpp:41:7:41:9 | ss1 | |
| stringstream.cpp:38:2:38:4 | ref arg ss1 | stringstream.cpp:43:7:43:9 | ss1 | |
| stringstream.cpp:39:2:39:4 | ref arg ss2 | stringstream.cpp:42:7:42:9 | ss2 | |
| stringstream.cpp:39:2:39:4 | ref arg ss2 | stringstream.cpp:44:7:44:9 | ss2 | |
| stringstream.cpp:26:35:26:40 | amount | stringstream.cpp:64:46:64:51 | amount | |
| stringstream.cpp:28:20:28:22 | call to basic_stringstream | stringstream.cpp:31:7:31:9 | ss1 | |
| stringstream.cpp:28:20:28:22 | call to basic_stringstream | stringstream.cpp:37:7:37:9 | ss1 | |
| stringstream.cpp:28:20:28:22 | call to basic_stringstream | stringstream.cpp:42:7:42:9 | ss1 | |
| stringstream.cpp:28:25:28:27 | call to basic_stringstream | stringstream.cpp:32:7:32:9 | ss2 | |
| stringstream.cpp:28:25:28:27 | call to basic_stringstream | stringstream.cpp:38:7:38:9 | ss2 | |
| stringstream.cpp:28:25:28:27 | call to basic_stringstream | stringstream.cpp:43:7:43:9 | ss2 | |
| stringstream.cpp:28:30:28:32 | call to basic_stringstream | stringstream.cpp:33:7:33:9 | ss3 | |
| stringstream.cpp:28:30:28:32 | call to basic_stringstream | stringstream.cpp:39:7:39:9 | ss3 | |
| stringstream.cpp:28:30:28:32 | call to basic_stringstream | stringstream.cpp:44:7:44:9 | ss3 | |
| stringstream.cpp:28:35:28:37 | call to basic_stringstream | stringstream.cpp:34:7:34:9 | ss4 | |
| stringstream.cpp:28:35:28:37 | call to basic_stringstream | stringstream.cpp:40:7:40:9 | ss4 | |
| stringstream.cpp:28:35:28:37 | call to basic_stringstream | stringstream.cpp:45:7:45:9 | ss4 | |
| stringstream.cpp:28:40:28:42 | call to basic_stringstream | stringstream.cpp:35:7:35:9 | ss5 | |
| stringstream.cpp:28:40:28:42 | call to basic_stringstream | stringstream.cpp:41:7:41:9 | ss5 | |
| stringstream.cpp:28:40:28:42 | call to basic_stringstream | stringstream.cpp:46:7:46:9 | ss5 | |
| stringstream.cpp:28:45:28:47 | call to basic_stringstream | stringstream.cpp:48:2:48:4 | ss6 | |
| stringstream.cpp:28:45:28:47 | call to basic_stringstream | stringstream.cpp:49:2:49:4 | ss6 | |
| stringstream.cpp:28:45:28:47 | call to basic_stringstream | stringstream.cpp:52:7:52:9 | ss6 | |
| stringstream.cpp:28:50:28:52 | call to basic_stringstream | stringstream.cpp:50:2:50:4 | ss7 | |
| stringstream.cpp:28:50:28:52 | call to basic_stringstream | stringstream.cpp:51:2:51:4 | ss7 | |
| stringstream.cpp:28:50:28:52 | call to basic_stringstream | stringstream.cpp:53:7:53:9 | ss7 | |
| stringstream.cpp:28:55:28:57 | call to basic_stringstream | stringstream.cpp:55:7:55:9 | ss8 | |
| stringstream.cpp:28:55:28:57 | call to basic_stringstream | stringstream.cpp:58:7:58:9 | ss8 | |
| stringstream.cpp:28:60:28:62 | call to basic_stringstream | stringstream.cpp:56:7:56:9 | ss9 | |
| stringstream.cpp:28:60:28:62 | call to basic_stringstream | stringstream.cpp:59:7:59:9 | ss9 | |
| stringstream.cpp:28:65:28:68 | call to basic_stringstream | stringstream.cpp:57:7:57:10 | ss10 | |
| stringstream.cpp:28:65:28:68 | call to basic_stringstream | stringstream.cpp:60:7:60:10 | ss10 | |
| stringstream.cpp:28:71:28:74 | call to basic_stringstream | stringstream.cpp:62:7:62:10 | ss11 | |
| stringstream.cpp:28:71:28:74 | call to basic_stringstream | stringstream.cpp:65:7:65:10 | ss11 | |
| stringstream.cpp:28:77:28:80 | call to basic_stringstream | stringstream.cpp:63:7:63:10 | ss12 | |
| stringstream.cpp:28:77:28:80 | call to basic_stringstream | stringstream.cpp:66:7:66:10 | ss12 | |
| stringstream.cpp:28:83:28:86 | call to basic_stringstream | stringstream.cpp:64:7:64:10 | ss13 | |
| stringstream.cpp:28:83:28:86 | call to basic_stringstream | stringstream.cpp:67:7:67:10 | ss13 | |
| stringstream.cpp:29:16:29:21 | call to source | stringstream.cpp:29:16:29:24 | call to basic_string | TAINT |
| stringstream.cpp:29:16:29:24 | call to basic_string | stringstream.cpp:35:14:35:14 | t | |
| stringstream.cpp:31:7:31:9 | ref arg ss1 | stringstream.cpp:37:7:37:9 | ss1 | |
| stringstream.cpp:31:7:31:9 | ref arg ss1 | stringstream.cpp:42:7:42:9 | ss1 | |
| stringstream.cpp:31:7:31:9 | ss1 | stringstream.cpp:31:11:31:11 | call to operator<< | |
| stringstream.cpp:31:14:31:19 | 1234 | stringstream.cpp:31:7:31:9 | ref arg ss1 | TAINT |
| stringstream.cpp:31:14:31:19 | 1234 | stringstream.cpp:31:11:31:11 | call to operator<< | TAINT |
| stringstream.cpp:32:7:32:9 | ref arg ss2 | stringstream.cpp:38:7:38:9 | ss2 | |
| stringstream.cpp:32:7:32:9 | ref arg ss2 | stringstream.cpp:43:7:43:9 | ss2 | |
| stringstream.cpp:32:7:32:9 | ss2 | stringstream.cpp:32:11:32:11 | call to operator<< | |
| stringstream.cpp:32:14:32:19 | call to source | stringstream.cpp:32:7:32:9 | ref arg ss2 | TAINT |
| stringstream.cpp:32:14:32:19 | call to source | stringstream.cpp:32:11:32:11 | call to operator<< | TAINT |
| stringstream.cpp:33:7:33:9 | ref arg ss3 | stringstream.cpp:39:7:39:9 | ss3 | |
| stringstream.cpp:33:7:33:9 | ref arg ss3 | stringstream.cpp:44:7:44:9 | ss3 | |
| stringstream.cpp:33:7:33:9 | ss3 | stringstream.cpp:33:11:33:11 | call to operator<< | |
| stringstream.cpp:33:11:33:11 | call to operator<< | stringstream.cpp:33:20:33:20 | call to operator<< | |
| stringstream.cpp:33:11:33:11 | ref arg call to operator<< | stringstream.cpp:33:7:33:9 | ref arg ss3 | TAINT |
| stringstream.cpp:33:14:33:18 | 123 | stringstream.cpp:33:7:33:9 | ref arg ss3 | TAINT |
| stringstream.cpp:33:14:33:18 | 123 | stringstream.cpp:33:11:33:11 | call to operator<< | TAINT |
| stringstream.cpp:33:23:33:28 | call to source | stringstream.cpp:33:11:33:11 | ref arg call to operator<< | TAINT |
| stringstream.cpp:33:23:33:28 | call to source | stringstream.cpp:33:20:33:20 | call to operator<< | TAINT |
| stringstream.cpp:34:7:34:9 | ref arg ss4 | stringstream.cpp:40:7:40:9 | ss4 | |
| stringstream.cpp:34:7:34:9 | ref arg ss4 | stringstream.cpp:45:7:45:9 | ss4 | |
| stringstream.cpp:34:7:34:9 | ss4 | stringstream.cpp:34:11:34:11 | call to operator<< | |
| stringstream.cpp:34:11:34:11 | call to operator<< | stringstream.cpp:34:23:34:23 | call to operator<< | |
| stringstream.cpp:34:11:34:11 | ref arg call to operator<< | stringstream.cpp:34:7:34:9 | ref arg ss4 | TAINT |
| stringstream.cpp:34:14:34:19 | call to source | stringstream.cpp:34:7:34:9 | ref arg ss4 | TAINT |
| stringstream.cpp:34:14:34:19 | call to source | stringstream.cpp:34:11:34:11 | call to operator<< | TAINT |
| stringstream.cpp:34:26:34:30 | 456 | stringstream.cpp:34:11:34:11 | ref arg call to operator<< | TAINT |
| stringstream.cpp:34:26:34:30 | 456 | stringstream.cpp:34:23:34:23 | call to operator<< | TAINT |
| stringstream.cpp:35:7:35:9 | ref arg ss5 | stringstream.cpp:41:7:41:9 | ss5 | |
| stringstream.cpp:35:7:35:9 | ref arg ss5 | stringstream.cpp:46:7:46:9 | ss5 | |
| stringstream.cpp:35:7:35:9 | ss5 | stringstream.cpp:35:11:35:11 | call to operator<< | |
| stringstream.cpp:35:14:35:14 | t | stringstream.cpp:35:7:35:9 | ref arg ss5 | TAINT |
| stringstream.cpp:35:14:35:14 | t | stringstream.cpp:35:11:35:11 | call to operator<< | TAINT |
| stringstream.cpp:48:2:48:4 | ref arg ss6 | stringstream.cpp:49:2:49:4 | ss6 | |
| stringstream.cpp:48:2:48:4 | ref arg ss6 | stringstream.cpp:52:7:52:9 | ss6 | |
| stringstream.cpp:48:10:48:14 | abc | stringstream.cpp:48:10:48:14 | call to basic_string | TAINT |
| stringstream.cpp:49:2:49:4 | ref arg ss6 | stringstream.cpp:52:7:52:9 | ss6 | |
| stringstream.cpp:49:10:49:15 | call to source | stringstream.cpp:49:10:49:17 | call to basic_string | TAINT |
| stringstream.cpp:50:2:50:4 | ref arg ss7 | stringstream.cpp:51:2:51:4 | ss7 | |
| stringstream.cpp:50:2:50:4 | ref arg ss7 | stringstream.cpp:53:7:53:9 | ss7 | |
| stringstream.cpp:50:10:50:15 | call to source | stringstream.cpp:50:10:50:17 | call to basic_string | TAINT |
| stringstream.cpp:51:2:51:4 | ref arg ss7 | stringstream.cpp:53:7:53:9 | ss7 | |
| stringstream.cpp:51:10:51:14 | abc | stringstream.cpp:51:10:51:14 | call to basic_string | TAINT |
| stringstream.cpp:55:7:55:9 | ref arg ss8 | stringstream.cpp:58:7:58:9 | ss8 | |
| stringstream.cpp:56:7:56:9 | ref arg ss9 | stringstream.cpp:59:7:59:9 | ss9 | |
| stringstream.cpp:57:7:57:10 | ref arg ss10 | stringstream.cpp:60:7:60:10 | ss10 | |
| stringstream.cpp:62:7:62:10 | ref arg ss11 | stringstream.cpp:65:7:65:10 | ss11 | |
| stringstream.cpp:63:7:63:10 | ref arg ss12 | stringstream.cpp:66:7:66:10 | ss12 | |
| stringstream.cpp:64:7:64:10 | ref arg ss13 | stringstream.cpp:67:7:67:10 | ss13 | |
| stringstream.cpp:70:32:70:37 | source | stringstream.cpp:76:14:76:19 | source | |
| stringstream.cpp:72:20:72:22 | call to basic_stringstream | stringstream.cpp:75:7:75:9 | ss1 | |
| stringstream.cpp:72:20:72:22 | call to basic_stringstream | stringstream.cpp:77:7:77:9 | ss1 | |
| stringstream.cpp:72:20:72:22 | call to basic_stringstream | stringstream.cpp:80:7:80:9 | ss1 | |
| stringstream.cpp:72:20:72:22 | call to basic_stringstream | stringstream.cpp:82:7:82:9 | ss1 | |
| stringstream.cpp:72:25:72:27 | call to basic_stringstream | stringstream.cpp:76:7:76:9 | ss2 | |
| stringstream.cpp:72:25:72:27 | call to basic_stringstream | stringstream.cpp:78:7:78:9 | ss2 | |
| stringstream.cpp:72:25:72:27 | call to basic_stringstream | stringstream.cpp:81:7:81:9 | ss2 | |
| stringstream.cpp:72:25:72:27 | call to basic_stringstream | stringstream.cpp:83:7:83:9 | ss2 | |
| stringstream.cpp:73:10:73:11 | 0 | stringstream.cpp:77:14:77:15 | v1 | |
| stringstream.cpp:73:10:73:11 | 0 | stringstream.cpp:84:7:84:8 | v1 | |
| stringstream.cpp:73:18:73:19 | 0 | stringstream.cpp:78:14:78:15 | v2 | |
| stringstream.cpp:73:18:73:19 | 0 | stringstream.cpp:85:7:85:8 | v2 | |
| stringstream.cpp:75:7:75:9 | ref arg ss1 | stringstream.cpp:77:7:77:9 | ss1 | |
| stringstream.cpp:75:7:75:9 | ref arg ss1 | stringstream.cpp:80:7:80:9 | ss1 | |
| stringstream.cpp:75:7:75:9 | ref arg ss1 | stringstream.cpp:82:7:82:9 | ss1 | |
| stringstream.cpp:75:14:75:17 | 1234 | stringstream.cpp:75:7:75:9 | ref arg ss1 | TAINT |
| stringstream.cpp:75:14:75:17 | 1234 | stringstream.cpp:75:11:75:11 | call to operator<< | TAINT |
| stringstream.cpp:76:7:76:9 | ref arg ss2 | stringstream.cpp:78:7:78:9 | ss2 | |
| stringstream.cpp:76:7:76:9 | ref arg ss2 | stringstream.cpp:81:7:81:9 | ss2 | |
| stringstream.cpp:76:7:76:9 | ref arg ss2 | stringstream.cpp:83:7:83:9 | ss2 | |
| stringstream.cpp:76:14:76:19 | source | stringstream.cpp:76:7:76:9 | ref arg ss2 | TAINT |
| stringstream.cpp:76:14:76:19 | source | stringstream.cpp:76:11:76:11 | call to operator<< | TAINT |
| stringstream.cpp:77:7:77:9 | ref arg ss1 | stringstream.cpp:80:7:80:9 | ss1 | |
| stringstream.cpp:77:7:77:9 | ref arg ss1 | stringstream.cpp:82:7:82:9 | ss1 | |
| stringstream.cpp:77:14:77:15 | ref arg v1 | stringstream.cpp:84:7:84:8 | v1 | |
| stringstream.cpp:78:7:78:9 | ref arg ss2 | stringstream.cpp:81:7:81:9 | ss2 | |
| stringstream.cpp:78:7:78:9 | ref arg ss2 | stringstream.cpp:83:7:83:9 | ss2 | |
| stringstream.cpp:78:14:78:15 | ref arg v2 | stringstream.cpp:85:7:85:8 | v2 | |
| stringstream.cpp:90:18:90:23 | call to basic_string | stringstream.cpp:92:24:92:25 | s1 | |
| stringstream.cpp:90:19:90:23 | abc | stringstream.cpp:90:18:90:23 | call to basic_string | TAINT |
| stringstream.cpp:91:18:91:26 | call to basic_string | stringstream.cpp:93:24:93:25 | s2 | |
| stringstream.cpp:91:19:91:24 | call to source | stringstream.cpp:91:18:91:26 | call to basic_string | TAINT |
| stringstream.cpp:92:24:92:26 | call to basic_stringstream | stringstream.cpp:102:7:102:9 | ss1 | |
| stringstream.cpp:93:24:93:26 | call to basic_stringstream | stringstream.cpp:103:7:103:9 | ss2 | |
| stringstream.cpp:94:25:94:49 | call to basic_stringstream | stringstream.cpp:104:7:104:9 | ss3 | |
| stringstream.cpp:94:44:94:48 | abc | stringstream.cpp:94:44:94:48 | call to basic_string | TAINT |
| stringstream.cpp:95:25:95:52 | call to basic_stringstream | stringstream.cpp:105:7:105:9 | ss4 | |
| stringstream.cpp:95:44:95:49 | call to source | stringstream.cpp:95:44:95:51 | call to basic_string | TAINT |
| stringstream.cpp:96:20:96:22 | call to basic_stringstream | stringstream.cpp:99:7:99:9 | ss5 | |
| stringstream.cpp:96:20:96:22 | call to basic_stringstream | stringstream.cpp:106:7:106:9 | ss5 | |
| stringstream.cpp:97:20:97:22 | call to basic_stringstream | stringstream.cpp:100:7:100:9 | ss6 | |
| stringstream.cpp:97:20:97:22 | call to basic_stringstream | stringstream.cpp:107:7:107:9 | ss6 | |
| stringstream.cpp:99:7:99:9 | ref arg ss5 | stringstream.cpp:106:7:106:9 | ss5 | |
| stringstream.cpp:99:13:99:36 | call to basic_stringstream | stringstream.cpp:99:7:99:9 | ref arg ss5 | TAINT |
| stringstream.cpp:99:13:99:36 | call to basic_stringstream | stringstream.cpp:99:11:99:11 | call to operator= | TAINT |
| stringstream.cpp:99:31:99:35 | abc | stringstream.cpp:99:31:99:35 | call to basic_string | TAINT |
| stringstream.cpp:100:7:100:9 | ref arg ss6 | stringstream.cpp:107:7:107:9 | ss6 | |
| stringstream.cpp:100:13:100:39 | call to basic_stringstream | stringstream.cpp:100:7:100:9 | ref arg ss6 | TAINT |
| stringstream.cpp:100:13:100:39 | call to basic_stringstream | stringstream.cpp:100:11:100:11 | call to operator= | TAINT |
| stringstream.cpp:100:31:100:36 | call to source | stringstream.cpp:100:31:100:38 | call to basic_string | TAINT |
| stringstream.cpp:112:24:112:28 | abc | stringstream.cpp:112:24:112:28 | call to basic_string | TAINT |
| stringstream.cpp:112:24:112:29 | call to basic_stringstream | stringstream.cpp:117:2:117:4 | ss1 | |
| stringstream.cpp:112:24:112:29 | call to basic_stringstream | stringstream.cpp:120:7:120:9 | ss1 | |
| stringstream.cpp:113:24:113:29 | call to source | stringstream.cpp:113:24:113:31 | call to basic_string | TAINT |
| stringstream.cpp:113:24:113:32 | call to basic_stringstream | stringstream.cpp:117:11:117:13 | ss2 | |
| stringstream.cpp:113:24:113:32 | call to basic_stringstream | stringstream.cpp:121:7:121:9 | ss2 | |
| stringstream.cpp:114:24:114:28 | abc | stringstream.cpp:114:24:114:28 | call to basic_string | TAINT |
| stringstream.cpp:114:24:114:29 | call to basic_stringstream | stringstream.cpp:118:11:118:13 | ss3 | |
| stringstream.cpp:114:24:114:29 | call to basic_stringstream | stringstream.cpp:122:7:122:9 | ss3 | |
| stringstream.cpp:115:24:115:29 | call to source | stringstream.cpp:115:24:115:31 | call to basic_string | TAINT |
| stringstream.cpp:115:24:115:32 | call to basic_stringstream | stringstream.cpp:118:2:118:4 | ss4 | |
| stringstream.cpp:115:24:115:32 | call to basic_stringstream | stringstream.cpp:123:7:123:9 | ss4 | |
| stringstream.cpp:117:2:117:4 | ref arg ss1 | stringstream.cpp:120:7:120:9 | ss1 | |
| stringstream.cpp:117:11:117:13 | ref arg ss2 | stringstream.cpp:121:7:121:9 | ss2 | |
| stringstream.cpp:118:2:118:4 | ref arg ss4 | stringstream.cpp:123:7:123:9 | ss4 | |
| stringstream.cpp:118:11:118:13 | ref arg ss3 | stringstream.cpp:122:7:122:9 | ss3 | |
| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:142:7:142:9 | ss1 | |
| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:145:7:145:9 | ss1 | |
| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:153:7:153:9 | ss1 | |
| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:161:7:161:9 | ss1 | |
| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:163:7:163:9 | ss1 | |
| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:165:7:165:9 | ss1 | |
| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:174:12:174:14 | ss1 | |
| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:176:12:176:14 | ss1 | |
| stringstream.cpp:128:20:128:22 | call to basic_stringstream | stringstream.cpp:178:7:178:9 | ss1 | |
| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:143:7:143:9 | ss2 | |
| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:146:7:146:9 | ss2 | |
| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:147:7:147:9 | ss2 | |
| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:154:7:154:9 | ss2 | |
| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:155:7:155:9 | ss2 | |
| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:162:7:162:9 | ss2 | |
| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:164:7:164:9 | ss2 | |
| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:166:7:166:9 | ss2 | |
| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:175:12:175:14 | ss2 | |
| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:177:12:177:14 | ss2 | |
| stringstream.cpp:128:25:128:27 | call to basic_stringstream | stringstream.cpp:179:7:179:9 | ss2 | |
| stringstream.cpp:129:14:129:15 | call to basic_string | stringstream.cpp:145:14:145:15 | s1 | |
| stringstream.cpp:129:14:129:15 | call to basic_string | stringstream.cpp:148:7:148:8 | s1 | |
| stringstream.cpp:129:18:129:19 | call to basic_string | stringstream.cpp:146:14:146:15 | s2 | |
| stringstream.cpp:129:18:129:19 | call to basic_string | stringstream.cpp:149:7:149:8 | s2 | |
| stringstream.cpp:129:22:129:23 | call to basic_string | stringstream.cpp:147:14:147:15 | s3 | |
| stringstream.cpp:129:22:129:23 | call to basic_string | stringstream.cpp:150:7:150:8 | s3 | |
| stringstream.cpp:129:26:129:27 | call to basic_string | stringstream.cpp:147:20:147:21 | s4 | |
| stringstream.cpp:129:26:129:27 | call to basic_string | stringstream.cpp:151:7:151:8 | s4 | |
| stringstream.cpp:130:16:130:19 | {...} | stringstream.cpp:153:14:153:15 | b1 | |
| stringstream.cpp:130:16:130:19 | {...} | stringstream.cpp:156:7:156:8 | b1 | |
| stringstream.cpp:130:18:130:18 | 0 | stringstream.cpp:130:16:130:19 | {...} | TAINT |
| stringstream.cpp:131:16:131:19 | {...} | stringstream.cpp:154:14:154:15 | b2 | |
| stringstream.cpp:131:16:131:19 | {...} | stringstream.cpp:157:7:157:8 | b2 | |
| stringstream.cpp:131:18:131:18 | 0 | stringstream.cpp:131:16:131:19 | {...} | TAINT |
| stringstream.cpp:132:16:132:19 | {...} | stringstream.cpp:155:14:155:15 | b3 | |
| stringstream.cpp:132:16:132:19 | {...} | stringstream.cpp:158:7:158:8 | b3 | |
| stringstream.cpp:132:18:132:18 | 0 | stringstream.cpp:132:16:132:19 | {...} | TAINT |
| stringstream.cpp:133:16:133:19 | {...} | stringstream.cpp:155:20:155:21 | b4 | |
| stringstream.cpp:133:16:133:19 | {...} | stringstream.cpp:159:7:159:8 | b4 | |
| stringstream.cpp:133:18:133:18 | 0 | stringstream.cpp:133:16:133:19 | {...} | TAINT |
| stringstream.cpp:134:16:134:19 | {...} | stringstream.cpp:161:16:161:17 | b5 | |
| stringstream.cpp:134:16:134:19 | {...} | stringstream.cpp:167:7:167:8 | b5 | |
| stringstream.cpp:134:18:134:18 | 0 | stringstream.cpp:134:16:134:19 | {...} | TAINT |
| stringstream.cpp:135:16:135:19 | {...} | stringstream.cpp:162:16:162:17 | b6 | |
| stringstream.cpp:135:16:135:19 | {...} | stringstream.cpp:168:7:168:8 | b6 | |
| stringstream.cpp:135:18:135:18 | 0 | stringstream.cpp:135:16:135:19 | {...} | TAINT |
| stringstream.cpp:136:16:136:19 | {...} | stringstream.cpp:163:20:163:21 | b7 | |
| stringstream.cpp:136:16:136:19 | {...} | stringstream.cpp:169:7:169:8 | b7 | |
| stringstream.cpp:136:18:136:18 | 0 | stringstream.cpp:136:16:136:19 | {...} | TAINT |
| stringstream.cpp:137:16:137:19 | {...} | stringstream.cpp:164:20:164:21 | b8 | |
| stringstream.cpp:137:16:137:19 | {...} | stringstream.cpp:170:7:170:8 | b8 | |
| stringstream.cpp:137:18:137:18 | 0 | stringstream.cpp:137:16:137:19 | {...} | TAINT |
| stringstream.cpp:138:16:138:19 | {...} | stringstream.cpp:165:15:165:16 | b9 | |
| stringstream.cpp:138:16:138:19 | {...} | stringstream.cpp:171:7:171:8 | b9 | |
| stringstream.cpp:138:18:138:18 | 0 | stringstream.cpp:138:16:138:19 | {...} | TAINT |
| stringstream.cpp:139:17:139:20 | {...} | stringstream.cpp:166:15:166:17 | b10 | |
| stringstream.cpp:139:17:139:20 | {...} | stringstream.cpp:172:7:172:9 | b10 | |
| stringstream.cpp:139:19:139:19 | 0 | stringstream.cpp:139:17:139:20 | {...} | TAINT |
| stringstream.cpp:140:44:140:44 | 0 | stringstream.cpp:178:15:178:16 | c5 | |
| stringstream.cpp:140:44:140:44 | 0 | stringstream.cpp:184:7:184:8 | c5 | |
| stringstream.cpp:140:52:140:52 | 0 | stringstream.cpp:179:15:179:16 | c6 | |
| stringstream.cpp:140:52:140:52 | 0 | stringstream.cpp:185:7:185:8 | c6 | |
| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:145:7:145:9 | ss1 | |
| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:153:7:153:9 | ss1 | |
| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:161:7:161:9 | ss1 | |
| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:163:7:163:9 | ss1 | |
| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:165:7:165:9 | ss1 | |
| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:174:12:174:14 | ss1 | |
| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:176:12:176:14 | ss1 | |
| stringstream.cpp:142:7:142:9 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | |
| stringstream.cpp:142:7:142:9 | ss1 | stringstream.cpp:142:11:142:11 | call to operator<< | |
| stringstream.cpp:142:14:142:18 | abc | stringstream.cpp:142:7:142:9 | ref arg ss1 | TAINT |
| stringstream.cpp:142:14:142:18 | abc | stringstream.cpp:142:11:142:11 | call to operator<< | TAINT |
| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:146:7:146:9 | ss2 | |
| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:147:7:147:9 | ss2 | |
| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:154:7:154:9 | ss2 | |
| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:155:7:155:9 | ss2 | |
| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:162:7:162:9 | ss2 | |
| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:164:7:164:9 | ss2 | |
| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:166:7:166:9 | ss2 | |
| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | |
| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | |
| stringstream.cpp:143:7:143:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | |
| stringstream.cpp:143:7:143:9 | ss2 | stringstream.cpp:143:11:143:11 | call to operator<< | |
| stringstream.cpp:143:14:143:19 | call to source | stringstream.cpp:143:7:143:9 | ref arg ss2 | TAINT |
| stringstream.cpp:143:14:143:19 | call to source | stringstream.cpp:143:11:143:11 | call to operator<< | TAINT |
| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:153:7:153:9 | ss1 | |
| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:161:7:161:9 | ss1 | |
| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:163:7:163:9 | ss1 | |
| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:165:7:165:9 | ss1 | |
| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:174:12:174:14 | ss1 | |
| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:176:12:176:14 | ss1 | |
| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | |
| stringstream.cpp:145:14:145:15 | ref arg s1 | stringstream.cpp:148:7:148:8 | s1 | |
| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:147:7:147:9 | ss2 | |
| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:154:7:154:9 | ss2 | |
| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:155:7:155:9 | ss2 | |
| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:162:7:162:9 | ss2 | |
| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:164:7:164:9 | ss2 | |
| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:166:7:166:9 | ss2 | |
| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | |
| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | |
| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | |
| stringstream.cpp:146:14:146:15 | ref arg s2 | stringstream.cpp:149:7:149:8 | s2 | |
| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:154:7:154:9 | ss2 | |
| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:155:7:155:9 | ss2 | |
| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:162:7:162:9 | ss2 | |
| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:164:7:164:9 | ss2 | |
| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:166:7:166:9 | ss2 | |
| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | |
| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | |
| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | |
| stringstream.cpp:147:14:147:15 | ref arg s3 | stringstream.cpp:150:7:150:8 | s3 | |
| stringstream.cpp:147:20:147:21 | ref arg s4 | stringstream.cpp:151:7:151:8 | s4 | |
| stringstream.cpp:153:7:153:9 | ref arg ss1 | stringstream.cpp:161:7:161:9 | ss1 | |
| stringstream.cpp:153:7:153:9 | ref arg ss1 | stringstream.cpp:163:7:163:9 | ss1 | |
| stringstream.cpp:153:7:153:9 | ref arg ss1 | stringstream.cpp:165:7:165:9 | ss1 | |
| stringstream.cpp:153:7:153:9 | ref arg ss1 | stringstream.cpp:174:12:174:14 | ss1 | |
| stringstream.cpp:153:7:153:9 | ref arg ss1 | stringstream.cpp:176:12:176:14 | ss1 | |
| stringstream.cpp:153:7:153:9 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | |
| stringstream.cpp:153:14:153:15 | ref arg b1 | stringstream.cpp:156:7:156:8 | b1 | |
| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:155:7:155:9 | ss2 | |
| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:162:7:162:9 | ss2 | |
| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:164:7:164:9 | ss2 | |
| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:166:7:166:9 | ss2 | |
| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | |
| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | |
| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | |
| stringstream.cpp:154:14:154:15 | ref arg b2 | stringstream.cpp:157:7:157:8 | b2 | |
| stringstream.cpp:155:7:155:9 | ref arg ss2 | stringstream.cpp:162:7:162:9 | ss2 | |
| stringstream.cpp:155:7:155:9 | ref arg ss2 | stringstream.cpp:164:7:164:9 | ss2 | |
| stringstream.cpp:155:7:155:9 | ref arg ss2 | stringstream.cpp:166:7:166:9 | ss2 | |
| stringstream.cpp:155:7:155:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | |
| stringstream.cpp:155:7:155:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | |
| stringstream.cpp:155:7:155:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | |
| stringstream.cpp:155:14:155:15 | ref arg b3 | stringstream.cpp:158:7:158:8 | b3 | |
| stringstream.cpp:155:20:155:21 | ref arg b4 | stringstream.cpp:159:7:159:8 | b4 | |
| stringstream.cpp:156:7:156:8 | b1 | stringstream.cpp:156:7:156:8 | call to basic_string | TAINT |
| stringstream.cpp:157:7:157:8 | b2 | stringstream.cpp:157:7:157:8 | call to basic_string | TAINT |
| stringstream.cpp:158:7:158:8 | b3 | stringstream.cpp:158:7:158:8 | call to basic_string | TAINT |
| stringstream.cpp:159:7:159:8 | b4 | stringstream.cpp:159:7:159:8 | call to basic_string | TAINT |
| stringstream.cpp:161:7:161:9 | ref arg ss1 | stringstream.cpp:163:7:163:9 | ss1 | |
| stringstream.cpp:161:7:161:9 | ref arg ss1 | stringstream.cpp:165:7:165:9 | ss1 | |
| stringstream.cpp:161:7:161:9 | ref arg ss1 | stringstream.cpp:174:12:174:14 | ss1 | |
| stringstream.cpp:161:7:161:9 | ref arg ss1 | stringstream.cpp:176:12:176:14 | ss1 | |
| stringstream.cpp:161:7:161:9 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | |
| stringstream.cpp:161:16:161:17 | ref arg b5 | stringstream.cpp:167:7:167:8 | b5 | |
| stringstream.cpp:162:7:162:9 | ref arg ss2 | stringstream.cpp:164:7:164:9 | ss2 | |
| stringstream.cpp:162:7:162:9 | ref arg ss2 | stringstream.cpp:166:7:166:9 | ss2 | |
| stringstream.cpp:162:7:162:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | |
| stringstream.cpp:162:7:162:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | |
| stringstream.cpp:162:7:162:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | |
| stringstream.cpp:162:16:162:17 | ref arg b6 | stringstream.cpp:168:7:168:8 | b6 | |
| stringstream.cpp:163:7:163:9 | ref arg ss1 | stringstream.cpp:165:7:165:9 | ss1 | |
| stringstream.cpp:163:7:163:9 | ref arg ss1 | stringstream.cpp:174:12:174:14 | ss1 | |
| stringstream.cpp:163:7:163:9 | ref arg ss1 | stringstream.cpp:176:12:176:14 | ss1 | |
| stringstream.cpp:163:7:163:9 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | |
| stringstream.cpp:163:20:163:21 | ref arg b7 | stringstream.cpp:169:7:169:8 | b7 | |
| stringstream.cpp:164:7:164:9 | ref arg ss2 | stringstream.cpp:166:7:166:9 | ss2 | |
| stringstream.cpp:164:7:164:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | |
| stringstream.cpp:164:7:164:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | |
| stringstream.cpp:164:7:164:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | |
| stringstream.cpp:164:20:164:21 | ref arg b8 | stringstream.cpp:170:7:170:8 | b8 | |
| stringstream.cpp:165:7:165:9 | ref arg ss1 | stringstream.cpp:174:12:174:14 | ss1 | |
| stringstream.cpp:165:7:165:9 | ref arg ss1 | stringstream.cpp:176:12:176:14 | ss1 | |
| stringstream.cpp:165:7:165:9 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | |
| stringstream.cpp:165:15:165:16 | ref arg b9 | stringstream.cpp:171:7:171:8 | b9 | |
| stringstream.cpp:166:7:166:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | |
| stringstream.cpp:166:7:166:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | |
| stringstream.cpp:166:7:166:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | |
| stringstream.cpp:166:15:166:17 | ref arg b10 | stringstream.cpp:172:7:172:9 | b10 | |
| stringstream.cpp:167:7:167:8 | b5 | stringstream.cpp:167:7:167:8 | call to basic_string | TAINT |
| stringstream.cpp:168:7:168:8 | b6 | stringstream.cpp:168:7:168:8 | call to basic_string | TAINT |
| stringstream.cpp:169:7:169:8 | b7 | stringstream.cpp:169:7:169:8 | call to basic_string | TAINT |
| stringstream.cpp:170:7:170:8 | b8 | stringstream.cpp:170:7:170:8 | call to basic_string | TAINT |
| stringstream.cpp:171:7:171:8 | b9 | stringstream.cpp:171:7:171:8 | call to basic_string | TAINT |
| stringstream.cpp:172:7:172:9 | b10 | stringstream.cpp:172:7:172:9 | call to basic_string | TAINT |
| stringstream.cpp:174:12:174:14 | ref arg ss1 | stringstream.cpp:176:12:176:14 | ss1 | |
| stringstream.cpp:174:12:174:14 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | |
| stringstream.cpp:174:16:174:18 | call to get | stringstream.cpp:174:7:174:20 | ... = ... | |
| stringstream.cpp:174:16:174:18 | call to get | stringstream.cpp:180:7:180:8 | c1 | |
| stringstream.cpp:175:12:175:14 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | |
| stringstream.cpp:175:12:175:14 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | |
| stringstream.cpp:175:16:175:18 | call to get | stringstream.cpp:175:7:175:20 | ... = ... | |
| stringstream.cpp:175:16:175:18 | call to get | stringstream.cpp:181:7:181:8 | c2 | |
| stringstream.cpp:176:12:176:14 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | |
| stringstream.cpp:176:16:176:19 | call to peek | stringstream.cpp:176:7:176:21 | ... = ... | |
| stringstream.cpp:176:16:176:19 | call to peek | stringstream.cpp:182:7:182:8 | c3 | |
| stringstream.cpp:177:12:177:14 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | |
| stringstream.cpp:177:16:177:19 | call to peek | stringstream.cpp:177:7:177:21 | ... = ... | |
| stringstream.cpp:177:16:177:19 | call to peek | stringstream.cpp:183:7:183:8 | c4 | |
| stringstream.cpp:178:15:178:16 | ref arg c5 | stringstream.cpp:184:7:184:8 | c5 | |
| stringstream.cpp:179:15:179:16 | ref arg c6 | stringstream.cpp:185:7:185:8 | c6 | |
| stringstream.cpp:190:20:190:21 | call to basic_stringstream | stringstream.cpp:192:7:192:8 | ss | |
| stringstream.cpp:190:20:190:21 | call to basic_stringstream | stringstream.cpp:193:7:193:8 | ss | |
| stringstream.cpp:190:20:190:21 | call to basic_stringstream | stringstream.cpp:194:7:194:8 | ss | |
| stringstream.cpp:190:20:190:21 | call to basic_stringstream | stringstream.cpp:195:7:195:8 | ss | |
| stringstream.cpp:190:20:190:21 | call to basic_stringstream | stringstream.cpp:196:7:196:8 | ss | |
| stringstream.cpp:190:20:190:21 | call to basic_stringstream | stringstream.cpp:197:7:197:8 | ss | |
| stringstream.cpp:192:7:192:8 | ref arg ss | stringstream.cpp:193:7:193:8 | ss | |
| stringstream.cpp:192:7:192:8 | ref arg ss | stringstream.cpp:194:7:194:8 | ss | |
| stringstream.cpp:192:7:192:8 | ref arg ss | stringstream.cpp:195:7:195:8 | ss | |
| stringstream.cpp:192:7:192:8 | ref arg ss | stringstream.cpp:196:7:196:8 | ss | |
| stringstream.cpp:192:7:192:8 | ref arg ss | stringstream.cpp:197:7:197:8 | ss | |
| stringstream.cpp:193:7:193:8 | ref arg ss | stringstream.cpp:194:7:194:8 | ss | |
| stringstream.cpp:193:7:193:8 | ref arg ss | stringstream.cpp:195:7:195:8 | ss | |
| stringstream.cpp:193:7:193:8 | ref arg ss | stringstream.cpp:196:7:196:8 | ss | |
| stringstream.cpp:193:7:193:8 | ref arg ss | stringstream.cpp:197:7:197:8 | ss | |
| stringstream.cpp:194:7:194:8 | ref arg ss | stringstream.cpp:195:7:195:8 | ss | |
| stringstream.cpp:194:7:194:8 | ref arg ss | stringstream.cpp:196:7:196:8 | ss | |
| stringstream.cpp:194:7:194:8 | ref arg ss | stringstream.cpp:197:7:197:8 | ss | |
| stringstream.cpp:195:7:195:8 | ref arg ss | stringstream.cpp:196:7:196:8 | ss | |
| stringstream.cpp:195:7:195:8 | ref arg ss | stringstream.cpp:197:7:197:8 | ss | |
| stringstream.cpp:196:7:196:8 | ref arg ss | stringstream.cpp:197:7:197:8 | ss | |
| structlikeclass.cpp:5:7:5:7 | Unknown literal | structlikeclass.cpp:5:7:5:7 | constructor init of field v | TAINT |
| structlikeclass.cpp:5:7:5:7 | Unknown literal | structlikeclass.cpp:5:7:5:7 | constructor init of field v | TAINT |
| structlikeclass.cpp:5:7:5:7 | this | structlikeclass.cpp:5:7:5:7 | constructor init of field v [pre-this] | |

View File

@@ -132,16 +132,33 @@ namespace std
template <class charT, class traits = char_traits<charT> >
class basic_istream /*: virtual public basic_ios<charT,traits> - not needed for this test */ {
public:
basic_istream<charT,traits>& operator>>(int& n);
using char_type = charT;
using int_type = int; //typename traits::int_type;
basic_istream<charT, traits>& operator>>(int& n);
int_type get();
basic_istream<charT, traits>& get(char_type& c);
basic_istream<charT, traits>& get(char_type* s, streamsize n);
int_type peek();
basic_istream<charT, traits>& read (char_type* s, streamsize n);
streamsize readsome(char_type* s, streamsize n);
basic_istream<charT, traits>& putback(char_type c);
};
template<class charT, class traits> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>&, charT*);
template<class charT, class traits, class Allocator> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
template <class charT, class traits = char_traits<charT> >
class basic_ostream /*: virtual public basic_ios<charT,traits> - not needed for this test */ {
public:
typedef charT char_type;
basic_ostream<charT,traits>& write(const char_type* s, streamsize n);
basic_ostream<charT, traits>& operator<<(int n);
basic_ostream<charT, traits>& put(char_type c);
basic_ostream<charT, traits>& write(const char_type* s, streamsize n);
};
template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const charT*);
@@ -156,8 +173,16 @@ namespace std
class basic_stringstream : public basic_iostream<charT, traits> {
public:
explicit basic_stringstream(/*ios_base::openmode which = ios_base::out|ios_base::in - not needed for this test*/);
explicit basic_stringstream( const basic_string<charT, traits, Allocator>& str/*, ios_base::openmode which = ios_base::out | ios_base::in*/);
basic_stringstream(const basic_stringstream& rhs) = delete;
basic_stringstream(basic_stringstream&& rhs);
basic_stringstream& operator=(const basic_stringstream& rhs) = delete;
basic_stringstream& operator=(basic_stringstream&& rhs);
void swap(basic_stringstream& rhs);
basic_string<charT, traits, Allocator> str() const;
void str(const basic_string<charT, traits, Allocator>& str);
};
using stringstream = basic_stringstream<char>;

View File

@@ -5,41 +5,194 @@ using namespace std;
char *source();
void sink(const std::string &s) {};
void sink(const std::stringstream &s) {};
void test_stringstream()
namespace ns_char
{
std::stringstream ss1, ss2, ss3, ss4, ss5;
char source();
}
void sink(int i) {};
void sink(const std::string &s) {};
template<class charT>
void sink(const std::basic_ostream<charT> &s) {};
template<class charT>
void sink(const std::basic_istream<charT> &s) {};
template<class charT>
void sink(const std::basic_iostream<charT> &s) {};
void test_stringstream_string(int amount)
{
std::stringstream ss1, ss2, ss3, ss4, ss5, ss6, ss7, ss8, ss9, ss10, ss11, ss12, ss13;
std::string t(source());
ss1 << "1234";
ss2 << source();
ss3 << "123" << source();
ss4 << source() << "456";
ss5 << t;
sink(ss1 << "1234");
sink(ss2 << source()); // tainted
sink(ss3 << "123" << source()); // tainted
sink(ss4 << source() << "456"); // tainted
sink(ss5 << t); // tainted
sink(ss1);
sink(ss2); // tainted [NOT DETECTED]
sink(ss3); // tainted [NOT DETECTED]
sink(ss4); // tainted [NOT DETECTED]
sink(ss5); // tainted [NOT DETECTED]
sink(ss2); // tainted
sink(ss3); // tainted
sink(ss4); // tainted
sink(ss5); // tainted
sink(ss1.str());
sink(ss2.str()); // tainted [NOT DETECTED]
sink(ss3.str()); // tainted [NOT DETECTED]
sink(ss4.str()); // tainted [NOT DETECTED]
sink(ss5.str()); // tainted [NOT DETECTED]
ss6.str("abc");
ss6.str(source()); // (overwrites)
ss7.str(source());
ss7.str("abc"); // (overwrites)
sink(ss6); // tainted [NOT DETECTED]
sink(ss7);
sink(ss8.put('a'));
sink(ss9.put(ns_char::source())); // tainted [NOT DETECTED]
sink(ss10.put('a').put(ns_char::source()).put('z')); // tainted [NOT DETECTED]
sink(ss8);
sink(ss9); // tainted [NOT DETECTED]
sink(ss10); // tainted [NOT DETECTED]
sink(ss11.write("begin", 5));
sink(ss12.write(source(), 5)); // tainted [NOT DETECTED]
sink(ss13.write("begin", 5).write(source(), amount).write("end", 3)); // tainted [NOT DETECTED]
sink(ss11);
sink(ss12); // tainted [NOT DETECTED]
sink(ss13); // tainted [NOT DETECTED]
}
void test_stringstream_int(int source)
{
std::stringstream ss1, ss2;
int v1 = 0, v2 = 0;
ss1 << 1234;
ss2 << source;
sink(ss1 << 1234);
sink(ss2 << source); // tainted
sink(ss1 >> v1);
sink(ss2 >> v2); // tainted [NOT DETECTED]
sink(ss1);
sink(ss2); // tainted
sink(ss1.str());
sink(ss2.str()); // tainted [NOT DETECTED]
sink(v1);
sink(v2); // tainted [NOT DETECTED]
}
void test_stringstream_constructors()
{
std::string s1 = "abc";
std::string s2 = source();
std::stringstream ss1(s1);
std::stringstream ss2(s2);
std::stringstream ss3 = std::stringstream("abc");
std::stringstream ss4 = std::stringstream(source());
std::stringstream ss5;
std::stringstream ss6;
sink(ss5 = std::stringstream("abc"));
sink(ss6 = std::stringstream(source())); // tainted [NOT DETECTED]
sink(ss1);
sink(ss2); // tainted [NOT DETECTED]
sink(ss1.str());
sink(ss2.str()); // tainted [NOT DETECTED]
sink(ss3);
sink(ss4); // tainted [NOT DETECTED]
sink(ss5);
sink(ss6); // tainted [NOT DETECTED]
}
void test_stringstream_swap()
{
std::stringstream ss1("abc");
std::stringstream ss2(source());
std::stringstream ss3("abc");
std::stringstream ss4(source());
ss1.swap(ss2);
ss4.swap(ss3);
sink(ss1); // tainted [NOT DETECTED]
sink(ss2);
sink(ss3); // tainted [NOT DETECTED]
sink(ss4);
}
void test_stringstream_in()
{
std::stringstream ss1, ss2;
std::string s1, s2, s3, s4;
char b1[100] = {0};
char b2[100] = {0};
char b3[100] = {0};
char b4[100] = {0};
char b5[100] = {0};
char b6[100] = {0};
char b7[100] = {0};
char b8[100] = {0};
char b9[100] = {0};
char b10[100] = {0};
char c1 = 0, c2 = 0, c3 = 0, c4 = 0, c5 = 0, c6 = 0;
sink(ss1 << "abc");
sink(ss2 << source()); // tainted
sink(ss1 >> s1);
sink(ss2 >> s2); // tainted [NOT DETECTED]
sink(ss2 >> s3 >> s4); // tainted [NOT DETECTED]
sink(s1);
sink(s2); // tainted [NOT DETECTED]
sink(s3); // tainted [NOT DETECTED]
sink(s4); // tainted [NOT DETECTED]
sink(ss1 >> b1);
sink(ss2 >> b2);
sink(ss2 >> b3 >> b4);
sink(b1);
sink(b2); // tainted [NOT DETECTED]
sink(b3); // tainted [NOT DETECTED]
sink(b4); // tainted [NOT DETECTED]
sink(ss1.read(b5, 100));
sink(ss2.read(b6, 100)); // tainted [NOT DETECTED]
sink(ss1.readsome(b7, 100));
sink(ss2.readsome(b8, 100)); // (returns a length, not significantly tainted)
sink(ss1.get(b9, 100));
sink(ss2.get(b10, 100));
sink(b5);
sink(b6); // tainted [NOT DETECTED]
sink(b7);
sink(b8); // tainted [NOT DETECTED]
sink(b9);
sink(b10); // tainted [NOT DETECTED]
sink(c1 = ss1.get());
sink(c2 = ss2.get()); // tainted [NOT DETECTED]
sink(c3 = ss1.peek());
sink(c4 = ss2.peek()); // tainted [NOT DETECTED]
sink(ss1.get(c5));
sink(ss2.get(c6)); // tainted [NOT DETECTED]
sink(c1);
sink(c2); // tainted [NOT DETECTED]
sink(c3);
sink(c4); // tainted [NOT DETECTED]
sink(c5);
sink(c6); // tainted [NOT DETECTED]
}
void test_stringstream_putback()
{
std::stringstream ss;
sink(ss.put('a'));
sink(ss.get());
sink(ss.putback('b'));
sink(ss.get());
sink(ss.putback(ns_char::source())); // tainted [NOT DETECTED]
sink(ss.get()); // tainted [NOT DETECTED]
}

View File

@@ -162,6 +162,17 @@
| string.cpp:555:8:555:8 | d | string.cpp:549:27:549:32 | call to source |
| string.cpp:556:8:556:8 | e | string.cpp:550:31:550:36 | call to source |
| string.cpp:557:8:557:8 | f | string.cpp:551:18:551:23 | call to source |
| stringstream.cpp:32:11:32:11 | call to operator<< | stringstream.cpp:32:14:32:19 | call to source |
| stringstream.cpp:33:20:33:20 | call to operator<< | stringstream.cpp:33:23:33:28 | call to source |
| stringstream.cpp:34:23:34:23 | call to operator<< | stringstream.cpp:34:14:34:19 | call to source |
| stringstream.cpp:35:11:35:11 | call to operator<< | stringstream.cpp:29:16:29:21 | call to source |
| stringstream.cpp:38:7:38:9 | ss2 | stringstream.cpp:32:14:32:19 | call to source |
| stringstream.cpp:39:7:39:9 | ss3 | stringstream.cpp:33:23:33:28 | call to source |
| stringstream.cpp:40:7:40:9 | ss4 | stringstream.cpp:34:14:34:19 | call to source |
| stringstream.cpp:41:7:41:9 | ss5 | stringstream.cpp:29:16:29:21 | call to source |
| stringstream.cpp:76:11:76:11 | call to operator<< | stringstream.cpp:70:32:70:37 | source |
| stringstream.cpp:81:7:81:9 | ss2 | stringstream.cpp:70:32:70:37 | source |
| stringstream.cpp:143:11:143:11 | call to operator<< | stringstream.cpp:143:14:143:19 | call to source |
| structlikeclass.cpp:35:8:35:9 | s1 | structlikeclass.cpp:29:22:29:27 | call to source |
| structlikeclass.cpp:36:8:36:9 | s2 | structlikeclass.cpp:30:24:30:29 | call to source |
| structlikeclass.cpp:37:8:37:9 | s3 | structlikeclass.cpp:29:22:29:27 | call to source |

View File

@@ -172,6 +172,25 @@
| string.cpp:555:8:555:8 | string.cpp:549:27:549:32 | AST only |
| string.cpp:556:8:556:8 | string.cpp:550:31:550:36 | AST only |
| string.cpp:557:8:557:8 | string.cpp:551:18:551:23 | AST only |
| stringstream.cpp:32:11:32:11 | stringstream.cpp:32:14:32:21 | IR only |
| stringstream.cpp:32:11:32:22 | stringstream.cpp:32:14:32:19 | IR only |
| stringstream.cpp:32:11:32:22 | stringstream.cpp:32:14:32:21 | IR only |
| stringstream.cpp:33:20:33:20 | stringstream.cpp:33:23:33:30 | IR only |
| stringstream.cpp:33:20:33:31 | stringstream.cpp:33:23:33:28 | IR only |
| stringstream.cpp:33:20:33:31 | stringstream.cpp:33:23:33:30 | IR only |
| stringstream.cpp:34:23:34:23 | stringstream.cpp:34:14:34:21 | IR only |
| stringstream.cpp:34:23:34:31 | stringstream.cpp:34:14:34:19 | IR only |
| stringstream.cpp:34:23:34:31 | stringstream.cpp:34:14:34:21 | IR only |
| stringstream.cpp:35:11:35:11 | stringstream.cpp:29:16:29:21 | AST only |
| stringstream.cpp:38:7:38:9 | stringstream.cpp:32:14:32:19 | AST only |
| stringstream.cpp:39:7:39:9 | stringstream.cpp:33:23:33:28 | AST only |
| stringstream.cpp:40:7:40:9 | stringstream.cpp:34:14:34:19 | AST only |
| stringstream.cpp:41:7:41:9 | stringstream.cpp:29:16:29:21 | AST only |
| stringstream.cpp:76:11:76:11 | stringstream.cpp:70:32:70:37 | AST only |
| stringstream.cpp:81:7:81:9 | stringstream.cpp:70:32:70:37 | AST only |
| stringstream.cpp:143:11:143:11 | stringstream.cpp:143:14:143:21 | IR only |
| stringstream.cpp:143:11:143:22 | stringstream.cpp:143:14:143:19 | IR only |
| stringstream.cpp:143:11:143:22 | stringstream.cpp:143:14:143:21 | IR only |
| structlikeclass.cpp:35:8:35:9 | structlikeclass.cpp:29:22:29:27 | AST only |
| structlikeclass.cpp:36:8:36:9 | structlikeclass.cpp:30:24:30:29 | AST only |
| structlikeclass.cpp:37:8:37:9 | structlikeclass.cpp:29:22:29:27 | AST only |

View File

@@ -24,6 +24,38 @@
| string.cpp:28:7:28:7 | a | string.cpp:24:12:24:17 | call to source |
| string.cpp:55:7:55:8 | cs | string.cpp:50:19:50:24 | call to source |
| string.cpp:55:7:55:8 | cs | string.cpp:50:19:50:26 | (const char *)... |
| stringstream.cpp:32:11:32:11 | call to operator<< | stringstream.cpp:32:14:32:19 | call to source |
| stringstream.cpp:32:11:32:11 | call to operator<< | stringstream.cpp:32:14:32:21 | (const char *)... |
| stringstream.cpp:32:11:32:22 | (const basic_ostream<char, char_traits<char>>)... | stringstream.cpp:32:14:32:19 | call to source |
| stringstream.cpp:32:11:32:22 | (const basic_ostream<char, char_traits<char>>)... | stringstream.cpp:32:14:32:21 | (const char *)... |
| stringstream.cpp:32:11:32:22 | (reference dereference) | stringstream.cpp:32:14:32:19 | call to source |
| stringstream.cpp:32:11:32:22 | (reference dereference) | stringstream.cpp:32:14:32:21 | (const char *)... |
| stringstream.cpp:32:11:32:22 | (reference to) | stringstream.cpp:32:14:32:19 | call to source |
| stringstream.cpp:32:11:32:22 | (reference to) | stringstream.cpp:32:14:32:21 | (const char *)... |
| stringstream.cpp:33:20:33:20 | call to operator<< | stringstream.cpp:33:23:33:28 | call to source |
| stringstream.cpp:33:20:33:20 | call to operator<< | stringstream.cpp:33:23:33:30 | (const char *)... |
| stringstream.cpp:33:20:33:31 | (const basic_ostream<char, char_traits<char>>)... | stringstream.cpp:33:23:33:28 | call to source |
| stringstream.cpp:33:20:33:31 | (const basic_ostream<char, char_traits<char>>)... | stringstream.cpp:33:23:33:30 | (const char *)... |
| stringstream.cpp:33:20:33:31 | (reference dereference) | stringstream.cpp:33:23:33:28 | call to source |
| stringstream.cpp:33:20:33:31 | (reference dereference) | stringstream.cpp:33:23:33:30 | (const char *)... |
| stringstream.cpp:33:20:33:31 | (reference to) | stringstream.cpp:33:23:33:28 | call to source |
| stringstream.cpp:33:20:33:31 | (reference to) | stringstream.cpp:33:23:33:30 | (const char *)... |
| stringstream.cpp:34:23:34:23 | call to operator<< | stringstream.cpp:34:14:34:19 | call to source |
| stringstream.cpp:34:23:34:23 | call to operator<< | stringstream.cpp:34:14:34:21 | (const char *)... |
| stringstream.cpp:34:23:34:31 | (const basic_ostream<char, char_traits<char>>)... | stringstream.cpp:34:14:34:19 | call to source |
| stringstream.cpp:34:23:34:31 | (const basic_ostream<char, char_traits<char>>)... | stringstream.cpp:34:14:34:21 | (const char *)... |
| stringstream.cpp:34:23:34:31 | (reference dereference) | stringstream.cpp:34:14:34:19 | call to source |
| stringstream.cpp:34:23:34:31 | (reference dereference) | stringstream.cpp:34:14:34:21 | (const char *)... |
| stringstream.cpp:34:23:34:31 | (reference to) | stringstream.cpp:34:14:34:19 | call to source |
| stringstream.cpp:34:23:34:31 | (reference to) | stringstream.cpp:34:14:34:21 | (const char *)... |
| stringstream.cpp:143:11:143:11 | call to operator<< | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:143:11:143:11 | call to operator<< | stringstream.cpp:143:14:143:21 | (const char *)... |
| stringstream.cpp:143:11:143:22 | (const basic_ostream<char, char_traits<char>>)... | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:143:11:143:22 | (const basic_ostream<char, char_traits<char>>)... | stringstream.cpp:143:14:143:21 | (const char *)... |
| stringstream.cpp:143:11:143:22 | (reference dereference) | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:143:11:143:22 | (reference dereference) | stringstream.cpp:143:14:143:21 | (const char *)... |
| stringstream.cpp:143:11:143:22 | (reference to) | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:143:11:143:22 | (reference to) | stringstream.cpp:143:14:143:21 | (const char *)... |
| structlikeclass.cpp:38:8:38:9 | s4 | structlikeclass.cpp:33:8:33:13 | call to source |
| structlikeclass.cpp:61:8:61:9 | s2 | structlikeclass.cpp:58:24:58:29 | call to source |
| structlikeclass.cpp:62:8:62:20 | ... = ... | structlikeclass.cpp:62:13:62:18 | call to source |

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

View File

@@ -88,7 +88,7 @@ namespace Semmle.BuildAnalyser
nuget = new NugetPackages(sourceDir.FullName, PackageDirectory);
ReadNugetFiles();
}
catch(FileNotFoundException)
catch (FileNotFoundException)
{
progressMonitor.MissingNuGet();
}
@@ -97,7 +97,9 @@ namespace Semmle.BuildAnalyser
// Find DLLs in the .Net Framework
if (options.ScanNetFrameworkDlls)
{
dllDirNames.Add(Runtime.Runtimes.First());
var runtimeLocation = Runtime.GetRuntime(options.UseSelfContainedDotnet);
progressMonitor.Log(Util.Logging.Severity.Debug, $"Runtime location selected: {runtimeLocation}");
dllDirNames.Add(runtimeLocation);
}
// These files can sometimes prevent `dotnet restore` from working correctly.
@@ -279,7 +281,7 @@ namespace Semmle.BuildAnalyser
void AnalyseProject(FileInfo project)
{
if(!project.Exists)
if (!project.Exists)
{
progressMonitor.MissingProject(project.FullName);
return;
@@ -323,7 +325,7 @@ namespace Semmle.BuildAnalyser
void Restore(string projectOrSolution)
{
int exit = DotNet.RestoreToDirectory(projectOrSolution, PackageDirectory.DirInfo.FullName);
switch(exit)
switch (exit)
{
case 0:
case 1:
@@ -342,7 +344,7 @@ namespace Semmle.BuildAnalyser
public void AnalyseSolutions(IEnumerable<string> solutions)
{
Parallel.ForEach(solutions, new ParallelOptions { MaxDegreeOfParallelism = 4 } , solutionFile =>
Parallel.ForEach(solutions, new ParallelOptions { MaxDegreeOfParallelism = 4 }, solutionFile =>
{
try
{

View File

@@ -13,7 +13,7 @@ namespace Semmle.Extraction.CSharp.Standalone
{
public override bool handleFlag(string key, bool value)
{
switch(key)
switch (key)
{
case "silent":
Verbosity = value ? Verbosity.Off : Verbosity.Info;
@@ -36,6 +36,9 @@ namespace Semmle.Extraction.CSharp.Standalone
case "skip-dotnet":
ScanNetFrameworkDlls = !value;
return true;
case "self-contained-dotnet":
UseSelfContainedDotnet = value;
return true;
default:
return base.handleFlag(key, value);
}
@@ -43,7 +46,7 @@ namespace Semmle.Extraction.CSharp.Standalone
public override bool handleOption(string key, string value)
{
switch(key)
switch (key)
{
case "exclude":
Excludes.Add(value);
@@ -134,6 +137,11 @@ namespace Semmle.Extraction.CSharp.Standalone
/// </summary>
public bool Help = false;
/// <summary>
/// Whether to use the packaged dotnet runtime.
/// </summary>
public bool UseSelfContainedDotnet = false;
/// <summary>
/// Determine whether the given path should be excluded.
/// </summary>
@@ -162,6 +170,7 @@ namespace Semmle.Extraction.CSharp.Standalone
output.WriteLine(" --threads:nnn Specify number of threads (default=CPU cores)");
output.WriteLine(" --verbose Produce more output");
output.WriteLine(" --pdb Cross-reference information from PDBs where available");
output.WriteLine(" --self-contained-dotnet Use the .Net Framework packaged with the extractor");
}
private Options()

View File

@@ -16,7 +16,7 @@ namespace Semmle.BuildAnalyser
void NugetInstall(string package);
void ResolvedReference(string filename);
void Summary(int existingSources, int usedSources, int missingSources, int references, int unresolvedReferences, int resolvedConflicts, int totalProjects, int failedProjects, TimeSpan analysisTime);
void Warning(string message);
void Log(Severity severity, string message);
void ResolvedConflict(string asm1, string asm2);
void MissingProject(string projectFile);
void CommandFailed(string exe, string arguments, int exitCode);
@@ -93,9 +93,9 @@ namespace Semmle.BuildAnalyser
logger.Log(Severity.Info, "Build analysis completed in {0}", analysisTime);
}
public void Warning(string message)
public void Log(Severity severity, string message)
{
logger.Log(Severity.Warning, message);
logger.Log(severity, message);
}
public void ResolvedConflict(string asm1, string asm2)

View File

@@ -17,7 +17,7 @@ namespace Semmle.Extraction.CSharp.Standalone
/// <summary>
/// Locates .NET Core Runtimes.
/// </summary>
public static IEnumerable<string> CoreRuntimes
private static IEnumerable<string> CoreRuntimes
{
get
{
@@ -37,7 +37,7 @@ namespace Semmle.Extraction.CSharp.Standalone
/// Locates .NET Desktop Runtimes.
/// This includes Mono and Microsoft.NET.
/// </summary>
public static IEnumerable<string> DesktopRuntimes
private static IEnumerable<string> DesktopRuntimes
{
get
{
@@ -63,7 +63,12 @@ namespace Semmle.Extraction.CSharp.Standalone
}
}
public static IEnumerable<string> Runtimes
/// <summary>
/// Gets the .NET runtime location to use for extraction
/// </summary>
public static string GetRuntime(bool useSelfContained) => useSelfContained ? ExecutingRuntime : Runtimes.First();
private static IEnumerable<string> Runtimes
{
get
{

View File

@@ -14,10 +14,10 @@ private import semmle.code.csharp.frameworks.JsonNET
private import semmle.code.csharp.frameworks.WCF
/**
* Holds if `node` should be a barrier in all global taint flow configurations
* Holds if `node` should be a sanitizer in all global taint flow configurations
* but not in local taint.
*/
predicate defaultTaintBarrier(DataFlow::Node node) { none() }
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
deprecated predicate localAdditionalTaintStep = defaultAdditionalTaintStep/2;

View File

@@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrier(DataFlow::Node node) {
isSanitizer(node) or
defaultTaintBarrier(node)
defaultTaintSanitizer(node)
}
/** Holds if data flow into `node` is prohibited. */
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
/** Holds if data flow out of `node` is prohibited. */
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }

View File

@@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrier(DataFlow::Node node) {
isSanitizer(node) or
defaultTaintBarrier(node)
defaultTaintSanitizer(node)
}
/** Holds if data flow into `node` is prohibited. */
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
/** Holds if data flow out of `node` is prohibited. */
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }

View File

@@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrier(DataFlow::Node node) {
isSanitizer(node) or
defaultTaintBarrier(node)
defaultTaintSanitizer(node)
}
/** Holds if data flow into `node` is prohibited. */
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
/** Holds if data flow out of `node` is prohibited. */
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }

View File

@@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrier(DataFlow::Node node) {
isSanitizer(node) or
defaultTaintBarrier(node)
defaultTaintSanitizer(node)
}
/** Holds if data flow into `node` is prohibited. */
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
/** Holds if data flow out of `node` is prohibited. */
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }

View File

@@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrier(DataFlow::Node node) {
isSanitizer(node) or
defaultTaintBarrier(node)
defaultTaintSanitizer(node)
}
/** Holds if data flow into `node` is prohibited. */
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
/** Holds if data flow out of `node` is prohibited. */
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }

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

View File

@@ -1022,7 +1022,7 @@ class LambdaExpr extends FunctionalExpr, @lambdaexpr {
}
/** Gets the body of this lambda expression, if it is a statement. */
Block getStmtBody() { hasStmtBody() and result = asMethod().getBody() }
BlockStmt getStmtBody() { hasStmtBody() and result = asMethod().getBody() }
/** Gets a printable representation of this expression. */
override string toString() { result = "...->..." }

View File

@@ -215,7 +215,7 @@ class Callable extends StmtParent, Member, @callable {
Call getAReference() { result.getCallee() = this }
/** Gets the body of this callable, if any. */
Block getBody() { result.getParent() = this }
BlockStmt getBody() { result.getParent() = this }
/**
* Gets the source declaration of this callable.

View File

@@ -469,7 +469,7 @@ private class PpWildcardTypeAccess extends PpAst, WildcardTypeAccess {
* Statements
*/
private class PpBlock extends PpAst, Block {
private class PpBlock extends PpAst, BlockStmt {
override string getPart(int i) {
i = 0 and result = "{"
or
@@ -493,26 +493,26 @@ private class PpIfStmt extends PpAst, IfStmt {
or
i = 2 and result = ")"
or
i = 3 and result = " " and this.getThen() instanceof Block
i = 3 and result = " " and this.getThen() instanceof BlockStmt
or
exists(this.getElse()) and
(
i = 5 and result = " " and this.getThen() instanceof Block
i = 5 and result = " " and this.getThen() instanceof BlockStmt
or
i = 6 and result = "else"
or
i = 7 and result = " " and this.getElse() instanceof Block
i = 7 and result = " " and this.getElse() instanceof BlockStmt
)
}
override predicate newline(int i) {
i = 3 and not this.getThen() instanceof Block
i = 3 and not this.getThen() instanceof BlockStmt
or
exists(this.getElse()) and
(
i = 5 and not this.getThen() instanceof Block
i = 5 and not this.getThen() instanceof BlockStmt
or
i = 7 and not this.getElse() instanceof Block
i = 7 and not this.getElse() instanceof BlockStmt
)
}
@@ -525,9 +525,9 @@ private class PpIfStmt extends PpAst, IfStmt {
}
override predicate indents(int i) {
i = 4 and not this.getThen() instanceof Block
i = 4 and not this.getThen() instanceof BlockStmt
or
i = 8 and not this.getElse() instanceof Block
i = 8 and not this.getElse() instanceof BlockStmt
}
}
@@ -549,7 +549,7 @@ private class PpForStmt extends PpAst, ForStmt {
or
i = 1 + lastUpdateIndex() and result = ")"
or
i = 2 + lastUpdateIndex() and result = " " and this.getStmt() instanceof Block
i = 2 + lastUpdateIndex() and result = " " and this.getStmt() instanceof BlockStmt
}
private int lastInitIndex() { result = 3 + 2 * max(int j | exists(this.getInit(j))) }
@@ -559,7 +559,7 @@ private class PpForStmt extends PpAst, ForStmt {
}
override predicate newline(int i) {
i = 2 + lastUpdateIndex() and not this.getStmt() instanceof Block
i = 2 + lastUpdateIndex() and not this.getStmt() instanceof BlockStmt
}
override PpAst getChild(int i) {
@@ -575,7 +575,7 @@ private class PpForStmt extends PpAst, ForStmt {
}
override predicate indents(int i) {
i = 3 + lastUpdateIndex() and not this.getStmt() instanceof Block
i = 3 + lastUpdateIndex() and not this.getStmt() instanceof BlockStmt
}
}
@@ -588,7 +588,7 @@ private class PpEnhancedForStmt extends PpAst, EnhancedForStmt {
i = 4 and result = " : "
or
i = 6 and
if this.getStmt() instanceof Block then result = ") " else result = ")"
if this.getStmt() instanceof BlockStmt then result = ") " else result = ")"
}
override PpAst getChild(int i) {
@@ -601,7 +601,7 @@ private class PpEnhancedForStmt extends PpAst, EnhancedForStmt {
i = 7 and result = this.getStmt()
}
override predicate indents(int i) { i = 7 and not this.getStmt() instanceof Block }
override predicate indents(int i) { i = 7 and not this.getStmt() instanceof BlockStmt }
}
private class PpWhileStmt extends PpAst, WhileStmt {
@@ -610,10 +610,10 @@ private class PpWhileStmt extends PpAst, WhileStmt {
or
i = 2 and result = ")"
or
i = 3 and result = " " and this.getStmt() instanceof Block
i = 3 and result = " " and this.getStmt() instanceof BlockStmt
}
override predicate newline(int i) { i = 3 and not this.getStmt() instanceof Block }
override predicate newline(int i) { i = 3 and not this.getStmt() instanceof BlockStmt }
override PpAst getChild(int i) {
i = 1 and result = this.getCondition()
@@ -621,21 +621,21 @@ private class PpWhileStmt extends PpAst, WhileStmt {
i = 4 and result = this.getStmt()
}
override predicate indents(int i) { i = 4 and not this.getStmt() instanceof Block }
override predicate indents(int i) { i = 4 and not this.getStmt() instanceof BlockStmt }
}
private class PpDoStmt extends PpAst, DoStmt {
override string getPart(int i) {
i = 0 and result = "do"
or
i in [1, 3] and result = " " and this.getStmt() instanceof Block
i in [1, 3] and result = " " and this.getStmt() instanceof BlockStmt
or
i = 4 and result = "while ("
or
i = 6 and result = ");"
}
override predicate newline(int i) { i in [1, 3] and not this.getStmt() instanceof Block }
override predicate newline(int i) { i in [1, 3] and not this.getStmt() instanceof BlockStmt }
override PpAst getChild(int i) {
i = 2 and result = this.getStmt()
@@ -643,7 +643,7 @@ private class PpDoStmt extends PpAst, DoStmt {
i = 5 and result = this.getCondition()
}
override predicate indents(int i) { i = 2 and not this.getStmt() instanceof Block }
override predicate indents(int i) { i = 2 and not this.getStmt() instanceof BlockStmt }
}
private class PpTryStmt extends PpAst, TryStmt {

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