Merge branch 'master' of github.com:github/codeql into MagicMethods

This commit is contained in:
Rasmus Lerchedahl Petersen
2020-08-14 13:26:27 +02:00
35 changed files with 3404 additions and 1375 deletions

View File

@@ -14,6 +14,10 @@ The following changes in version 1.26 affect C/C++ analysis in all applications.
| **Query** | **Expected impact** | **Change** |
|----------------------------|------------------------|------------------------------------------------------------------|
| Inconsistent direction of for loop (`cpp/inconsistent-loop-direction`) | Fewer false positive results | The query now accounts for intentional wrapping of an unsigned loop counter. |
| Comparison result is always the same (`cpp/constant-comparison`) | More correct results | Bounds on expressions involving multiplication can now be determined in more cases. |
## Changes to libraries
* The models library now models more taint flows through `std::string`.
* The `SimpleRangeAnalysis` library now supports multiplications of the form
`e1 * e2` when `e1` and `e2` are unsigned.

View File

@@ -18,6 +18,9 @@ Expr getTest() {
or
// boost tests; http://www.boost.org/
result.(FunctionCall).getTarget().hasQualifiedName("boost::unit_test", "make_test_case")
or
// googletest tests; https://github.com/google/googletest/
result.(FunctionCall).getTarget().hasQualifiedName("testing::internal", "MakeAndRegisterTestInfo")
}
from File f, int n

View File

@@ -1,5 +1,13 @@
/**
* Provides classes for identifying and reasoning about Microsoft source code
* annotation language (SAL) macros.
*/
import cpp
/**
* A SAL macro defined in `sal.h` or a similar header file.
*/
class SALMacro extends Macro {
SALMacro() {
exists(string filename | filename = this.getFile().getBaseName() |
@@ -20,27 +28,34 @@ class SALMacro extends Macro {
}
pragma[noinline]
predicate isTopLevelMacroAccess(MacroAccess ma) { not exists(ma.getParentInvocation()) }
private predicate isTopLevelMacroAccess(MacroAccess ma) { not exists(ma.getParentInvocation()) }
/**
* An invocation of a SAL macro (excluding invocations inside other macros).
*/
class SALAnnotation extends MacroInvocation {
SALAnnotation() {
this.getMacro() instanceof SALMacro and
isTopLevelMacroAccess(this)
}
/** Returns the `Declaration` annotated by `this`. */
/** Gets the `Declaration` annotated by `this`. */
Declaration getDeclaration() {
annotatesAt(this, result.getADeclarationEntry(), _, _) and
not result instanceof Type // exclude typedefs
}
/** Returns the `DeclarationEntry` annotated by `this`. */
/** Gets the `DeclarationEntry` annotated by `this`. */
DeclarationEntry getDeclarationEntry() {
annotatesAt(this, result, _, _) and
not result instanceof TypeDeclarationEntry // exclude typedefs
}
}
/**
* A SAL macro indicating that the return value of a function should always be
* checked.
*/
class SALCheckReturn extends SALAnnotation {
SALCheckReturn() {
exists(SALMacro m | m = this.getMacro() |
@@ -50,6 +65,10 @@ class SALCheckReturn extends SALAnnotation {
}
}
/**
* A SAL macro indicating that a pointer variable or return value should not be
* `NULL`.
*/
class SALNotNull extends SALAnnotation {
SALNotNull() {
exists(SALMacro m | m = this.getMacro() |
@@ -69,6 +88,9 @@ class SALNotNull extends SALAnnotation {
}
}
/**
* A SAL macro indicating that a value may be `NULL`.
*/
class SALMaybeNull extends SALAnnotation {
SALMaybeNull() {
exists(SALMacro m | m = this.getMacro() |
@@ -79,13 +101,29 @@ class SALMaybeNull extends SALAnnotation {
}
}
/**
* A parameter annotated by one or more SAL annotations.
*/
class SALParameter extends Parameter {
/** One of this parameter's annotations. */
SALAnnotation a;
SALParameter() { annotatesAt(a, this.getADeclarationEntry(), _, _) }
predicate isIn() { a.getMacroName().toLowerCase().matches("%\\_in%") }
predicate isOut() { a.getMacroName().toLowerCase().matches("%\\_out%") }
predicate isInOut() { a.getMacroName().toLowerCase().matches("%\\_inout%") }
}
///////////////////////////////////////////////////////////////////////////////
// Implementation details
/**
* Holds if `a` annotates the declaration entry `d` and
* its start position is the `idx`th position in `file` that holds a SAL element.
*/
predicate annotatesAt(SALAnnotation a, DeclarationEntry d, File file, int idx) {
private predicate annotatesAt(SALAnnotation a, DeclarationEntry d, File file, int idx) {
annotatesAtPosition(a.(SALElement).getStartPosition(), d, file, idx)
}
@@ -109,22 +147,6 @@ private predicate annotatesAtPosition(SALPosition pos, DeclarationEntry d, File
)
}
/**
* A parameter annotated by one or more SAL annotations.
*/
class SALParameter extends Parameter {
/** One of this parameter's annotations. */
SALAnnotation a;
SALParameter() { annotatesAt(a, this.getADeclarationEntry(), _, _) }
predicate isIn() { a.getMacroName().toLowerCase().matches("%\\_in%") }
predicate isOut() { a.getMacroName().toLowerCase().matches("%\\_out%") }
predicate isInOut() { a.getMacroName().toLowerCase().matches("%\\_inout%") }
}
/**
* A SAL element, that is, a SAL annotation or a declaration entry
* that may have SAL annotations.

View File

@@ -1,5 +1,12 @@
import semmle.code.cpp.models.interfaces.Taint
/**
* The `std::basic_string` template class.
*/
class StdBasicString extends TemplateClass {
StdBasicString() { this.hasQualifiedName("std", "basic_string") }
}
/**
* The standard function `std::string.c_str`.
*/
@@ -12,3 +19,51 @@ class StdStringCStr extends TaintFunction {
output.isReturnValue()
}
}
/**
* The `std::string` function `operator+`.
*/
class StdStringPlus extends TaintFunction {
StdStringPlus() {
this.hasQualifiedName("std", "operator+") and
this.getUnspecifiedType() = any(StdBasicString s).getAnInstantiation()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from parameters to return value
(
input.isParameterDeref(0) or
input.isParameterDeref(1)
) and
output.isReturnValue()
}
}
/**
* The `std::string` functions `operator+=` and `append`.
*/
class StdStringAppend extends TaintFunction {
StdStringAppend() {
this.hasQualifiedName("std", "basic_string", "operator+=") or
this.hasQualifiedName("std", "basic_string", "append")
}
/**
* Gets the index of a parameter to this function that is a string (or
* character).
*/
int getAStringParameter() {
getParameter(result).getType() instanceof PointerType or
getParameter(result).getType() instanceof ReferenceType or
getParameter(result).getType() = getDeclaringType().getTemplateArgument(0) // i.e. `std::basic_string::CharT`
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from parameter to string itself (qualifier) and return value
input.isParameterDeref(getAStringParameter()) and
(
output.isQualifierObject() or
output.isReturnValueDeref()
)
}
}

View File

@@ -156,6 +156,10 @@ float safeFloor(float v) {
result = v
}
private class UnsignedMulExpr extends MulExpr {
UnsignedMulExpr() { this.getType().(IntegralType).isUnsigned() }
}
/** Set of expressions which we know how to analyze. */
private predicate analyzableExpr(Expr e) {
// The type of the expression must be arithmetic. We reuse the logic in
@@ -178,6 +182,8 @@ private predicate analyzableExpr(Expr e) {
or
e instanceof SubExpr
or
e instanceof UnsignedMulExpr
or
e instanceof AssignExpr
or
e instanceof AssignAddExpr
@@ -278,6 +284,10 @@ private predicate exprDependsOnDef(Expr e, RangeSsaDefinition srcDef, StackVaria
or
exists(SubExpr subExpr | e = subExpr | exprDependsOnDef(subExpr.getAnOperand(), srcDef, srcVar))
or
exists(UnsignedMulExpr mulExpr | e = mulExpr |
exprDependsOnDef(mulExpr.getAnOperand(), srcDef, srcVar)
)
or
exists(AssignExpr addExpr | e = addExpr | exprDependsOnDef(addExpr.getRValue(), srcDef, srcVar))
or
exists(AssignAddExpr addExpr | e = addExpr |
@@ -625,6 +635,13 @@ private float getLowerBoundsImpl(Expr expr) {
result = addRoundingDown(xLow, -yHigh)
)
or
exists(UnsignedMulExpr mulExpr, float xLow, float yLow |
expr = mulExpr and
xLow = getFullyConvertedLowerBounds(mulExpr.getLeftOperand()) and
yLow = getFullyConvertedLowerBounds(mulExpr.getRightOperand()) and
result = xLow * yLow
)
or
exists(AssignExpr assign |
expr = assign and
result = getFullyConvertedLowerBounds(assign.getRValue())
@@ -794,6 +811,13 @@ private float getUpperBoundsImpl(Expr expr) {
result = addRoundingUp(xHigh, -yLow)
)
or
exists(UnsignedMulExpr mulExpr, float xHigh, float yHigh |
expr = mulExpr and
xHigh = getFullyConvertedUpperBounds(mulExpr.getLeftOperand()) and
yHigh = getFullyConvertedUpperBounds(mulExpr.getRightOperand()) and
result = xHigh * yHigh
)
or
exists(AssignExpr assign |
expr = assign and
result = getFullyConvertedUpperBounds(assign.getRValue())

View File

@@ -308,205 +308,284 @@
| movableclass.cpp:65:13:65:18 | call to source | movableclass.cpp:65:13:65:20 | call to MyMovableClass | TAINT |
| movableclass.cpp:65:13:65:20 | call to MyMovableClass | movableclass.cpp:65:8:65:9 | ref arg s3 | TAINT |
| movableclass.cpp:65:13:65:20 | call to MyMovableClass | movableclass.cpp:65:11:65:11 | call to operator= | TAINT |
| stl.cpp:97:12:97:17 | call to source | stl.cpp:101:7:101:7 | a | |
| stl.cpp:98:16:98:20 | 123 | stl.cpp:98:16:98:21 | call to basic_string | TAINT |
| stl.cpp:98:16:98:21 | call to basic_string | stl.cpp:102:7:102:7 | b | |
| stl.cpp:98:16:98:21 | call to basic_string | stl.cpp:104:7:104:7 | b | |
| stl.cpp:99:16:99:21 | call to source | stl.cpp:99:16:99:24 | call to basic_string | TAINT |
| stl.cpp:99:16:99:24 | call to basic_string | stl.cpp:103:7:103:7 | c | |
| stl.cpp:99:16:99:24 | call to basic_string | stl.cpp:105:7:105:7 | c | |
| stl.cpp:104:7:104:7 | b | stl.cpp:104:9:104:13 | call to c_str | TAINT |
| stl.cpp:105:7:105:7 | c | stl.cpp:105:9:105:13 | call to c_str | TAINT |
| stl.cpp:110:20:110:22 | call to basic_stringstream | stl.cpp:113:2:113:4 | ss1 | |
| stl.cpp:110:20:110:22 | call to basic_stringstream | stl.cpp:119:7:119:9 | ss1 | |
| stl.cpp:110:20:110:22 | call to basic_stringstream | stl.cpp:124:7:124:9 | ss1 | |
| stl.cpp:110:25:110:27 | call to basic_stringstream | stl.cpp:114:2:114:4 | ss2 | |
| stl.cpp:110:25:110:27 | call to basic_stringstream | stl.cpp:120:7:120:9 | ss2 | |
| stl.cpp:110:25:110:27 | call to basic_stringstream | stl.cpp:125:7:125:9 | ss2 | |
| stl.cpp:110:30:110:32 | call to basic_stringstream | stl.cpp:115:2:115:4 | ss3 | |
| stl.cpp:110:30:110:32 | call to basic_stringstream | stl.cpp:121:7:121:9 | ss3 | |
| stl.cpp:110:30:110:32 | call to basic_stringstream | stl.cpp:126:7:126:9 | ss3 | |
| stl.cpp:110:35:110:37 | call to basic_stringstream | stl.cpp:116:2:116:4 | ss4 | |
| stl.cpp:110:35:110:37 | call to basic_stringstream | stl.cpp:122:7:122:9 | ss4 | |
| stl.cpp:110:35:110:37 | call to basic_stringstream | stl.cpp:127:7:127:9 | ss4 | |
| stl.cpp:110:40:110:42 | call to basic_stringstream | stl.cpp:117:2:117:4 | ss5 | |
| stl.cpp:110:40:110:42 | call to basic_stringstream | stl.cpp:123:7:123:9 | ss5 | |
| stl.cpp:110:40:110:42 | call to basic_stringstream | stl.cpp:128:7:128:9 | ss5 | |
| stl.cpp:109:12:109:17 | call to source | stl.cpp:113:7:113:7 | a | |
| stl.cpp:110:16:110:20 | 123 | stl.cpp:110:16:110:21 | call to basic_string | TAINT |
| stl.cpp:110:16:110:21 | call to basic_string | stl.cpp:114:7:114:7 | b | |
| stl.cpp:110:16:110:21 | call to basic_string | stl.cpp:116:7:116:7 | b | |
| stl.cpp:111:16:111:21 | call to source | stl.cpp:111:16:111:24 | call to basic_string | TAINT |
| stl.cpp:111:16:111:24 | call to basic_string | stl.cpp:117:9:117:9 | t | |
| stl.cpp:113:2:113:4 | ref arg ss1 | stl.cpp:119:7:119:9 | ss1 | |
| stl.cpp:113:2:113:4 | ref arg ss1 | stl.cpp:124:7:124:9 | ss1 | |
| stl.cpp:114:2:114:4 | ref arg ss2 | stl.cpp:120:7:120:9 | ss2 | |
| stl.cpp:114:2:114:4 | ref arg ss2 | stl.cpp:125:7:125:9 | ss2 | |
| stl.cpp:115:2:115:4 | ref arg ss3 | stl.cpp:121:7:121:9 | ss3 | |
| stl.cpp:115:2:115:4 | ref arg ss3 | stl.cpp:126:7:126:9 | ss3 | |
| stl.cpp:116:2:116:4 | ref arg ss4 | stl.cpp:122:7:122:9 | ss4 | |
| stl.cpp:116:2:116:4 | ref arg ss4 | stl.cpp:127:7:127:9 | ss4 | |
| stl.cpp:117:2:117:4 | ref arg ss5 | stl.cpp:123:7:123:9 | ss5 | |
| stl.cpp:117:2:117:4 | ref arg ss5 | stl.cpp:128:7:128:9 | ss5 | |
| stl.cpp:131:32:131:37 | source | stl.cpp:136:9:136:14 | source | |
| stl.cpp:133:20:133:22 | call to basic_stringstream | stl.cpp:135:2:135:4 | ss1 | |
| stl.cpp:133:20:133:22 | call to basic_stringstream | stl.cpp:138:7:138:9 | ss1 | |
| stl.cpp:133:20:133:22 | call to basic_stringstream | stl.cpp:140:7:140:9 | ss1 | |
| stl.cpp:133:25:133:27 | call to basic_stringstream | stl.cpp:136:2:136:4 | ss2 | |
| stl.cpp:133:25:133:27 | call to basic_stringstream | stl.cpp:139:7:139:9 | ss2 | |
| stl.cpp:133:25:133:27 | call to basic_stringstream | stl.cpp:141:7:141:9 | ss2 | |
| stl.cpp:135:2:135:4 | ref arg ss1 | stl.cpp:138:7:138:9 | ss1 | |
| stl.cpp:135:2:135:4 | ref arg ss1 | stl.cpp:140:7:140:9 | ss1 | |
| stl.cpp:136:2:136:4 | ref arg ss2 | stl.cpp:139:7:139:9 | ss2 | |
| stl.cpp:136:2:136:4 | ref arg ss2 | stl.cpp:141:7:141:9 | ss2 | |
| stl.cpp:154:16:154:28 | call to basic_string | stl.cpp:155:7:155:11 | path1 | |
| stl.cpp:154:17:154:26 | call to user_input | stl.cpp:154:16:154:28 | call to basic_string | TAINT |
| stl.cpp:155:7:155:11 | path1 | stl.cpp:155:13:155:17 | call to c_str | TAINT |
| stl.cpp:158:10:158:19 | call to user_input | stl.cpp:158:10:158:21 | call to basic_string | TAINT |
| stl.cpp:158:10:158:21 | call to basic_string | stl.cpp:158:2:158:21 | ... = ... | |
| stl.cpp:158:10:158:21 | call to basic_string | stl.cpp:159:7:159:11 | path2 | |
| stl.cpp:159:7:159:11 | path2 | stl.cpp:159:13:159:17 | call to c_str | TAINT |
| stl.cpp:161:15:161:24 | call to user_input | stl.cpp:161:15:161:27 | call to basic_string | TAINT |
| stl.cpp:161:15:161:27 | call to basic_string | stl.cpp:162:7:162:11 | path3 | |
| stl.cpp:162:7:162:11 | path3 | stl.cpp:162:13:162:17 | call to c_str | TAINT |
| stl.cpp:167:19:167:24 | call to source | stl.cpp:170:17:170:18 | cs | |
| stl.cpp:167:19:167:24 | call to source | stl.cpp:172:7:172:8 | cs | |
| stl.cpp:170:17:170:18 | cs | stl.cpp:170:17:170:19 | call to basic_string | TAINT |
| stl.cpp:170:17:170:19 | call to basic_string | stl.cpp:173:7:173:8 | ss | |
| stl.cpp:178:19:178:24 | call to source | stl.cpp:181:17:181:18 | cs | |
| stl.cpp:181:17:181:18 | cs | stl.cpp:181:17:181:19 | call to basic_string | TAINT |
| stl.cpp:181:17:181:19 | call to basic_string | stl.cpp:184:7:184:8 | ss | |
| stl.cpp:181:17:181:19 | call to basic_string | stl.cpp:187:7:187:8 | ss | |
| stl.cpp:184:7:184:8 | ss | stl.cpp:184:10:184:14 | call to c_str | TAINT |
| stl.cpp:184:10:184:14 | call to c_str | stl.cpp:184:2:184:16 | ... = ... | |
| stl.cpp:184:10:184:14 | call to c_str | stl.cpp:186:7:186:8 | cs | |
| stl.cpp:193:18:193:24 | hello | stl.cpp:193:18:193:25 | call to basic_string | TAINT |
| stl.cpp:193:18:193:25 | call to basic_string | stl.cpp:198:8:198:9 | s1 | |
| stl.cpp:194:19:194:26 | call to basic_string | stl.cpp:199:8:199:9 | s2 | |
| stl.cpp:194:20:194:26 | hello | stl.cpp:194:19:194:26 | call to basic_string | TAINT |
| stl.cpp:196:8:196:14 | call to basic_string | stl.cpp:196:3:196:14 | ... = ... | |
| stl.cpp:196:8:196:14 | call to basic_string | stl.cpp:200:8:200:9 | s3 | |
| stl.cpp:196:8:196:14 | hello | stl.cpp:196:8:196:14 | call to basic_string | TAINT |
| stl.cpp:204:18:204:23 | call to source | stl.cpp:204:18:204:26 | call to basic_string | TAINT |
| stl.cpp:204:18:204:26 | call to basic_string | stl.cpp:209:8:209:9 | s1 | |
| stl.cpp:205:19:205:27 | call to basic_string | stl.cpp:210:8:210:9 | s2 | |
| stl.cpp:205:20:205:25 | call to source | stl.cpp:205:19:205:27 | call to basic_string | TAINT |
| stl.cpp:207:8:207:13 | call to source | stl.cpp:207:8:207:15 | call to basic_string | TAINT |
| stl.cpp:207:8:207:15 | call to basic_string | stl.cpp:207:3:207:15 | ... = ... | |
| stl.cpp:207:8:207:15 | call to basic_string | stl.cpp:211:8:211:9 | s3 | |
| stl.cpp:215:15:215:16 | call to basic_string | stl.cpp:216:20:216:21 | s1 | |
| stl.cpp:215:15:215:16 | call to basic_string | stl.cpp:218:8:218:9 | s1 | |
| stl.cpp:215:15:215:16 | call to basic_string | stl.cpp:220:8:220:9 | s1 | |
| stl.cpp:216:20:216:21 | s1 | stl.cpp:221:8:221:9 | s2 | |
| stl.cpp:218:8:218:9 | s1 | stl.cpp:218:3:218:9 | ... = ... | |
| stl.cpp:218:8:218:9 | s1 | stl.cpp:222:8:222:9 | s3 | |
| stl.cpp:226:19:226:40 | call to basic_string | stl.cpp:230:8:230:9 | s1 | |
| stl.cpp:226:32:226:37 | call to source | stl.cpp:226:19:226:40 | call to basic_string | TAINT |
| stl.cpp:228:8:228:28 | call to basic_string | stl.cpp:228:3:228:28 | ... = ... | |
| stl.cpp:228:8:228:28 | call to basic_string | stl.cpp:231:8:231:9 | s2 | |
| stl.cpp:228:20:228:25 | call to source | stl.cpp:228:8:228:28 | call to basic_string | TAINT |
| stl.cpp:238:16:238:21 | call to source | stl.cpp:238:16:238:24 | call to basic_string | TAINT |
| stl.cpp:238:16:238:24 | call to basic_string | stl.cpp:239:15:239:15 | s | |
| stl.cpp:238:16:238:24 | call to basic_string | stl.cpp:243:33:243:33 | s | |
| stl.cpp:238:16:238:24 | call to basic_string | stl.cpp:243:50:243:50 | s | |
| stl.cpp:238:16:238:24 | call to basic_string | stl.cpp:247:16:247:16 | s | |
| stl.cpp:239:15:239:15 | call to begin | stl.cpp:239:15:239:15 | (__begin) | |
| stl.cpp:239:15:239:15 | call to begin | stl.cpp:239:15:239:15 | (__begin) | |
| stl.cpp:239:15:239:15 | call to begin | stl.cpp:239:15:239:15 | (__begin) | |
| stl.cpp:239:15:239:15 | call to end | stl.cpp:239:15:239:15 | (__end) | |
| stl.cpp:239:15:239:15 | call to operator* | stl.cpp:240:8:240:8 | c | |
| stl.cpp:239:15:239:15 | ref arg (__begin) | stl.cpp:239:15:239:15 | (__begin) | |
| stl.cpp:239:15:239:15 | ref arg (__begin) | stl.cpp:239:15:239:15 | (__begin) | |
| stl.cpp:239:15:239:15 | ref arg (__begin) | stl.cpp:239:15:239:15 | (__begin) | |
| stl.cpp:239:15:239:15 | ref arg (__range) | stl.cpp:239:15:239:15 | (__range) | |
| stl.cpp:239:15:239:15 | s | stl.cpp:239:15:239:15 | (__range) | |
| stl.cpp:239:15:239:15 | s | stl.cpp:239:15:239:15 | (__range) | |
| stl.cpp:239:15:239:15 | s | stl.cpp:239:15:239:15 | call to operator* | TAINT |
| stl.cpp:243:33:243:33 | ref arg s | stl.cpp:243:50:243:50 | s | |
| stl.cpp:243:33:243:33 | ref arg s | stl.cpp:247:16:247:16 | s | |
| stl.cpp:243:35:243:39 | call to begin | stl.cpp:243:44:243:45 | it | |
| stl.cpp:243:35:243:39 | call to begin | stl.cpp:243:61:243:62 | it | |
| stl.cpp:243:35:243:39 | call to begin | stl.cpp:244:9:244:10 | it | |
| stl.cpp:243:50:243:50 | ref arg s | stl.cpp:243:50:243:50 | s | |
| stl.cpp:243:50:243:50 | ref arg s | stl.cpp:247:16:247:16 | s | |
| stl.cpp:243:61:243:62 | ref arg it | stl.cpp:243:44:243:45 | it | |
| stl.cpp:243:61:243:62 | ref arg it | stl.cpp:243:61:243:62 | it | |
| stl.cpp:243:61:243:62 | ref arg it | stl.cpp:244:9:244:10 | it | |
| stl.cpp:247:16:247:16 | call to begin | stl.cpp:247:16:247:16 | (__begin) | |
| stl.cpp:247:16:247:16 | call to begin | stl.cpp:247:16:247:16 | (__begin) | |
| stl.cpp:247:16:247:16 | call to begin | stl.cpp:247:16:247:16 | (__begin) | |
| stl.cpp:247:16:247:16 | call to end | stl.cpp:247:16:247:16 | (__end) | |
| stl.cpp:247:16:247:16 | call to operator* | stl.cpp:248:8:248:8 | c | |
| stl.cpp:247:16:247:16 | ref arg (__begin) | stl.cpp:247:16:247:16 | (__begin) | |
| stl.cpp:247:16:247:16 | ref arg (__begin) | stl.cpp:247:16:247:16 | (__begin) | |
| stl.cpp:247:16:247:16 | ref arg (__begin) | stl.cpp:247:16:247:16 | (__begin) | |
| stl.cpp:247:16:247:16 | ref arg (__range) | stl.cpp:247:16:247:16 | (__range) | |
| stl.cpp:247:16:247:16 | s | stl.cpp:247:16:247:16 | (__range) | |
| stl.cpp:247:16:247:16 | s | stl.cpp:247:16:247:16 | (__range) | |
| stl.cpp:247:16:247:16 | s | stl.cpp:247:16:247:16 | call to operator* | TAINT |
| stl.cpp:251:28:251:33 | call to source | stl.cpp:251:28:251:36 | call to basic_string | TAINT |
| stl.cpp:251:28:251:36 | call to basic_string | stl.cpp:252:22:252:28 | const_s | |
| stl.cpp:252:22:252:22 | call to begin | stl.cpp:252:22:252:22 | (__begin) | |
| stl.cpp:252:22:252:22 | call to begin | stl.cpp:252:22:252:22 | (__begin) | |
| stl.cpp:252:22:252:22 | call to begin | stl.cpp:252:22:252:22 | (__begin) | |
| stl.cpp:252:22:252:22 | call to end | stl.cpp:252:22:252:22 | (__end) | |
| stl.cpp:252:22:252:22 | call to operator* | stl.cpp:253:8:253:8 | c | |
| stl.cpp:252:22:252:22 | ref arg (__begin) | stl.cpp:252:22:252:22 | (__begin) | |
| stl.cpp:252:22:252:22 | ref arg (__begin) | stl.cpp:252:22:252:22 | (__begin) | |
| stl.cpp:252:22:252:22 | ref arg (__begin) | stl.cpp:252:22:252:22 | (__begin) | |
| stl.cpp:252:22:252:28 | const_s | stl.cpp:252:22:252:22 | (__range) | |
| stl.cpp:252:22:252:28 | const_s | stl.cpp:252:22:252:22 | (__range) | |
| stl.cpp:252:22:252:28 | const_s | stl.cpp:252:22:252:22 | call to operator* | TAINT |
| stl.cpp:288:43:288:49 | source1 | stl.cpp:292:21:292:27 | source1 | |
| stl.cpp:288:43:288:49 | source1 | stl.cpp:306:33:306:39 | source1 | |
| stl.cpp:292:21:292:27 | source1 | stl.cpp:292:21:292:28 | call to vector | TAINT |
| stl.cpp:292:21:292:28 | call to vector | stl.cpp:294:14:294:14 | v | |
| stl.cpp:292:21:292:28 | call to vector | stl.cpp:298:38:298:38 | v | |
| stl.cpp:292:21:292:28 | call to vector | stl.cpp:298:55:298:55 | v | |
| stl.cpp:292:21:292:28 | call to vector | stl.cpp:302:15:302:15 | v | |
| stl.cpp:294:14:294:14 | call to begin | stl.cpp:294:14:294:14 | (__begin) | |
| stl.cpp:294:14:294:14 | call to begin | stl.cpp:294:14:294:14 | (__begin) | |
| stl.cpp:294:14:294:14 | call to begin | stl.cpp:294:14:294:14 | (__begin) | |
| stl.cpp:294:14:294:14 | call to end | stl.cpp:294:14:294:14 | (__end) | |
| stl.cpp:294:14:294:14 | call to operator* | stl.cpp:295:8:295:8 | x | |
| stl.cpp:294:14:294:14 | ref arg (__begin) | stl.cpp:294:14:294:14 | (__begin) | |
| stl.cpp:294:14:294:14 | ref arg (__begin) | stl.cpp:294:14:294:14 | (__begin) | |
| stl.cpp:294:14:294:14 | ref arg (__begin) | stl.cpp:294:14:294:14 | (__begin) | |
| stl.cpp:294:14:294:14 | ref arg (__range) | stl.cpp:294:14:294:14 | (__range) | |
| stl.cpp:294:14:294:14 | v | stl.cpp:294:14:294:14 | (__range) | |
| stl.cpp:294:14:294:14 | v | stl.cpp:294:14:294:14 | (__range) | |
| stl.cpp:294:14:294:14 | v | stl.cpp:294:14:294:14 | call to operator* | TAINT |
| stl.cpp:298:38:298:38 | ref arg v | stl.cpp:298:55:298:55 | v | |
| stl.cpp:298:38:298:38 | ref arg v | stl.cpp:302:15:302:15 | v | |
| stl.cpp:298:40:298:44 | call to begin | stl.cpp:298:49:298:50 | it | |
| stl.cpp:298:40:298:44 | call to begin | stl.cpp:298:66:298:67 | it | |
| stl.cpp:298:40:298:44 | call to begin | stl.cpp:299:9:299:10 | it | |
| stl.cpp:298:55:298:55 | ref arg v | stl.cpp:298:55:298:55 | v | |
| stl.cpp:298:55:298:55 | ref arg v | stl.cpp:302:15:302:15 | v | |
| stl.cpp:298:66:298:67 | ref arg it | stl.cpp:298:49:298:50 | it | |
| stl.cpp:298:66:298:67 | ref arg it | stl.cpp:298:66:298:67 | it | |
| stl.cpp:298:66:298:67 | ref arg it | stl.cpp:299:9:299:10 | it | |
| stl.cpp:302:15:302:15 | call to begin | stl.cpp:302:15:302:15 | (__begin) | |
| stl.cpp:302:15:302:15 | call to begin | stl.cpp:302:15:302:15 | (__begin) | |
| stl.cpp:302:15:302:15 | call to begin | stl.cpp:302:15:302:15 | (__begin) | |
| stl.cpp:302:15:302:15 | call to end | stl.cpp:302:15:302:15 | (__end) | |
| stl.cpp:302:15:302:15 | call to operator* | stl.cpp:303:8:303:8 | x | |
| stl.cpp:302:15:302:15 | ref arg (__begin) | stl.cpp:302:15:302:15 | (__begin) | |
| stl.cpp:302:15:302:15 | ref arg (__begin) | stl.cpp:302:15:302:15 | (__begin) | |
| stl.cpp:302:15:302:15 | ref arg (__begin) | stl.cpp:302:15:302:15 | (__begin) | |
| stl.cpp:302:15:302:15 | ref arg (__range) | stl.cpp:302:15:302:15 | (__range) | |
| stl.cpp:302:15:302:15 | v | stl.cpp:302:15:302:15 | (__range) | |
| stl.cpp:302:15:302:15 | v | stl.cpp:302:15:302:15 | (__range) | |
| stl.cpp:302:15:302:15 | v | stl.cpp:302:15:302:15 | call to operator* | TAINT |
| stl.cpp:306:33:306:39 | source1 | stl.cpp:306:33:306:40 | call to vector | TAINT |
| stl.cpp:306:33:306:40 | call to vector | stl.cpp:307:21:307:27 | const_v | |
| stl.cpp:307:21:307:21 | call to begin | stl.cpp:307:21:307:21 | (__begin) | |
| stl.cpp:307:21:307:21 | call to begin | stl.cpp:307:21:307:21 | (__begin) | |
| stl.cpp:307:21:307:21 | call to begin | stl.cpp:307:21:307:21 | (__begin) | |
| stl.cpp:307:21:307:21 | call to end | stl.cpp:307:21:307:21 | (__end) | |
| stl.cpp:307:21:307:21 | call to operator* | stl.cpp:308:8:308:8 | x | |
| stl.cpp:307:21:307:21 | ref arg (__begin) | stl.cpp:307:21:307:21 | (__begin) | |
| stl.cpp:307:21:307:21 | ref arg (__begin) | stl.cpp:307:21:307:21 | (__begin) | |
| stl.cpp:307:21:307:21 | ref arg (__begin) | stl.cpp:307:21:307:21 | (__begin) | |
| stl.cpp:307:21:307:27 | const_v | stl.cpp:307:21:307:21 | (__range) | |
| stl.cpp:307:21:307:27 | const_v | stl.cpp:307:21:307:21 | (__range) | |
| stl.cpp:307:21:307:27 | const_v | stl.cpp:307:21:307:21 | call to operator* | TAINT |
| stl.cpp:111:16:111:24 | call to basic_string | stl.cpp:115:7:115:7 | c | |
| stl.cpp:111:16:111:24 | call to basic_string | stl.cpp:117:7:117:7 | c | |
| stl.cpp:116:7:116:7 | b | stl.cpp:116:9:116:13 | call to c_str | TAINT |
| stl.cpp:117:7:117:7 | c | stl.cpp:117:9:117:13 | call to c_str | TAINT |
| stl.cpp:122:20:122:22 | call to basic_stringstream | stl.cpp:125:2:125:4 | ss1 | |
| stl.cpp:122:20:122:22 | call to basic_stringstream | stl.cpp:131:7:131:9 | ss1 | |
| stl.cpp:122:20:122:22 | call to basic_stringstream | stl.cpp:136:7:136:9 | ss1 | |
| stl.cpp:122:25:122:27 | call to basic_stringstream | stl.cpp:126:2:126:4 | ss2 | |
| stl.cpp:122:25:122:27 | call to basic_stringstream | stl.cpp:132:7:132:9 | ss2 | |
| stl.cpp:122:25:122:27 | call to basic_stringstream | stl.cpp:137:7:137:9 | ss2 | |
| stl.cpp:122:30:122:32 | call to basic_stringstream | stl.cpp:127:2:127:4 | ss3 | |
| stl.cpp:122:30:122:32 | call to basic_stringstream | stl.cpp:133:7:133:9 | ss3 | |
| stl.cpp:122:30:122:32 | call to basic_stringstream | stl.cpp:138:7:138:9 | ss3 | |
| stl.cpp:122:35:122:37 | call to basic_stringstream | stl.cpp:128:2:128:4 | ss4 | |
| stl.cpp:122:35:122:37 | call to basic_stringstream | stl.cpp:134:7:134:9 | ss4 | |
| stl.cpp:122:35:122:37 | call to basic_stringstream | stl.cpp:139:7:139:9 | ss4 | |
| stl.cpp:122:40:122:42 | call to basic_stringstream | stl.cpp:129:2:129:4 | ss5 | |
| stl.cpp:122:40:122:42 | call to basic_stringstream | stl.cpp:135:7:135:9 | ss5 | |
| stl.cpp:122:40:122:42 | call to basic_stringstream | stl.cpp:140:7:140:9 | ss5 | |
| stl.cpp:123:16:123:21 | call to source | stl.cpp:123:16:123:24 | call to basic_string | TAINT |
| stl.cpp:123:16:123:24 | call to basic_string | stl.cpp:129:9:129:9 | t | |
| stl.cpp:125:2:125:4 | ref arg ss1 | stl.cpp:131:7:131:9 | ss1 | |
| stl.cpp:125:2:125:4 | ref arg ss1 | stl.cpp:136:7:136:9 | ss1 | |
| stl.cpp:126:2:126:4 | ref arg ss2 | stl.cpp:132:7:132:9 | ss2 | |
| stl.cpp:126:2:126:4 | ref arg ss2 | stl.cpp:137:7:137:9 | ss2 | |
| stl.cpp:127:2:127:4 | ref arg ss3 | stl.cpp:133:7:133:9 | ss3 | |
| stl.cpp:127:2:127:4 | ref arg ss3 | stl.cpp:138:7:138:9 | ss3 | |
| stl.cpp:128:2:128:4 | ref arg ss4 | stl.cpp:134:7:134:9 | ss4 | |
| stl.cpp:128:2:128:4 | ref arg ss4 | stl.cpp:139:7:139:9 | ss4 | |
| stl.cpp:129:2:129:4 | ref arg ss5 | stl.cpp:135:7:135:9 | ss5 | |
| stl.cpp:129:2:129:4 | ref arg ss5 | stl.cpp:140:7:140:9 | ss5 | |
| stl.cpp:143:32:143:37 | source | stl.cpp:148:9:148:14 | source | |
| stl.cpp:145:20:145:22 | call to basic_stringstream | stl.cpp:147:2:147:4 | ss1 | |
| stl.cpp:145:20:145:22 | call to basic_stringstream | stl.cpp:150:7:150:9 | ss1 | |
| stl.cpp:145:20:145:22 | call to basic_stringstream | stl.cpp:152:7:152:9 | ss1 | |
| stl.cpp:145:25:145:27 | call to basic_stringstream | stl.cpp:148:2:148:4 | ss2 | |
| stl.cpp:145:25:145:27 | call to basic_stringstream | stl.cpp:151:7:151:9 | ss2 | |
| stl.cpp:145:25:145:27 | call to basic_stringstream | stl.cpp:153:7:153:9 | ss2 | |
| stl.cpp:147:2:147:4 | ref arg ss1 | stl.cpp:150:7:150:9 | ss1 | |
| stl.cpp:147:2:147:4 | ref arg ss1 | stl.cpp:152:7:152:9 | ss1 | |
| stl.cpp:148:2:148:4 | ref arg ss2 | stl.cpp:151:7:151:9 | ss2 | |
| stl.cpp:148:2:148:4 | ref arg ss2 | stl.cpp:153:7:153:9 | ss2 | |
| stl.cpp:166:16:166:28 | call to basic_string | stl.cpp:167:7:167:11 | path1 | |
| stl.cpp:166:17:166:26 | call to user_input | stl.cpp:166:16:166:28 | call to basic_string | TAINT |
| stl.cpp:167:7:167:11 | path1 | stl.cpp:167:13:167:17 | call to c_str | TAINT |
| stl.cpp:170:10:170:19 | call to user_input | stl.cpp:170:10:170:21 | call to basic_string | TAINT |
| stl.cpp:170:10:170:21 | call to basic_string | stl.cpp:170:2:170:21 | ... = ... | |
| stl.cpp:170:10:170:21 | call to basic_string | stl.cpp:171:7:171:11 | path2 | |
| stl.cpp:171:7:171:11 | path2 | stl.cpp:171:13:171:17 | call to c_str | TAINT |
| stl.cpp:173:15:173:24 | call to user_input | stl.cpp:173:15:173:27 | call to basic_string | TAINT |
| stl.cpp:173:15:173:27 | call to basic_string | stl.cpp:174:7:174:11 | path3 | |
| stl.cpp:174:7:174:11 | path3 | stl.cpp:174:13:174:17 | call to c_str | TAINT |
| stl.cpp:179:19:179:24 | call to source | stl.cpp:182:17:182:18 | cs | |
| stl.cpp:179:19:179:24 | call to source | stl.cpp:184:7:184:8 | cs | |
| stl.cpp:182:17:182:18 | cs | stl.cpp:182:17:182:19 | call to basic_string | TAINT |
| stl.cpp:182:17:182:19 | call to basic_string | stl.cpp:185:7:185:8 | ss | |
| stl.cpp:190:19:190:24 | call to source | stl.cpp:193:17:193:18 | cs | |
| stl.cpp:193:17:193:18 | cs | stl.cpp:193:17:193:19 | call to basic_string | TAINT |
| stl.cpp:193:17:193:19 | call to basic_string | stl.cpp:196:7:196:8 | ss | |
| stl.cpp:193:17:193:19 | call to basic_string | stl.cpp:199:7:199:8 | ss | |
| stl.cpp:196:7:196:8 | ss | stl.cpp:196:10:196:14 | call to c_str | TAINT |
| stl.cpp:196:10:196:14 | call to c_str | stl.cpp:196:2:196:16 | ... = ... | |
| stl.cpp:196:10:196:14 | call to c_str | stl.cpp:198:7:198:8 | cs | |
| stl.cpp:205:18:205:24 | hello | stl.cpp:205:18:205:25 | call to basic_string | TAINT |
| stl.cpp:205:18:205:25 | call to basic_string | stl.cpp:210:8:210:9 | s1 | |
| stl.cpp:206:19:206:26 | call to basic_string | stl.cpp:211:8:211:9 | s2 | |
| stl.cpp:206:20:206:26 | hello | stl.cpp:206:19:206:26 | call to basic_string | TAINT |
| stl.cpp:208:8:208:14 | call to basic_string | stl.cpp:208:3:208:14 | ... = ... | |
| stl.cpp:208:8:208:14 | call to basic_string | stl.cpp:212:8:212:9 | s3 | |
| stl.cpp:208:8:208:14 | hello | stl.cpp:208:8:208:14 | call to basic_string | TAINT |
| stl.cpp:216:18:216:23 | call to source | stl.cpp:216:18:216:26 | call to basic_string | TAINT |
| stl.cpp:216:18:216:26 | call to basic_string | stl.cpp:221:8:221:9 | s1 | |
| stl.cpp:217:19:217:27 | call to basic_string | stl.cpp:222:8:222:9 | s2 | |
| stl.cpp:217:20:217:25 | call to source | stl.cpp:217:19:217:27 | call to basic_string | TAINT |
| stl.cpp:219:8:219:13 | call to source | stl.cpp:219:8:219:15 | call to basic_string | TAINT |
| stl.cpp:219:8:219:15 | call to basic_string | stl.cpp:219:3:219:15 | ... = ... | |
| stl.cpp:219:8:219:15 | call to basic_string | stl.cpp:223:8:223:9 | s3 | |
| stl.cpp:227:15:227:16 | call to basic_string | stl.cpp:228:20:228:21 | s1 | |
| stl.cpp:227:15:227:16 | call to basic_string | stl.cpp:230:8:230:9 | s1 | |
| stl.cpp:227:15:227:16 | call to basic_string | stl.cpp:232:8:232:9 | s1 | |
| stl.cpp:228:20:228:21 | s1 | stl.cpp:233:8:233:9 | s2 | |
| stl.cpp:230:8:230:9 | s1 | stl.cpp:230:3:230:9 | ... = ... | |
| stl.cpp:230:8:230:9 | s1 | stl.cpp:234:8:234:9 | s3 | |
| stl.cpp:238:19:238:40 | call to basic_string | stl.cpp:242:8:242:9 | s1 | |
| stl.cpp:238:32:238:37 | call to source | stl.cpp:238:19:238:40 | call to basic_string | TAINT |
| stl.cpp:240:8:240:28 | call to basic_string | stl.cpp:240:3:240:28 | ... = ... | |
| stl.cpp:240:8:240:28 | call to basic_string | stl.cpp:243:8:243:9 | s2 | |
| stl.cpp:240:20:240:25 | call to source | stl.cpp:240:8:240:28 | call to basic_string | TAINT |
| stl.cpp:250:16:250:21 | call to source | stl.cpp:250:16:250:24 | call to basic_string | TAINT |
| stl.cpp:250:16:250:24 | call to basic_string | stl.cpp:251:15:251:15 | s | |
| stl.cpp:250:16:250:24 | call to basic_string | stl.cpp:255:33:255:33 | s | |
| stl.cpp:250:16:250:24 | call to basic_string | stl.cpp:255:50:255:50 | s | |
| stl.cpp:250:16:250:24 | call to basic_string | stl.cpp:259:16:259:16 | s | |
| stl.cpp:251:15:251:15 | call to begin | stl.cpp:251:15:251:15 | (__begin) | |
| stl.cpp:251:15:251:15 | call to begin | stl.cpp:251:15:251:15 | (__begin) | |
| stl.cpp:251:15:251:15 | call to begin | stl.cpp:251:15:251:15 | (__begin) | |
| stl.cpp:251:15:251:15 | call to end | stl.cpp:251:15:251:15 | (__end) | |
| stl.cpp:251:15:251:15 | call to operator* | stl.cpp:252:8:252:8 | c | |
| stl.cpp:251:15:251:15 | ref arg (__begin) | stl.cpp:251:15:251:15 | (__begin) | |
| stl.cpp:251:15:251:15 | ref arg (__begin) | stl.cpp:251:15:251:15 | (__begin) | |
| stl.cpp:251:15:251:15 | ref arg (__begin) | stl.cpp:251:15:251:15 | (__begin) | |
| stl.cpp:251:15:251:15 | ref arg (__range) | stl.cpp:251:15:251:15 | (__range) | |
| stl.cpp:251:15:251:15 | s | stl.cpp:251:15:251:15 | (__range) | |
| stl.cpp:251:15:251:15 | s | stl.cpp:251:15:251:15 | (__range) | |
| stl.cpp:251:15:251:15 | s | stl.cpp:251:15:251:15 | call to operator* | TAINT |
| stl.cpp:255:33:255:33 | ref arg s | stl.cpp:255:50:255:50 | s | |
| stl.cpp:255:33:255:33 | ref arg s | stl.cpp:259:16:259:16 | s | |
| stl.cpp:255:35:255:39 | call to begin | stl.cpp:255:44:255:45 | it | |
| stl.cpp:255:35:255:39 | call to begin | stl.cpp:255:61:255:62 | it | |
| stl.cpp:255:35:255:39 | call to begin | stl.cpp:256:9:256:10 | it | |
| stl.cpp:255:50:255:50 | ref arg s | stl.cpp:255:50:255:50 | s | |
| stl.cpp:255:50:255:50 | ref arg s | stl.cpp:259:16:259:16 | s | |
| stl.cpp:255:61:255:62 | ref arg it | stl.cpp:255:44:255:45 | it | |
| stl.cpp:255:61:255:62 | ref arg it | stl.cpp:255:61:255:62 | it | |
| stl.cpp:255:61:255:62 | ref arg it | stl.cpp:256:9:256:10 | it | |
| stl.cpp:259:16:259:16 | call to begin | stl.cpp:259:16:259:16 | (__begin) | |
| stl.cpp:259:16:259:16 | call to begin | stl.cpp:259:16:259:16 | (__begin) | |
| stl.cpp:259:16:259:16 | call to begin | stl.cpp:259:16:259:16 | (__begin) | |
| stl.cpp:259:16:259:16 | call to end | stl.cpp:259:16:259:16 | (__end) | |
| stl.cpp:259:16:259:16 | call to operator* | stl.cpp:260:8:260:8 | c | |
| stl.cpp:259:16:259:16 | ref arg (__begin) | stl.cpp:259:16:259:16 | (__begin) | |
| stl.cpp:259:16:259:16 | ref arg (__begin) | stl.cpp:259:16:259:16 | (__begin) | |
| stl.cpp:259:16:259:16 | ref arg (__begin) | stl.cpp:259:16:259:16 | (__begin) | |
| stl.cpp:259:16:259:16 | ref arg (__range) | stl.cpp:259:16:259:16 | (__range) | |
| stl.cpp:259:16:259:16 | s | stl.cpp:259:16:259:16 | (__range) | |
| stl.cpp:259:16:259:16 | s | stl.cpp:259:16:259:16 | (__range) | |
| stl.cpp:259:16:259:16 | s | stl.cpp:259:16:259:16 | call to operator* | TAINT |
| stl.cpp:263:28:263:33 | call to source | stl.cpp:263:28:263:36 | call to basic_string | TAINT |
| stl.cpp:263:28:263:36 | call to basic_string | stl.cpp:264:22:264:28 | const_s | |
| stl.cpp:264:22:264:22 | call to begin | stl.cpp:264:22:264:22 | (__begin) | |
| stl.cpp:264:22:264:22 | call to begin | stl.cpp:264:22:264:22 | (__begin) | |
| stl.cpp:264:22:264:22 | call to begin | stl.cpp:264:22:264:22 | (__begin) | |
| stl.cpp:264:22:264:22 | call to end | stl.cpp:264:22:264:22 | (__end) | |
| stl.cpp:264:22:264:22 | call to operator* | stl.cpp:265:8:265:8 | c | |
| stl.cpp:264:22:264:22 | ref arg (__begin) | stl.cpp:264:22:264:22 | (__begin) | |
| stl.cpp:264:22:264:22 | ref arg (__begin) | stl.cpp:264:22:264:22 | (__begin) | |
| stl.cpp:264:22:264:22 | ref arg (__begin) | stl.cpp:264:22:264:22 | (__begin) | |
| stl.cpp:264:22:264:28 | const_s | stl.cpp:264:22:264:22 | (__range) | |
| stl.cpp:264:22:264:28 | const_s | stl.cpp:264:22:264:22 | (__range) | |
| stl.cpp:264:22:264:28 | const_s | stl.cpp:264:22:264:22 | call to operator* | TAINT |
| stl.cpp:300:43:300:49 | source1 | stl.cpp:304:21:304:27 | source1 | |
| stl.cpp:300:43:300:49 | source1 | stl.cpp:318:33:318:39 | source1 | |
| stl.cpp:304:21:304:27 | source1 | stl.cpp:304:21:304:28 | call to vector | TAINT |
| stl.cpp:304:21:304:28 | call to vector | stl.cpp:306:14:306:14 | v | |
| stl.cpp:304:21:304:28 | call to vector | stl.cpp:310:38:310:38 | v | |
| stl.cpp:304:21:304:28 | call to vector | stl.cpp:310:55:310:55 | v | |
| stl.cpp:304:21:304:28 | call to vector | stl.cpp:314:15:314:15 | v | |
| stl.cpp:306:14:306:14 | call to begin | stl.cpp:306:14:306:14 | (__begin) | |
| stl.cpp:306:14:306:14 | call to begin | stl.cpp:306:14:306:14 | (__begin) | |
| stl.cpp:306:14:306:14 | call to begin | stl.cpp:306:14:306:14 | (__begin) | |
| stl.cpp:306:14:306:14 | call to end | stl.cpp:306:14:306:14 | (__end) | |
| stl.cpp:306:14:306:14 | call to operator* | stl.cpp:307:8:307:8 | x | |
| stl.cpp:306:14:306:14 | ref arg (__begin) | stl.cpp:306:14:306:14 | (__begin) | |
| stl.cpp:306:14:306:14 | ref arg (__begin) | stl.cpp:306:14:306:14 | (__begin) | |
| stl.cpp:306:14:306:14 | ref arg (__begin) | stl.cpp:306:14:306:14 | (__begin) | |
| stl.cpp:306:14:306:14 | ref arg (__range) | stl.cpp:306:14:306:14 | (__range) | |
| stl.cpp:306:14:306:14 | v | stl.cpp:306:14:306:14 | (__range) | |
| stl.cpp:306:14:306:14 | v | stl.cpp:306:14:306:14 | (__range) | |
| stl.cpp:306:14:306:14 | v | stl.cpp:306:14:306:14 | call to operator* | TAINT |
| stl.cpp:310:38:310:38 | ref arg v | stl.cpp:310:55:310:55 | v | |
| stl.cpp:310:38:310:38 | ref arg v | stl.cpp:314:15:314:15 | v | |
| stl.cpp:310:40:310:44 | call to begin | stl.cpp:310:49:310:50 | it | |
| stl.cpp:310:40:310:44 | call to begin | stl.cpp:310:66:310:67 | it | |
| stl.cpp:310:40:310:44 | call to begin | stl.cpp:311:9:311:10 | it | |
| stl.cpp:310:55:310:55 | ref arg v | stl.cpp:310:55:310:55 | v | |
| stl.cpp:310:55:310:55 | ref arg v | stl.cpp:314:15:314:15 | v | |
| stl.cpp:310:66:310:67 | ref arg it | stl.cpp:310:49:310:50 | it | |
| stl.cpp:310:66:310:67 | ref arg it | stl.cpp:310:66:310:67 | it | |
| stl.cpp:310:66:310:67 | ref arg it | stl.cpp:311:9:311:10 | it | |
| stl.cpp:314:15:314:15 | call to begin | stl.cpp:314:15:314:15 | (__begin) | |
| stl.cpp:314:15:314:15 | call to begin | stl.cpp:314:15:314:15 | (__begin) | |
| stl.cpp:314:15:314:15 | call to begin | stl.cpp:314:15:314:15 | (__begin) | |
| stl.cpp:314:15:314:15 | call to end | stl.cpp:314:15:314:15 | (__end) | |
| stl.cpp:314:15:314:15 | call to operator* | stl.cpp:315:8:315:8 | x | |
| stl.cpp:314:15:314:15 | ref arg (__begin) | stl.cpp:314:15:314:15 | (__begin) | |
| stl.cpp:314:15:314:15 | ref arg (__begin) | stl.cpp:314:15:314:15 | (__begin) | |
| stl.cpp:314:15:314:15 | ref arg (__begin) | stl.cpp:314:15:314:15 | (__begin) | |
| stl.cpp:314:15:314:15 | ref arg (__range) | stl.cpp:314:15:314:15 | (__range) | |
| stl.cpp:314:15:314:15 | v | stl.cpp:314:15:314:15 | (__range) | |
| stl.cpp:314:15:314:15 | v | stl.cpp:314:15:314:15 | (__range) | |
| stl.cpp:314:15:314:15 | v | stl.cpp:314:15:314:15 | call to operator* | TAINT |
| stl.cpp:318:33:318:39 | source1 | stl.cpp:318:33:318:40 | call to vector | TAINT |
| stl.cpp:318:33:318:40 | call to vector | stl.cpp:319:21:319:27 | const_v | |
| stl.cpp:319:21:319:21 | call to begin | stl.cpp:319:21:319:21 | (__begin) | |
| stl.cpp:319:21:319:21 | call to begin | stl.cpp:319:21:319:21 | (__begin) | |
| stl.cpp:319:21:319:21 | call to begin | stl.cpp:319:21:319:21 | (__begin) | |
| stl.cpp:319:21:319:21 | call to end | stl.cpp:319:21:319:21 | (__end) | |
| stl.cpp:319:21:319:21 | call to operator* | stl.cpp:320:8:320:8 | x | |
| stl.cpp:319:21:319:21 | ref arg (__begin) | stl.cpp:319:21:319:21 | (__begin) | |
| stl.cpp:319:21:319:21 | ref arg (__begin) | stl.cpp:319:21:319:21 | (__begin) | |
| stl.cpp:319:21:319:21 | ref arg (__begin) | stl.cpp:319:21:319:21 | (__begin) | |
| stl.cpp:319:21:319:27 | const_v | stl.cpp:319:21:319:21 | (__range) | |
| stl.cpp:319:21:319:27 | const_v | stl.cpp:319:21:319:21 | (__range) | |
| stl.cpp:319:21:319:27 | const_v | stl.cpp:319:21:319:21 | call to operator* | TAINT |
| stl.cpp:331:18:331:24 | hello | stl.cpp:331:18:331:25 | call to basic_string | TAINT |
| stl.cpp:331:18:331:25 | call to basic_string | stl.cpp:334:8:334:9 | s1 | |
| stl.cpp:331:18:331:25 | call to basic_string | stl.cpp:334:13:334:14 | s1 | |
| stl.cpp:331:18:331:25 | call to basic_string | stl.cpp:335:8:335:9 | s1 | |
| stl.cpp:331:18:331:25 | call to basic_string | stl.cpp:336:13:336:14 | s1 | |
| stl.cpp:331:18:331:25 | call to basic_string | stl.cpp:339:8:339:9 | s1 | |
| stl.cpp:331:18:331:25 | call to basic_string | stl.cpp:340:8:340:9 | s1 | |
| stl.cpp:332:18:332:23 | call to source | stl.cpp:332:18:332:26 | call to basic_string | TAINT |
| stl.cpp:332:18:332:26 | call to basic_string | stl.cpp:335:13:335:14 | s2 | |
| stl.cpp:332:18:332:26 | call to basic_string | stl.cpp:336:8:336:9 | s2 | |
| stl.cpp:332:18:332:26 | call to basic_string | stl.cpp:337:8:337:9 | s2 | |
| stl.cpp:332:18:332:26 | call to basic_string | stl.cpp:337:13:337:14 | s2 | |
| stl.cpp:334:8:334:9 | s1 | stl.cpp:334:11:334:11 | call to operator+ | TAINT |
| stl.cpp:334:13:334:14 | s1 | stl.cpp:334:11:334:11 | call to operator+ | TAINT |
| stl.cpp:335:8:335:9 | s1 | stl.cpp:335:11:335:11 | call to operator+ | TAINT |
| stl.cpp:335:13:335:14 | s2 | stl.cpp:335:11:335:11 | call to operator+ | TAINT |
| stl.cpp:336:8:336:9 | s2 | stl.cpp:336:11:336:11 | call to operator+ | TAINT |
| stl.cpp:336:13:336:14 | s1 | stl.cpp:336:11:336:11 | call to operator+ | TAINT |
| stl.cpp:337:8:337:9 | s2 | stl.cpp:337:11:337:11 | call to operator+ | TAINT |
| stl.cpp:337:13:337:14 | s2 | stl.cpp:337:11:337:11 | call to operator+ | TAINT |
| stl.cpp:339:8:339:9 | s1 | stl.cpp:339:11:339:11 | call to operator+ | TAINT |
| stl.cpp:339:13:339:20 | world | stl.cpp:339:11:339:11 | call to operator+ | TAINT |
| stl.cpp:340:8:340:9 | s1 | stl.cpp:340:11:340:11 | call to operator+ | TAINT |
| stl.cpp:340:13:340:18 | call to source | stl.cpp:340:11:340:11 | call to operator+ | TAINT |
| stl.cpp:344:18:344:22 | abc | stl.cpp:344:18:344:23 | call to basic_string | TAINT |
| stl.cpp:344:18:344:23 | call to basic_string | stl.cpp:348:8:348:9 | s3 | |
| stl.cpp:344:18:344:23 | call to basic_string | stl.cpp:351:8:351:9 | s3 | |
| stl.cpp:344:18:344:23 | call to basic_string | stl.cpp:355:8:355:9 | s3 | |
| stl.cpp:344:18:344:23 | call to basic_string | stl.cpp:360:8:360:9 | s3 | |
| stl.cpp:344:18:344:23 | call to basic_string | stl.cpp:364:8:364:9 | s3 | |
| stl.cpp:345:18:345:23 | call to source | stl.cpp:345:18:345:26 | call to basic_string | TAINT |
| stl.cpp:345:18:345:26 | call to basic_string | stl.cpp:348:13:348:14 | s4 | |
| stl.cpp:345:18:345:26 | call to basic_string | stl.cpp:352:9:352:10 | s4 | |
| stl.cpp:345:18:345:26 | call to basic_string | stl.cpp:361:13:361:14 | s4 | |
| stl.cpp:348:8:348:9 | s3 | stl.cpp:348:11:348:11 | call to operator+ | TAINT |
| stl.cpp:348:11:348:11 | call to operator+ | stl.cpp:348:3:348:14 | ... = ... | |
| stl.cpp:348:11:348:11 | call to operator+ | stl.cpp:349:8:349:9 | s5 | |
| stl.cpp:348:13:348:14 | s4 | stl.cpp:348:11:348:11 | call to operator+ | TAINT |
| stl.cpp:351:8:351:9 | s3 | stl.cpp:351:3:351:9 | ... = ... | |
| stl.cpp:351:8:351:9 | s3 | stl.cpp:352:3:352:4 | s6 | |
| stl.cpp:351:8:351:9 | s3 | stl.cpp:353:8:353:9 | s6 | |
| stl.cpp:352:3:352:4 | ref arg s6 | stl.cpp:353:8:353:9 | s6 | |
| stl.cpp:352:9:352:10 | s4 | stl.cpp:352:3:352:4 | ref arg s6 | TAINT |
| stl.cpp:352:9:352:10 | s4 | stl.cpp:352:6:352:6 | call to operator+= | TAINT |
| stl.cpp:355:8:355:9 | s3 | stl.cpp:355:3:355:9 | ... = ... | |
| stl.cpp:355:8:355:9 | s3 | stl.cpp:356:3:356:4 | s7 | |
| stl.cpp:355:8:355:9 | s3 | stl.cpp:357:3:357:4 | s7 | |
| stl.cpp:355:8:355:9 | s3 | stl.cpp:358:8:358:9 | s7 | |
| stl.cpp:356:3:356:4 | ref arg s7 | stl.cpp:357:3:357:4 | s7 | |
| stl.cpp:356:3:356:4 | ref arg s7 | stl.cpp:358:8:358:9 | s7 | |
| stl.cpp:356:9:356:14 | call to source | stl.cpp:356:3:356:4 | ref arg s7 | TAINT |
| stl.cpp:356:9:356:14 | call to source | stl.cpp:356:6:356:6 | call to operator+= | TAINT |
| stl.cpp:357:3:357:4 | ref arg s7 | stl.cpp:358:8:358:9 | s7 | |
| stl.cpp:357:9:357:11 | | stl.cpp:357:3:357:4 | ref arg s7 | TAINT |
| stl.cpp:357:9:357:11 | | stl.cpp:357:6:357:6 | call to operator+= | TAINT |
| stl.cpp:360:8:360:9 | s3 | stl.cpp:360:3:360:9 | ... = ... | |
| stl.cpp:360:8:360:9 | s3 | stl.cpp:361:3:361:4 | s8 | |
| stl.cpp:360:8:360:9 | s3 | stl.cpp:362:8:362:9 | s8 | |
| stl.cpp:361:3:361:4 | ref arg s8 | stl.cpp:362:8:362:9 | s8 | |
| stl.cpp:361:13:361:14 | s4 | stl.cpp:361:3:361:4 | ref arg s8 | TAINT |
| stl.cpp:361:13:361:14 | s4 | stl.cpp:361:6:361:11 | call to append | TAINT |
| stl.cpp:364:8:364:9 | s3 | stl.cpp:364:3:364:9 | ... = ... | |
| stl.cpp:364:8:364:9 | s3 | stl.cpp:365:3:365:4 | s9 | |
| stl.cpp:364:8:364:9 | s3 | stl.cpp:366:3:366:4 | s9 | |
| stl.cpp:364:8:364:9 | s3 | stl.cpp:367:8:367:9 | s9 | |
| stl.cpp:365:3:365:4 | ref arg s9 | stl.cpp:366:3:366:4 | s9 | |
| stl.cpp:365:3:365:4 | ref arg s9 | stl.cpp:367:8:367:9 | s9 | |
| stl.cpp:365:13:365:18 | call to source | stl.cpp:365:3:365:4 | ref arg s9 | TAINT |
| stl.cpp:365:13:365:18 | call to source | stl.cpp:365:6:365:11 | call to append | TAINT |
| stl.cpp:366:3:366:4 | ref arg s9 | stl.cpp:367:8:367:9 | s9 | |
| stl.cpp:366:13:366:15 | | stl.cpp:366:3:366:4 | ref arg s9 | TAINT |
| stl.cpp:366:13:366:15 | | stl.cpp:366:6:366:11 | call to append | TAINT |
| stl.cpp:371:19:371:23 | abc | stl.cpp:371:19:371:24 | call to basic_string | TAINT |
| stl.cpp:371:19:371:24 | call to basic_string | stl.cpp:374:3:374:5 | s10 | |
| stl.cpp:371:19:371:24 | call to basic_string | stl.cpp:375:8:375:10 | s10 | |
| stl.cpp:372:12:372:26 | call to source | stl.cpp:374:17:374:17 | c | |
| stl.cpp:374:3:374:5 | ref arg s10 | stl.cpp:375:8:375:10 | s10 | |
| stl.cpp:374:17:374:17 | c | stl.cpp:374:3:374:5 | ref arg s10 | TAINT |
| stl.cpp:374:17:374:17 | c | stl.cpp:374:7:374:12 | call to append | 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 | 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

@@ -30,11 +30,14 @@ namespace std
template <class T> class allocator {
public:
allocator() throw();
typedef size_t size_type;
};
template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
class basic_string {
public:
typedef typename Allocator::size_type size_type;
explicit basic_string(const Allocator& a = Allocator());
basic_string(const charT* s, const Allocator& a = Allocator());
@@ -49,8 +52,17 @@ namespace std
const_iterator end() const;
const_iterator cbegin() const;
const_iterator cend() const;
template<class T> basic_string& operator+=(const T& t);
basic_string& operator+=(const charT* s);
basic_string& append(const basic_string& str);
basic_string& append(const charT* s);
basic_string& append(size_type n, charT c);
};
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs);
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
typedef basic_string<char> string;
template <class charT, class traits = char_traits<charT> >
@@ -308,3 +320,58 @@ void test_range_based_for_loop_vector(int source1) {
sink(x); // tainted [NOT DETECTED by IR]
}
}
namespace ns_char
{
char source();
}
void test_string_append() {
{
std::string s1("hello");
std::string s2(source());
sink(s1 + s1);
sink(s1 + s2); // tainted
sink(s2 + s1); // tainted
sink(s2 + s2); // tainted
sink(s1 + " world");
sink(s1 + source()); // tainted
}
{
std::string s3("abc");
std::string s4(source());
std::string s5, s6, s7, s8, s9;
s5 = s3 + s4;
sink(s5); // tainted
s6 = s3;
s6 += s4;
sink(s6); // tainted
s7 = s3;
s7 += source();
s7 += " ";
sink(s7); // tainted
s8 = s3;
s8.append(s4);
sink(s8); // tainted
s9 = s3;
s9.append(source());
s9.append(" ");
sink(s9); // tainted
}
{
std::string s10("abc");
char c = ns_char::source();
s10.append(1, c);
sink(s10); // tainted
}
}

View File

@@ -32,27 +32,37 @@
| movableclass.cpp:55:8:55:9 | s2 | movableclass.cpp:52:23:52:28 | call to source |
| movableclass.cpp:64:8:64:9 | s2 | movableclass.cpp:23:55:23:60 | call to source |
| movableclass.cpp:65:11:65:11 | call to operator= | movableclass.cpp:65:13:65:18 | call to source |
| stl.cpp:101:7:101:7 | a | stl.cpp:97:12:97:17 | call to source |
| stl.cpp:103:7:103:7 | c | stl.cpp:99:16:99:21 | call to source |
| stl.cpp:105:9:105:13 | call to c_str | stl.cpp:99:16:99:21 | call to source |
| stl.cpp:155:13:155:17 | call to c_str | stl.cpp:147:10:147:15 | call to source |
| stl.cpp:159:13:159:17 | call to c_str | stl.cpp:147:10:147:15 | call to source |
| stl.cpp:162:13:162:17 | call to c_str | stl.cpp:147:10:147:15 | call to source |
| stl.cpp:172:7:172:8 | cs | stl.cpp:167:19:167:24 | call to source |
| stl.cpp:173:7:173:8 | ss | stl.cpp:167:19:167:24 | call to source |
| stl.cpp:186:7:186:8 | cs | stl.cpp:178:19:178:24 | call to source |
| stl.cpp:187:7:187:8 | ss | stl.cpp:178:19:178:24 | call to source |
| stl.cpp:209:8:209:9 | s1 | stl.cpp:204:18:204:23 | call to source |
| stl.cpp:210:8:210:9 | s2 | stl.cpp:205:20:205:25 | call to source |
| stl.cpp:211:8:211:9 | s3 | stl.cpp:207:8:207:13 | call to source |
| stl.cpp:230:8:230:9 | s1 | stl.cpp:226:32:226:37 | call to source |
| stl.cpp:231:8:231:9 | s2 | stl.cpp:228:20:228:25 | call to source |
| stl.cpp:240:8:240:8 | c | stl.cpp:238:16:238:21 | call to source |
| stl.cpp:248:8:248:8 | c | stl.cpp:238:16:238:21 | call to source |
| stl.cpp:253:8:253:8 | c | stl.cpp:251:28:251:33 | call to source |
| stl.cpp:295:8:295:8 | x | stl.cpp:288:43:288:49 | source1 |
| stl.cpp:303:8:303:8 | x | stl.cpp:288:43:288:49 | source1 |
| stl.cpp:308:8:308:8 | x | stl.cpp:288:43:288:49 | source1 |
| stl.cpp:113:7:113:7 | a | stl.cpp:109:12:109:17 | call to source |
| stl.cpp:115:7:115:7 | c | stl.cpp:111:16:111:21 | call to source |
| stl.cpp:117:9:117:13 | call to c_str | stl.cpp:111:16:111:21 | call to source |
| stl.cpp:167:13:167:17 | call to c_str | stl.cpp:159:10:159:15 | call to source |
| stl.cpp:171:13:171:17 | call to c_str | stl.cpp:159:10:159:15 | call to source |
| stl.cpp:174:13:174:17 | call to c_str | stl.cpp:159:10:159:15 | call to source |
| stl.cpp:184:7:184:8 | cs | stl.cpp:179:19:179:24 | call to source |
| stl.cpp:185:7:185:8 | ss | stl.cpp:179:19:179:24 | call to source |
| stl.cpp:198:7:198:8 | cs | stl.cpp:190:19:190:24 | call to source |
| stl.cpp:199:7:199:8 | ss | stl.cpp:190:19:190:24 | call to source |
| stl.cpp:221:8:221:9 | s1 | stl.cpp:216:18:216:23 | call to source |
| stl.cpp:222:8:222:9 | s2 | stl.cpp:217:20:217:25 | call to source |
| stl.cpp:223:8:223:9 | s3 | stl.cpp:219:8:219:13 | call to source |
| stl.cpp:242:8:242:9 | s1 | stl.cpp:238:32:238:37 | call to source |
| stl.cpp:243:8:243:9 | s2 | stl.cpp:240:20:240:25 | call to source |
| stl.cpp:252:8:252:8 | c | stl.cpp:250:16:250:21 | call to source |
| stl.cpp:260:8:260:8 | c | stl.cpp:250:16:250:21 | call to source |
| stl.cpp:265:8:265:8 | c | stl.cpp:263:28:263:33 | call to source |
| stl.cpp:307:8:307:8 | x | stl.cpp:300:43:300:49 | source1 |
| stl.cpp:315:8:315:8 | x | stl.cpp:300:43:300:49 | source1 |
| stl.cpp:320:8:320:8 | x | stl.cpp:300:43:300:49 | source1 |
| stl.cpp:335:11:335:11 | call to operator+ | stl.cpp:332:18:332:23 | call to source |
| stl.cpp:336:11:336:11 | call to operator+ | stl.cpp:332:18:332:23 | call to source |
| stl.cpp:337:11:337:11 | call to operator+ | stl.cpp:332:18:332:23 | call to source |
| stl.cpp:340:11:340:11 | call to operator+ | stl.cpp:340:13:340:18 | call to source |
| stl.cpp:349:8:349:9 | s5 | stl.cpp:345:18:345:23 | call to source |
| stl.cpp:353:8:353:9 | s6 | stl.cpp:345:18:345:23 | call to source |
| stl.cpp:358:8:358:9 | s7 | stl.cpp:356:9:356:14 | call to source |
| stl.cpp:362:8:362:9 | s8 | stl.cpp:345:18:345:23 | call to source |
| stl.cpp:367:8:367:9 | s9 | stl.cpp:365:13:365:18 | call to source |
| stl.cpp:375:8:375:10 | s10 | stl.cpp:372:12:372:26 | 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

@@ -30,26 +30,36 @@
| movableclass.cpp:55:8:55:9 | movableclass.cpp:52:23:52:28 | AST only |
| movableclass.cpp:64:8:64:9 | movableclass.cpp:23:55:23:60 | AST only |
| movableclass.cpp:65:11:65:11 | movableclass.cpp:65:13:65:18 | AST only |
| stl.cpp:103:7:103:7 | stl.cpp:99:16:99:21 | AST only |
| stl.cpp:105:9:105:13 | stl.cpp:99:16:99:21 | AST only |
| stl.cpp:155:13:155:17 | stl.cpp:147:10:147:15 | AST only |
| stl.cpp:159:13:159:17 | stl.cpp:147:10:147:15 | AST only |
| stl.cpp:162:13:162:17 | stl.cpp:147:10:147:15 | AST only |
| stl.cpp:172:7:172:8 | stl.cpp:167:19:167:26 | IR only |
| stl.cpp:173:7:173:8 | stl.cpp:167:19:167:24 | AST only |
| stl.cpp:186:7:186:8 | stl.cpp:178:19:178:24 | AST only |
| stl.cpp:187:7:187:8 | stl.cpp:178:19:178:24 | AST only |
| stl.cpp:209:8:209:9 | stl.cpp:204:18:204:23 | AST only |
| stl.cpp:210:8:210:9 | stl.cpp:205:20:205:25 | AST only |
| stl.cpp:211:8:211:9 | stl.cpp:207:8:207:13 | AST only |
| stl.cpp:230:8:230:9 | stl.cpp:226:32:226:37 | AST only |
| stl.cpp:231:8:231:9 | stl.cpp:228:20:228:25 | AST only |
| stl.cpp:240:8:240:8 | stl.cpp:238:16:238:21 | AST only |
| stl.cpp:248:8:248:8 | stl.cpp:238:16:238:21 | AST only |
| stl.cpp:253:8:253:8 | stl.cpp:251:28:251:33 | AST only |
| stl.cpp:295:8:295:8 | stl.cpp:288:43:288:49 | AST only |
| stl.cpp:303:8:303:8 | stl.cpp:288:43:288:49 | AST only |
| stl.cpp:308:8:308:8 | stl.cpp:288:43:288:49 | AST only |
| stl.cpp:115:7:115:7 | stl.cpp:111:16:111:21 | AST only |
| stl.cpp:117:9:117:13 | stl.cpp:111:16:111:21 | AST only |
| stl.cpp:167:13:167:17 | stl.cpp:159:10:159:15 | AST only |
| stl.cpp:171:13:171:17 | stl.cpp:159:10:159:15 | AST only |
| stl.cpp:174:13:174:17 | stl.cpp:159:10:159:15 | AST only |
| stl.cpp:184:7:184:8 | stl.cpp:179:19:179:26 | IR only |
| stl.cpp:185:7:185:8 | stl.cpp:179:19:179:24 | AST only |
| stl.cpp:198:7:198:8 | stl.cpp:190:19:190:24 | AST only |
| stl.cpp:199:7:199:8 | stl.cpp:190:19:190:24 | AST only |
| stl.cpp:221:8:221:9 | stl.cpp:216:18:216:23 | AST only |
| stl.cpp:222:8:222:9 | stl.cpp:217:20:217:25 | AST only |
| stl.cpp:223:8:223:9 | stl.cpp:219:8:219:13 | AST only |
| stl.cpp:242:8:242:9 | stl.cpp:238:32:238:37 | AST only |
| stl.cpp:243:8:243:9 | stl.cpp:240:20:240:25 | AST only |
| stl.cpp:252:8:252:8 | stl.cpp:250:16:250:21 | AST only |
| stl.cpp:260:8:260:8 | stl.cpp:250:16:250:21 | AST only |
| stl.cpp:265:8:265:8 | stl.cpp:263:28:263:33 | AST only |
| stl.cpp:307:8:307:8 | stl.cpp:300:43:300:49 | AST only |
| stl.cpp:315:8:315:8 | stl.cpp:300:43:300:49 | AST only |
| stl.cpp:320:8:320:8 | stl.cpp:300:43:300:49 | AST only |
| stl.cpp:335:11:335:11 | stl.cpp:332:18:332:23 | AST only |
| stl.cpp:336:11:336:11 | stl.cpp:332:18:332:23 | AST only |
| stl.cpp:337:11:337:11 | stl.cpp:332:18:332:23 | AST only |
| stl.cpp:340:11:340:11 | stl.cpp:340:13:340:18 | AST only |
| stl.cpp:349:8:349:9 | stl.cpp:345:18:345:23 | AST only |
| stl.cpp:353:8:353:9 | stl.cpp:345:18:345:23 | AST only |
| stl.cpp:358:8:358:9 | stl.cpp:356:9:356:14 | AST only |
| stl.cpp:362:8:362:9 | stl.cpp:345:18:345:23 | AST only |
| stl.cpp:367:8:367:9 | stl.cpp:365:13:365:18 | AST only |
| stl.cpp:375:8:375:10 | stl.cpp:372:12:372:26 | AST only |
| structlikeclass.cpp:35:8:35:9 | structlikeclass.cpp:29:22:29:27 | AST only |
| structlikeclass.cpp:36:8:36:9 | structlikeclass.cpp:30:24:30:29 | AST only |
| structlikeclass.cpp:37:8:37:9 | structlikeclass.cpp:29:22:29:27 | AST only |

View File

@@ -1,10 +1,10 @@
| format.cpp:157:7:157:22 | (int)... | format.cpp:147:12:147:25 | call to source |
| format.cpp:157:7:157:22 | access to array | format.cpp:147:12:147:25 | call to source |
| format.cpp:158:7:158:27 | ... + ... | format.cpp:148:16:148:30 | call to source |
| stl.cpp:101:7:101:7 | (const char *)... | stl.cpp:97:12:97:17 | call to source |
| stl.cpp:101:7:101:7 | a | stl.cpp:97:12:97:17 | call to source |
| stl.cpp:172:7:172:8 | cs | stl.cpp:167:19:167:24 | call to source |
| stl.cpp:172:7:172:8 | cs | stl.cpp:167:19:167:26 | (const char *)... |
| stl.cpp:113:7:113:7 | (const char *)... | stl.cpp:109:12:109:17 | call to source |
| stl.cpp:113:7:113:7 | a | stl.cpp:109:12:109:17 | call to source |
| stl.cpp:184:7:184:8 | cs | stl.cpp:179:19:179:24 | call to source |
| stl.cpp:184:7:184:8 | cs | stl.cpp:179:19:179:26 | (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 |

View File

@@ -1,4 +1,4 @@
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
from VariableAccess expr
select expr, lowerBound(expr)
select expr, lowerBound(expr).toString()

View File

@@ -463,3 +463,30 @@ int test_unsigned_mult02(unsigned b) {
return total;
}
unsigned long mult_rounding() {
unsigned long x, y, xy;
x = y = 1000000003UL; // 1e9 + 3
xy = x * y;
return xy; // BUG: upper bound should be >= 1000000006000000009UL
}
unsigned long mult_overflow() {
unsigned long x, y, xy;
x = 274177UL;
y = 67280421310721UL;
xy = x * y;
return xy; // BUG: lower bound should be <= 18446744073709551617UL
}
unsigned long mult_lower_bound(unsigned int ui, unsigned long ul) {
if (ui >= 10) {
unsigned long result = (unsigned long)ui * ui;
return result; // BUG: upper bound should be >= 18446744065119617025 (possibly a pretty-printing bug)
}
if (ul >= 10) {
unsigned long result = ul * ul;
return result; // lower bound is correctly 0 (overflow is possible)
}
return 0;
}

View File

@@ -1,4 +1,4 @@
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
from VariableAccess expr
select expr, upperBound(expr)
select expr, upperBound(expr).toString()

View File

@@ -385,10 +385,39 @@ void bitwise_ands()
void unsigned_mult(unsigned int x, unsigned int y) {
if(x < 13 && y < 35) {
if(x * y > 1024) {} // always false [NOT DETECTED]
if(x * y > 1024) {} // always false
if(x * y < 204) {}
if(x >= 3 && y >= 2) {
if(x * y < 5) {} // always false [NOT DETECTED]
if(x * y < 5) {} // always false
}
}
}
}
void mult_rounding() {
unsigned long x, y, xy;
x = y = 1000000003UL; // 1e9 + 3
xy = 1000000006000000009UL; // x * y, precisely
// Even though the range analysis wrongly considers x*y to be xy - 9, there
// are no PointlessComparison false positives in these tests because alerts
// are suppressed when ulp() < 1, which roughly means that the number is
// larger than 2^53.
if (x * y < xy) {} // always false [NOT DETECTED]
if (x * y > xy) {} // always false [NOT DETECTED]
}
void mult_overflow() {
unsigned long x, y;
// The following two numbers multiply to 2^64 + 1, which is 1 when truncated
// to 64-bit unsigned.
x = 274177UL;
y = 67280421310721UL;
if (x * y == 1) {} // always true [BUG: reported as always false]
// This bug appears to be caused by
// `RangeAnalysisUtils::typeUpperBound(unsigned long)` having a result of
// 2**64 + 384, making the range analysis think that the multiplication can't
// overflow. The correct `typeUpperBound` would be 2**64 - 1, but we can't
// represent that with a QL float or int. We could make `typeUpperBound`
// exclusive instead of inclusive, but there is no exclusive upper bound for
// floats.
}

View File

@@ -41,6 +41,9 @@
| PointlessComparison.c:372:6:372:16 | ... >= ... | Comparison is always true because ... >> ... >= 1. |
| PointlessComparison.c:373:6:373:16 | ... >= ... | Comparison is always false because ... >> ... <= 1. |
| PointlessComparison.c:383:6:383:17 | ... >= ... | Comparison is always false because ... & ... <= 2. |
| PointlessComparison.c:388:10:388:21 | ... > ... | Comparison is always false because ... * ... <= 408. |
| PointlessComparison.c:391:12:391:20 | ... < ... | Comparison is always false because ... * ... >= 6. |
| PointlessComparison.c:414:7:414:16 | ... == ... | Comparison is always false because ... * ... >= 18446744073709552000. |
| PointlessComparison.cpp:36:6:36:33 | ... >= ... | Comparison is always false because ... >> ... <= 9223372036854776000. |
| PointlessComparison.cpp:41:6:41:29 | ... >= ... | Comparison is always false because ... >> ... <= 140737488355327.5. |
| PointlessComparison.cpp:42:6:42:29 | ... >= ... | Comparison is always false because ... >> ... <= 140737488355327.5. |

View File

@@ -17,7 +17,7 @@ import PathGraph
*/
private string getACredentialRegex() {
result = "(?i).*challenge|pass(wd|word|code|phrase)(?!.*question).*" or
result = "(?i)(.*username|url).*"
result = "(?i)(.*username|.*secret|url).*"
}
/** Variable keeps sensitive information judging by its name * */
@@ -31,8 +31,12 @@ class CredentialExpr extends Expr {
class LoggerType extends RefType {
LoggerType() {
this.hasQualifiedName("org.apache.log4j", "Category") or //Log4J
this.hasQualifiedName("org.apache.logging.log4j", "Logger") or //Log4J 2
this.hasQualifiedName("org.slf4j", "Logger") or //SLF4j and Gradle Logging
this.hasQualifiedName("org.jboss.logging", "BasicLogger") //JBoss Logging
this.hasQualifiedName("org.jboss.logging", "BasicLogger") or //JBoss Logging
this.hasQualifiedName("org.jboss.logging", "Logger") or //JBoss Logging (`org.jboss.logging.Logger` in some implementations like JBoss Application Server 4.0.4 did not implement `BasicLogger`)
this.hasQualifiedName("org.apache.commons.logging", "Log") or //Apache Commons Logging
this.hasQualifiedName("org.scijava.log", "Logger") //SciJava Logging
}
}
@@ -42,7 +46,8 @@ predicate isSensitiveLoggingSink(DataFlow::Node sink) {
(
ma.getMethod().hasName("debug") or
ma.getMethod().hasName("trace") or
ma.getMethod().hasName("debugf")
ma.getMethod().hasName("debugf") or
ma.getMethod().hasName("debugv")
) and //Check low priority log levels which are more likely to be real issues to reduce false positives
sink.asExpr() = ma.getAnArgument()
)

View File

@@ -1344,10 +1344,7 @@ class VarAccess extends Expr, @varaccess {
*/
predicate isLValue() {
exists(Assignment a | a.getDest() = this) or
exists(PreIncExpr e | e.getExpr() = this) or
exists(PreDecExpr e | e.getExpr() = this) or
exists(PostIncExpr e | e.getExpr() = this) or
exists(PostDecExpr e | e.getExpr() = this)
exists(UnaryAssignExpr e | e.getExpr() = this)
}
/**

View File

@@ -97,6 +97,7 @@ class WritingMethod extends Method {
(
this.getName().matches("print%") or
this.getName() = "append" or
this.getName() = "format" or
this.getName() = "write"
)
}

View File

@@ -210,6 +210,7 @@ public class AutoBuild {
private final String defaultEncoding;
private ExecutorService threadPool;
private volatile boolean seenCode = false;
private volatile boolean seenFiles = false;
private boolean installDependencies = false;
private int installDependenciesTimeout;
private final VirtualSourceRoot virtualSourceRoot;
@@ -472,7 +473,11 @@ public class AutoBuild {
shutdownThreadPool();
}
if (!seenCode) {
warn("No JavaScript or TypeScript code found.");
if (seenFiles) {
warn("Only found JavaScript or TypeScript files that were empty or contained syntax errors.");
} else {
warn("No JavaScript or TypeScript code found.");
}
return -1;
}
return 0;
@@ -1201,6 +1206,7 @@ protected DependencyInstallationResult preparePackagesAndDependencies(Set<Path>
long start = logBeginProcess("Extracting " + file);
Integer loc = extractor.extract(f, state);
if (!extractor.getConfig().isExterns() && (loc == null || loc != 0)) seenCode = true;
if (!extractor.getConfig().isExterns()) seenFiles = true;
logEndProcess(start, "Done extracting " + file);
} catch (Throwable t) {
System.err.println("Exception while extracting " + file + ".");

View File

@@ -97,8 +97,65 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
//--------
// Global flow
//--------
/**
* IPA type for DataFlowCallable.
* A callable is either a callable value or a class.
*/
newtype TDataFlowCallable =
TCallableValue(CallableValue callable) or
TClassValue(ClassValue c)
/** Represents a callable */
class DataFlowCallable = CallableValue;
abstract class DataFlowCallable extends TDataFlowCallable {
/** Gets a textual representation of this element. */
abstract string toString();
/** Gets a call to this callable. */
abstract CallNode getACall();
/** Gets the scope of this callable */
abstract Scope getScope();
/** Gets the specified parameter of this callable */
abstract NameNode getParameter(int n);
/** Gets the name of this callable. */
abstract string getName();
}
class DataFlowCallableValue extends DataFlowCallable, TCallableValue {
CallableValue callable;
DataFlowCallableValue() { this = TCallableValue(callable) }
override string toString() { result = callable.toString() }
override CallNode getACall() { result = callable.getACall() }
override Scope getScope() { result = callable.getScope() }
override NameNode getParameter(int n) { result = callable.getParameter(n) }
override string getName() { result = callable.getName() }
}
class DataFlowClassValue extends DataFlowCallable, TClassValue {
ClassValue c;
DataFlowClassValue() { this = TClassValue(c) }
override string toString() { result = c.toString() }
override CallNode getACall() { result = c.getACall() }
override Scope getScope() { result = c.getScope() }
override NameNode getParameter(int n) {
result.getNode() = c.getScope().getInitMethod().getArg(n + 1).asName()
}
override string getName() { result = c.getName() }
}
/** Represents a call to a callable */
class DataFlowCall extends CallNode {

View File

@@ -1,4 +1,4 @@
import callGraphConfig
import experimental.dataflow.callGraphConfig
from DataFlow::Node source, DataFlow::Node sink
where exists(CallGraphConfig cfg | cfg.hasFlow(source, sink))

View File

@@ -1,4 +1,4 @@
import callGraphConfig
import experimental.dataflow.callGraphConfig
from DataFlow::Node sink
where exists(CallGraphConfig cfg | cfg.isSink(sink))

View File

@@ -1,4 +1,4 @@
import callGraphConfig
import experimental.dataflow.callGraphConfig
from DataFlow::Node source
where exists(CallGraphConfig cfg | cfg.isSource(source))

View File

@@ -101,3 +101,5 @@ argHasPostUpdate
| test.py:74:17:74:17 | ControlFlowNode for t | ArgumentNode is missing PostUpdateNode. |
| test.py:81:13:81:13 | ControlFlowNode for t | ArgumentNode is missing PostUpdateNode. |
| test.py:86:13:86:13 | ControlFlowNode for t | ArgumentNode is missing PostUpdateNode. |
| test.py:158:15:158:15 | ControlFlowNode for l | ArgumentNode is missing PostUpdateNode. |
| test.py:159:15:159:15 | ControlFlowNode for d | ArgumentNode is missing PostUpdateNode. |

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
| classes.py:19:12:19:31 | ControlFlowNode for Attribute() | classes.py:19:12:19:31 | ControlFlowNode for Attribute() |
| classes.py:174:7:174:22 | ControlFlowNode for set() | classes.py:174:7:174:22 | ControlFlowNode for set() |
| classes.py:178:7:178:28 | ControlFlowNode for frozenset() | classes.py:178:7:178:28 | ControlFlowNode for frozenset() |
| classes.py:182:7:182:26 | ControlFlowNode for dict() | classes.py:182:7:182:26 | ControlFlowNode for dict() |
| classes.py:303:28:303:51 | ControlFlowNode for dict() | classes.py:303:28:303:51 | ControlFlowNode for dict() |
| classes.py:466:12:466:24 | ControlFlowNode for Attribute() | classes.py:466:12:466:24 | ControlFlowNode for Attribute() |

View File

@@ -0,0 +1,10 @@
import experimental.dataflow.callGraphConfig
from DataFlow::Node source, DataFlow::Node sink
where
source.getLocation().getFile().getBaseName() = "classes.py" and
sink.getLocation().getFile().getBaseName() = "classes.py" and
exists(CallGraphConfig cfg | cfg.hasFlow(source, sink))
select source, sink
// Ideally, we would just have 1-step paths either from argument to parameter
// or from return to call. This gives a bit more, so should be rewritten.

View File

@@ -1,39 +1,167 @@
edges
| test.py:35:9:35:14 | ControlFlowNode for SOURCE | test.py:36:10:36:10 | ControlFlowNode for x |
| test.py:40:9:40:16 | ControlFlowNode for Str | test.py:41:10:41:10 | ControlFlowNode for x |
| test.py:44:9:44:17 | ControlFlowNode for Str | test.py:45:10:45:10 | ControlFlowNode for x |
| test.py:48:9:48:10 | ControlFlowNode for IntegerLiteral | test.py:49:10:49:10 | ControlFlowNode for x |
| test.py:52:9:52:12 | ControlFlowNode for FloatLiteral | test.py:53:10:53:10 | ControlFlowNode for x |
| test.py:61:10:61:15 | ControlFlowNode for SOURCE | test.py:62:10:62:10 | ControlFlowNode for x |
| test.py:238:28:238:33 | ControlFlowNode for SOURCE | test.py:238:10:238:34 | ControlFlowNode for second() |
| test.py:297:12:297:17 | ControlFlowNode for SOURCE | test.py:297:10:297:18 | ControlFlowNode for f() |
| test.py:301:28:301:33 | ControlFlowNode for SOURCE | test.py:301:10:301:34 | ControlFlowNode for second() |
| datamodel.py:13:1:13:6 | GSSA Variable SOURCE | datamodel.py:38:6:38:17 | ControlFlowNode for f() |
| datamodel.py:13:1:13:6 | GSSA Variable SOURCE | datamodel.py:38:6:38:17 | GSSA Variable SOURCE |
| datamodel.py:13:1:13:6 | GSSA Variable SOURCE | datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE |
| datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:13:1:13:6 | GSSA Variable SOURCE |
| datamodel.py:38:6:38:17 | GSSA Variable SOURCE | datamodel.py:65:5:65:7 | ControlFlowNode for C() |
| datamodel.py:38:6:38:17 | GSSA Variable SOURCE | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() |
| datamodel.py:38:6:38:17 | GSSA Variable SOURCE | datamodel.py:71:6:71:24 | GSSA Variable SOURCE |
| datamodel.py:38:6:38:17 | GSSA Variable SOURCE | datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE |
| datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:38:6:38:17 | ControlFlowNode for f() |
| datamodel.py:65:1:65:1 | GSSA Variable c | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() |
| datamodel.py:65:1:65:1 | GSSA Variable c | datamodel.py:71:6:71:24 | GSSA Variable c |
| datamodel.py:65:5:65:7 | ControlFlowNode for C() | datamodel.py:65:1:65:1 | GSSA Variable c |
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() |
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE |
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | datamodel.py:73:6:73:27 | ControlFlowNode for func_obj() |
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() |
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | datamodel.py:80:6:80:26 | GSSA Variable SOURCE |
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE |
| datamodel.py:71:6:71:24 | GSSA Variable c | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() |
| datamodel.py:71:6:71:24 | GSSA Variable c | datamodel.py:72:6:72:27 | GSSA Variable c |
| datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() |
| datamodel.py:72:6:72:27 | GSSA Variable c | datamodel.py:73:6:73:27 | ControlFlowNode for func_obj() |
| datamodel.py:72:6:72:27 | GSSA Variable c | datamodel.py:73:6:73:27 | GSSA Variable c |
| datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() |
| datamodel.py:73:6:73:27 | GSSA Variable c | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() |
| datamodel.py:73:6:73:27 | GSSA Variable c | datamodel.py:80:6:80:26 | GSSA Variable c |
| datamodel.py:80:6:80:26 | GSSA Variable SOURCE | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() |
| datamodel.py:80:6:80:26 | GSSA Variable SOURCE | datamodel.py:81:6:81:26 | GSSA Variable SOURCE |
| datamodel.py:80:6:80:26 | GSSA Variable SOURCE | datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE |
| datamodel.py:80:6:80:26 | GSSA Variable c | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() |
| datamodel.py:80:6:80:26 | GSSA Variable c | datamodel.py:82:6:82:26 | ControlFlowNode for c_func_obj() |
| datamodel.py:80:6:80:26 | GSSA Variable c | datamodel.py:92:8:92:21 | ControlFlowNode for gen() |
| datamodel.py:80:6:80:26 | GSSA Variable c | datamodel.py:93:6:93:20 | ControlFlowNode for Attribute() |
| datamodel.py:80:6:80:26 | GSSA Variable c | datamodel.py:96:9:96:24 | ControlFlowNode for Attribute() |
| datamodel.py:80:6:80:26 | GSSA Variable c | datamodel.py:96:9:96:24 | GSSA Variable c |
| datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() |
| datamodel.py:81:6:81:26 | GSSA Variable SOURCE | datamodel.py:82:6:82:26 | ControlFlowNode for c_func_obj() |
| datamodel.py:81:6:81:26 | GSSA Variable SOURCE | datamodel.py:92:8:92:21 | ControlFlowNode for gen() |
| datamodel.py:81:6:81:26 | GSSA Variable SOURCE | datamodel.py:92:8:92:21 | GSSA Variable SOURCE |
| datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() |
| datamodel.py:92:1:92:4 | GSSA Variable iter | datamodel.py:93:6:93:20 | ControlFlowNode for Attribute() |
| datamodel.py:92:1:92:4 | GSSA Variable iter | datamodel.py:93:6:93:20 | GSSA Variable iter |
| datamodel.py:92:8:92:21 | ControlFlowNode for gen() | datamodel.py:92:1:92:4 | GSSA Variable iter |
| datamodel.py:92:8:92:21 | GSSA Variable SOURCE | datamodel.py:93:6:93:20 | ControlFlowNode for Attribute() |
| datamodel.py:92:8:92:21 | GSSA Variable SOURCE | datamodel.py:96:9:96:24 | ControlFlowNode for Attribute() |
| datamodel.py:92:8:92:21 | GSSA Variable SOURCE | datamodel.py:96:9:96:24 | GSSA Variable SOURCE |
| datamodel.py:93:6:93:20 | GSSA Variable iter | datamodel.py:96:9:96:24 | ControlFlowNode for Attribute() |
| datamodel.py:93:6:93:20 | GSSA Variable iter | datamodel.py:97:6:97:21 | ControlFlowNode for Attribute() |
| datamodel.py:93:6:93:20 | GSSA Variable iter | datamodel.py:106:6:106:30 | ControlFlowNode for Attribute() |
| datamodel.py:93:6:93:20 | GSSA Variable iter | datamodel.py:107:6:107:32 | ControlFlowNode for Attribute() |
| datamodel.py:93:6:93:20 | GSSA Variable iter | datamodel.py:119:6:119:30 | ControlFlowNode for Attribute() |
| datamodel.py:96:1:96:5 | GSSA Variable oiter | datamodel.py:97:6:97:21 | ControlFlowNode for Attribute() |
| datamodel.py:96:1:96:5 | GSSA Variable oiter | datamodel.py:97:6:97:21 | GSSA Variable oiter |
| datamodel.py:96:9:96:24 | ControlFlowNode for Attribute() | datamodel.py:96:1:96:5 | GSSA Variable oiter |
| datamodel.py:96:9:96:24 | GSSA Variable SOURCE | datamodel.py:97:6:97:21 | ControlFlowNode for Attribute() |
| datamodel.py:96:9:96:24 | GSSA Variable SOURCE | datamodel.py:106:18:106:29 | GSSA Variable SOURCE |
| datamodel.py:96:9:96:24 | GSSA Variable c | datamodel.py:97:6:97:21 | ControlFlowNode for Attribute() |
| datamodel.py:96:9:96:24 | GSSA Variable c | datamodel.py:106:6:106:30 | ControlFlowNode for Attribute() |
| datamodel.py:96:9:96:24 | GSSA Variable c | datamodel.py:107:18:107:31 | GSSA Variable c |
| datamodel.py:97:6:97:21 | GSSA Variable oiter | datamodel.py:106:6:106:30 | ControlFlowNode for Attribute() |
| datamodel.py:97:6:97:21 | GSSA Variable oiter | datamodel.py:107:6:107:32 | ControlFlowNode for Attribute() |
| datamodel.py:97:6:97:21 | GSSA Variable oiter | datamodel.py:119:6:119:30 | ControlFlowNode for Attribute() |
| datamodel.py:106:18:106:29 | GSSA Variable SOURCE | datamodel.py:106:6:106:30 | ControlFlowNode for Attribute() |
| datamodel.py:106:18:106:29 | GSSA Variable SOURCE | datamodel.py:107:18:107:31 | GSSA Variable SOURCE |
| datamodel.py:107:18:107:31 | GSSA Variable SOURCE | datamodel.py:107:6:107:32 | ControlFlowNode for Attribute() |
| datamodel.py:107:18:107:31 | GSSA Variable SOURCE | datamodel.py:119:18:119:29 | GSSA Variable SOURCE |
| datamodel.py:107:18:107:31 | GSSA Variable c | datamodel.py:107:6:107:32 | ControlFlowNode for Attribute() |
| datamodel.py:107:18:107:31 | GSSA Variable c | datamodel.py:119:6:119:30 | ControlFlowNode for Attribute() |
| datamodel.py:119:18:119:29 | GSSA Variable SOURCE | datamodel.py:119:6:119:30 | ControlFlowNode for Attribute() |
| test.py:43:9:43:14 | ControlFlowNode for SOURCE | test.py:44:10:44:10 | ControlFlowNode for x |
| test.py:48:9:48:16 | ControlFlowNode for Str | test.py:49:10:49:10 | ControlFlowNode for x |
| test.py:52:9:52:17 | ControlFlowNode for Str | test.py:53:10:53:10 | ControlFlowNode for x |
| test.py:56:9:56:10 | ControlFlowNode for IntegerLiteral | test.py:57:10:57:10 | ControlFlowNode for x |
| test.py:60:9:60:12 | ControlFlowNode for FloatLiteral | test.py:61:10:61:10 | ControlFlowNode for x |
| test.py:69:10:69:15 | ControlFlowNode for SOURCE | test.py:70:10:70:10 | ControlFlowNode for x |
| test.py:246:28:246:33 | ControlFlowNode for SOURCE | test.py:246:10:246:34 | ControlFlowNode for second() |
| test.py:305:12:305:17 | ControlFlowNode for SOURCE | test.py:305:10:305:18 | ControlFlowNode for f() |
| test.py:309:28:309:33 | ControlFlowNode for SOURCE | test.py:309:10:309:34 | ControlFlowNode for second() |
nodes
| test.py:35:9:35:14 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:36:10:36:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:40:9:40:16 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
| test.py:41:10:41:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:44:9:44:17 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
| test.py:45:10:45:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:48:9:48:10 | ControlFlowNode for IntegerLiteral | semmle.label | ControlFlowNode for IntegerLiteral |
| datamodel.py:13:1:13:6 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
| datamodel.py:13:10:13:17 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
| datamodel.py:38:6:38:17 | ControlFlowNode for f() | semmle.label | ControlFlowNode for f() |
| datamodel.py:38:6:38:17 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
| datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| datamodel.py:65:1:65:1 | GSSA Variable c | semmle.label | GSSA Variable c |
| datamodel.py:65:5:65:7 | ControlFlowNode for C() | semmle.label | ControlFlowNode for C() |
| datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
| datamodel.py:71:6:71:24 | GSSA Variable c | semmle.label | GSSA Variable c |
| datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| datamodel.py:72:6:72:27 | GSSA Variable c | semmle.label | GSSA Variable c |
| datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| datamodel.py:73:6:73:27 | ControlFlowNode for func_obj() | semmle.label | ControlFlowNode for func_obj() |
| datamodel.py:73:6:73:27 | GSSA Variable c | semmle.label | GSSA Variable c |
| datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| datamodel.py:80:6:80:26 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
| datamodel.py:80:6:80:26 | GSSA Variable c | semmle.label | GSSA Variable c |
| datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| datamodel.py:81:6:81:26 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
| datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| datamodel.py:82:6:82:26 | ControlFlowNode for c_func_obj() | semmle.label | ControlFlowNode for c_func_obj() |
| datamodel.py:92:1:92:4 | GSSA Variable iter | semmle.label | GSSA Variable iter |
| datamodel.py:92:8:92:21 | ControlFlowNode for gen() | semmle.label | ControlFlowNode for gen() |
| datamodel.py:92:8:92:21 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
| datamodel.py:93:6:93:20 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| datamodel.py:93:6:93:20 | GSSA Variable iter | semmle.label | GSSA Variable iter |
| datamodel.py:96:1:96:5 | GSSA Variable oiter | semmle.label | GSSA Variable oiter |
| datamodel.py:96:9:96:24 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| datamodel.py:96:9:96:24 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
| datamodel.py:96:9:96:24 | GSSA Variable c | semmle.label | GSSA Variable c |
| datamodel.py:97:6:97:21 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| datamodel.py:97:6:97:21 | GSSA Variable oiter | semmle.label | GSSA Variable oiter |
| datamodel.py:106:6:106:30 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| datamodel.py:106:18:106:29 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
| datamodel.py:107:6:107:32 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| datamodel.py:107:18:107:31 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
| datamodel.py:107:18:107:31 | GSSA Variable c | semmle.label | GSSA Variable c |
| datamodel.py:119:6:119:30 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| datamodel.py:119:18:119:29 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
| test.py:43:9:43:14 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:44:10:44:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:48:9:48:16 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
| test.py:49:10:49:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:52:9:52:12 | ControlFlowNode for FloatLiteral | semmle.label | ControlFlowNode for FloatLiteral |
| test.py:52:9:52:17 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
| test.py:53:10:53:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:61:10:61:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:62:10:62:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:238:10:238:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
| test.py:238:28:238:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:297:10:297:18 | ControlFlowNode for f() | semmle.label | ControlFlowNode for f() |
| test.py:297:12:297:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:301:10:301:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
| test.py:301:28:301:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:56:9:56:10 | ControlFlowNode for IntegerLiteral | semmle.label | ControlFlowNode for IntegerLiteral |
| test.py:57:10:57:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:60:9:60:12 | ControlFlowNode for FloatLiteral | semmle.label | ControlFlowNode for FloatLiteral |
| test.py:61:10:61:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:69:10:69:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:70:10:70:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:246:10:246:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
| test.py:246:28:246:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:305:10:305:18 | ControlFlowNode for f() | semmle.label | ControlFlowNode for f() |
| test.py:305:12:305:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
| test.py:309:10:309:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
| test.py:309:28:309:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
#select
| test.py:36:10:36:10 | ControlFlowNode for x | test.py:35:9:35:14 | ControlFlowNode for SOURCE | test.py:36:10:36:10 | ControlFlowNode for x | <message> |
| test.py:41:10:41:10 | ControlFlowNode for x | test.py:40:9:40:16 | ControlFlowNode for Str | test.py:41:10:41:10 | ControlFlowNode for x | <message> |
| test.py:45:10:45:10 | ControlFlowNode for x | test.py:44:9:44:17 | ControlFlowNode for Str | test.py:45:10:45:10 | ControlFlowNode for x | <message> |
| test.py:49:10:49:10 | ControlFlowNode for x | test.py:48:9:48:10 | ControlFlowNode for IntegerLiteral | test.py:49:10:49:10 | ControlFlowNode for x | <message> |
| test.py:53:10:53:10 | ControlFlowNode for x | test.py:52:9:52:12 | ControlFlowNode for FloatLiteral | test.py:53:10:53:10 | ControlFlowNode for x | <message> |
| test.py:62:10:62:10 | ControlFlowNode for x | test.py:61:10:61:15 | ControlFlowNode for SOURCE | test.py:62:10:62:10 | ControlFlowNode for x | <message> |
| test.py:238:10:238:34 | ControlFlowNode for second() | test.py:238:28:238:33 | ControlFlowNode for SOURCE | test.py:238:10:238:34 | ControlFlowNode for second() | <message> |
| test.py:297:10:297:18 | ControlFlowNode for f() | test.py:297:12:297:17 | ControlFlowNode for SOURCE | test.py:297:10:297:18 | ControlFlowNode for f() | <message> |
| test.py:301:10:301:34 | ControlFlowNode for second() | test.py:301:28:301:33 | ControlFlowNode for SOURCE | test.py:301:10:301:34 | ControlFlowNode for second() | <message> |
| datamodel.py:38:6:38:17 | ControlFlowNode for f() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:38:6:38:17 | ControlFlowNode for f() | <message> |
| datamodel.py:38:6:38:17 | ControlFlowNode for f() | datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:38:6:38:17 | ControlFlowNode for f() | <message> |
| datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | <message> |
| datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | <message> |
| datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | <message> |
| datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | <message> |
| datamodel.py:73:6:73:27 | ControlFlowNode for func_obj() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:73:6:73:27 | ControlFlowNode for func_obj() | <message> |
| datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | <message> |
| datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | <message> |
| datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | <message> |
| datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | <message> |
| datamodel.py:82:6:82:26 | ControlFlowNode for c_func_obj() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:82:6:82:26 | ControlFlowNode for c_func_obj() | <message> |
| datamodel.py:93:6:93:20 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:93:6:93:20 | ControlFlowNode for Attribute() | <message> |
| datamodel.py:97:6:97:21 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:97:6:97:21 | ControlFlowNode for Attribute() | <message> |
| datamodel.py:106:6:106:30 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:106:6:106:30 | ControlFlowNode for Attribute() | <message> |
| datamodel.py:107:6:107:32 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:107:6:107:32 | ControlFlowNode for Attribute() | <message> |
| datamodel.py:119:6:119:30 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:119:6:119:30 | ControlFlowNode for Attribute() | <message> |
| test.py:44:10:44:10 | ControlFlowNode for x | test.py:43:9:43:14 | ControlFlowNode for SOURCE | test.py:44:10:44:10 | ControlFlowNode for x | <message> |
| test.py:49:10:49:10 | ControlFlowNode for x | test.py:48:9:48:16 | ControlFlowNode for Str | test.py:49:10:49:10 | ControlFlowNode for x | <message> |
| test.py:53:10:53:10 | ControlFlowNode for x | test.py:52:9:52:17 | ControlFlowNode for Str | test.py:53:10:53:10 | ControlFlowNode for x | <message> |
| test.py:57:10:57:10 | ControlFlowNode for x | test.py:56:9:56:10 | ControlFlowNode for IntegerLiteral | test.py:57:10:57:10 | ControlFlowNode for x | <message> |
| test.py:61:10:61:10 | ControlFlowNode for x | test.py:60:9:60:12 | ControlFlowNode for FloatLiteral | test.py:61:10:61:10 | ControlFlowNode for x | <message> |
| test.py:70:10:70:10 | ControlFlowNode for x | test.py:69:10:69:15 | ControlFlowNode for SOURCE | test.py:70:10:70:10 | ControlFlowNode for x | <message> |
| test.py:246:10:246:34 | ControlFlowNode for second() | test.py:246:28:246:33 | ControlFlowNode for SOURCE | test.py:246:10:246:34 | ControlFlowNode for second() | <message> |
| test.py:305:10:305:18 | ControlFlowNode for f() | test.py:305:12:305:17 | ControlFlowNode for SOURCE | test.py:305:10:305:18 | ControlFlowNode for f() | <message> |
| test.py:309:10:309:34 | ControlFlowNode for second() | test.py:309:28:309:33 | ControlFlowNode for SOURCE | test.py:309:10:309:34 | ControlFlowNode for second() | <message> |

View File

@@ -0,0 +1,159 @@
# User-defined methods, both instance methods and class methods, can be called in many non-standard ways
# i.e. differently from simply `c.f()` or `C.f()`. For example, a user-defined `__await__` method on a
# class `C` will be called by the syntactic construct `await c` when `c` is an instance of `C`.
#
# These tests are based on the first part of https://docs.python.org/3/reference/datamodel.html.
# A thorough covering of methods in that document is found in classes.py.
#
# Intended sources should be the variable `SOURCE` and intended sinks should be
# arguments to the function `SINK` (see python/ql/test/experimental/dataflow/testConfig.qll).
# These are defined so that we can evaluate the test code.
NONSOURCE = "not a source"
SOURCE = "source"
def is_source(x):
return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j
def SINK(x):
if is_source(x):
print("OK")
else:
print("Unexpected flow", x)
def SINK_F(x):
if is_source(x):
print("Unexpected flow", x)
else:
print("OK")
# Callable types
# These are the types to which the function call operation (see section Calls) can be applied:
# User-defined functions
# A user-defined function object is created by a function definition (see section Function definitions). It should be called with an argument list containing the same number of items as the function's formal parameter list.
def f(a, b):
return a
SINK(f(SOURCE, 3))
# Instance methods
# An instance method object combines a class, a class instance and any callable object (normally a user-defined function).
class C(object):
def method(self, x, cls):
assert cls is self.__class__
return x
@classmethod
def classmethod(cls, x):
return x
@staticmethod
def staticmethod(x):
return x
def gen(self, x, count):
n = count
while n > 0:
yield x
n -= 1
async def coro(self, x):
return x
c = C()
# When an instance method object is created by retrieving a user-defined function object from a class via one of its instances, its __self__ attribute is the instance, and the method object is said to be bound. The new methods __func__ attribute is the original function object.
func_obj = c.method.__func__
# When an instance method object is called, the underlying function (__func__) is called, inserting the class instance (__self__) in front of the argument list. For instance, when C is a class which contains a definition for a function f(), and x is an instance of C, calling x.f(1) is equivalent to calling C.f(x, 1).
SINK(c.method(SOURCE, C))
SINK(C.method(c, SOURCE, C))
SINK(func_obj(c, SOURCE, C))
# When an instance method object is created by retrieving a class method object from a class or instance, its __self__ attribute is the class itself, and its __func__ attribute is the function object underlying the class method.
c_func_obj = C.classmethod.__func__
# When an instance method object is derived from a class method object, the “class instance” stored in __self__ will actually be the class itself, so that calling either x.f(1) or C.f(1) is equivalent to calling f(C,1) where f is the underlying function.
SINK(c.classmethod(SOURCE))
SINK(C.classmethod(SOURCE))
SINK(c_func_obj(C, SOURCE))
# Generator functions
# A function or method which uses the yield statement (see section The yield statement) is called a generator function. Such a function, when called, always returns an iterator object which can be used to execute the body of the function: calling the iterators iterator.__next__() method will cause the function to execute until it provides a value using the yield statement. When the function executes a return statement or falls off the end, a StopIteration exception is raised and the iterator will have reached the end of the set of values to be returned.
def gen(x, count):
n = count
while n > 0:
yield x
n -= 1
iter = gen(SOURCE, 1)
SINK(iter.__next__())
# SINK_F(iter.__next__()) # throws StopIteration, FP
oiter = c.gen(SOURCE, 1)
SINK(oiter.__next__())
# SINK_F(oiter.__next__()) # throws StopIteration, FP
# Coroutine functions
# A function or method which is defined using async def is called a coroutine function. Such a function, when called, returns a coroutine object. It may contain await expressions, as well as async with and async for statements. See also the Coroutine Objects section.
async def coro(x):
return x
import asyncio
SINK(asyncio.run(coro(SOURCE)))
SINK(asyncio.run(c.coro(SOURCE)))
class A:
def __await__(self):
# yield SOURCE -- see https://groups.google.com/g/dev-python/c/_lrrc-vp9TI?pli=1
return (yield from asyncio.coroutine(lambda: SOURCE)())
async def agen(x):
a = A()
return await a
SINK(asyncio.run(agen(SOURCE)))
# Asynchronous generator functions
# A function or method which is defined using async def and which uses the yield statement is called a asynchronous generator function. Such a function, when called, returns an asynchronous iterator object which can be used in an async for statement to execute the body of the function.
# Calling the asynchronous iterators aiterator.__anext__() method will return an awaitable which when awaited will execute until it provides a value using the yield expression. When the function executes an empty return statement or falls off the end, a StopAsyncIteration exception is raised and the asynchronous iterator will have reached the end of the set of values to be yielded.
# Built-in functions
# A built-in function object is a wrapper around a C function. Examples of built-in functions are len() and math.sin() (math is a standard built-in module). The number and type of the arguments are determined by the C function. Special read-only attributes: __doc__ is the functions documentation string, or None if unavailable; __name__ is the functions name; __self__ is set to None (but see the next item); __module__ is the name of the module the function was defined in or None if unavailable.
# Built-in methods
# This is really a different disguise of a built-in function, this time containing an object passed to the C function as an implicit extra argument. An example of a built-in method is alist.append(), assuming alist is a list object. In this case, the special read-only attribute __self__ is set to the object denoted by alist.
# Classes
# Classes are callable. These objects normally act as factories for new instances of themselves, but variations are possible for class types that override __new__(). The arguments of the call are passed to __new__() and, in the typical case, to __init__() to initialize the new instance.
# Class Instances
# Instances of arbitrary classes can be made callable by defining a __call__() method in their class.
# If a class sets __iter__() to None, calling iter() on its instances will raise a TypeError (without falling back to __getitem__()).
# 3.3.1. Basic customization
class Customized:
a = NONSOURCE
b = NONSOURCE
def __new__(cls):
cls.a = SOURCE
return super().__new__(cls)
def __init__(self):
self.b = SOURCE
# testing __new__ and __init__
customized = Customized()
SINK(Customized.a)
SINK_F(Customized.b)
SINK(customized.a)
SINK(customized.b)

View File

@@ -1,7 +1,7 @@
| test.py:24:5:24:5 | SSA variable x | test.py:23:1:23:33 | Exit node for Function test_tuple_with_local_flow |
| test.py:24:5:24:5 | SSA variable x | test.py:25:9:25:9 | ControlFlowNode for x |
| test.py:24:10:24:26 | ControlFlowNode for Tuple | test.py:24:5:24:5 | SSA variable x |
| test.py:25:5:25:5 | SSA variable y | test.py:26:5:26:11 | SSA variable y |
| test.py:25:5:25:5 | SSA variable y | test.py:26:10:26:10 | ControlFlowNode for y |
| test.py:25:9:25:12 | ControlFlowNode for Subscript | test.py:25:5:25:5 | SSA variable y |
| test.py:26:5:26:11 | SSA variable y | test.py:23:1:23:33 | Exit node for Function test_tuple_with_local_flow |
| test.py:32:5:32:5 | SSA variable x | test.py:31:1:31:33 | Exit node for Function test_tuple_with_local_flow |
| test.py:32:5:32:5 | SSA variable x | test.py:33:9:33:9 | ControlFlowNode for x |
| test.py:32:10:32:26 | ControlFlowNode for Tuple | test.py:32:5:32:5 | SSA variable x |
| test.py:33:5:33:5 | SSA variable y | test.py:34:5:34:11 | SSA variable y |
| test.py:33:5:33:5 | SSA variable y | test.py:34:10:34:10 | ControlFlowNode for y |
| test.py:33:9:33:12 | ControlFlowNode for Subscript | test.py:33:5:33:5 | SSA variable y |
| test.py:34:5:34:11 | SSA variable y | test.py:31:1:31:33 | Exit node for Function test_tuple_with_local_flow |

View File

@@ -6,19 +6,27 @@
#
# Functions whose name ends with "_with_local_flow" will also be tested for local flow.
#
# All functions starting with "test_" should run and either
# - print a source (sources are defined in testConfig.qll).
# - print "Unexpected flow: " and a non-source
# (The idea is to later write a script to autimatically confirm this.)
# All functions starting with "test_" should run and print `"OK"`.
# This can be checked by running validTest.py.
# These are defined so that we can evaluate the test code.
NONSOURCE = "not a source"
SOURCE = "source"
def is_source(x):
return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j
def SINK(x):
print(x)
if is_source(x):
print("OK")
else:
print("Unexpected flow", x)
def SINK_F(x):
print("Unexpected flow: ", x)
if is_source(x):
print("Unexpected flow", x)
else:
print("OK")
def test_tuple_with_local_flow():
x = (NONSOURCE, SOURCE)

View File

@@ -0,0 +1,49 @@
def check_output(s, f):
if s == "OK\n":
pass
else:
raise RuntimeError("Function failed", s, f)
def check_test_function(f):
from io import StringIO
import sys
capturer = StringIO()
old_stdout = sys.stdout
sys.stdout = capturer
f()
sys.stdout = old_stdout
check_output(capturer.getvalue(), f)
def check_async_test_function(f):
from io import StringIO
import sys
import asyncio
capturer = StringIO()
old_stdout = sys.stdout
sys.stdout = capturer
asyncio.run(f())
sys.stdout = old_stdout
check_output(capturer.getvalue(), f)
def check_tests_valid(testFile):
import importlib
tests = importlib.import_module(testFile)
for i in dir(tests):
# print("Considering", i)
if i.startswith("test_"):
item = getattr(tests,i)
if callable(item):
print("Checking", testFile, item)
check_test_function(item)
elif i.startswith("atest_"):
item = getattr(tests,i)
if callable(item):
print("Checking", testFile, item)
check_async_test_function(item)
if __name__ == '__main__':
check_tests_valid("classes")
check_tests_valid("test")