зеркало из https://github.com/github/codeql.git
Merge remote-tracking branch 'upstream/main' into
uncontrolled-alloc-size
This commit is contained in:
Коммит
5d485859af
|
@ -15,6 +15,10 @@ The following changes in version 1.26 affect C/C++ analysis in all applications.
|
|||
|----------------------------|------------------------|------------------------------------------------------------------|
|
||||
| Inconsistent direction of for loop (`cpp/inconsistent-loop-direction`) | Fewer false positive results | The query now accounts for intentional wrapping of an unsigned loop counter. |
|
||||
| Overflow in uncontrolled allocation size (`cpp/uncontrolled-allocation-size`) | | The precision of this query has been decreased from "high" to "medium". As a result, the query is still run but results are no longer displayed on LGTM by default. |
|
||||
| Comparison result is always the same (`cpp/constant-comparison`) | More correct results | Bounds on expressions involving multiplication can now be determined in more cases. |
|
||||
|
||||
## Changes to libraries
|
||||
|
||||
* The 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.
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
| **Query** | **Expected impact** | **Change** |
|
||||
|--------------------------------|------------------------------|---------------------------------------------------------------------------|
|
||||
| Incomplete URL substring sanitization (`js/incomplete-url-substring-sanitization`) | More results | This query now recognizes additional URLs when the substring check is an inclusion check. |
|
||||
|
||||
|
||||
## Changes to libraries
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>Private data that is stored in a file or buffer unencrypted is accessible to an attacker who gains access to the
|
||||
storage.</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>Ensure that private data is always encrypted before being stored.
|
||||
It may be wise to encrypt information before it is put into a buffer that may be readable in memory.</p>
|
||||
|
||||
<p>In general, decrypt private data only at the point where it is necessary for it to be used in
|
||||
cleartext.</p>
|
||||
|
||||
</recommendation>
|
||||
|
||||
<references>
|
||||
|
||||
<li><a href="https://owasp.org/www-project-top-ten/OWASP_Top_Ten_2017/Top_10-2017_A3-Sensitive_Data_Exposure">OWASP Sensitive_Data_Exposure</a></li>
|
||||
<li>M. Dowd, J. McDonald and J. Schuhm, <i>The Art of Software Security Assessment</i>, 1st Edition, Chapter 2 - 'Common Vulnerabilities of Encryption', p. 43. Addison Wesley, 2006.</li>
|
||||
<li>M. Howard and D. LeBlanc, <i>Writing Secure Code</i>, 2nd Edition, Chapter 9 - 'Protecting Secret Data', p. 299. Microsoft, 2002.</li>
|
||||
|
||||
|
||||
|
||||
<!-- LocalWords: CWE
|
||||
-->
|
||||
|
||||
</references>
|
||||
</qhelp>
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* @name Exposure of private information
|
||||
* @description If private information is written to an external location, it may be accessible by
|
||||
* unauthorized persons.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @id cpp/private-cleartext-write
|
||||
* @tags security
|
||||
* external/cwe/cwe-359
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import experimental.semmle.code.cpp.security.PrivateCleartextWrite
|
||||
import experimental.semmle.code.cpp.security.PrivateCleartextWrite::PrivateCleartextWrite
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from WriteConfig b, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where b.hasFlowPath(source, sink)
|
||||
select sink.getNode(),
|
||||
"This write into the external location '" + sink + "' may contain unencrypted data from $@",
|
||||
source, "this source."
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* EXPERIMENTAL: The API of this module may change without notice.
|
||||
*
|
||||
* Provides a class for modeling `Expr`s with a restricted range.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL: The API of this class may change without notice.
|
||||
*
|
||||
* An expression for which a range can be deduced. Extend this class to add
|
||||
* functionality to the range analysis library.
|
||||
*/
|
||||
abstract class SimpleRangeAnalysisExpr extends Expr {
|
||||
/**
|
||||
* Gets the lower bound of the expression.
|
||||
*
|
||||
* Implementations of this predicate should use
|
||||
* `getFullyConvertedLowerBounds` and `getFullyConvertedUpperBounds` for
|
||||
* recursive calls to get the bounds of their children.
|
||||
*/
|
||||
abstract float getLowerBounds();
|
||||
|
||||
/**
|
||||
* Gets the upper bound of the expression.
|
||||
*
|
||||
* Implementations of this predicate should use
|
||||
* `getFullyConvertedLowerBounds` and `getFullyConvertedUpperBounds` for
|
||||
* recursive calls to get the bounds of their children.
|
||||
*/
|
||||
abstract float getUpperBounds();
|
||||
|
||||
/**
|
||||
* Holds if the range this expression depends on the definition `srcDef` for
|
||||
* StackVariable `srcVar`.
|
||||
*
|
||||
* Because this predicate cannot be recursive, most implementations should
|
||||
* override `dependsOnChild` instead.
|
||||
*/
|
||||
predicate dependsOnDef(RangeSsaDefinition srcDef, StackVariable srcVar) { none() }
|
||||
|
||||
/**
|
||||
* Holds if this expression depends on the range of its unconverted
|
||||
* subexpression `child`. This information is used to inform the range
|
||||
* analysis about cyclic dependencies. Without this information, range
|
||||
* analysis might work for simple cases but will go into infinite loops on
|
||||
* complex code.
|
||||
*
|
||||
* For example, when modeling a function call whose return value depends on
|
||||
* all of its arguments, implement this predicate as
|
||||
* `child = this.getAnArgument()`.
|
||||
*/
|
||||
abstract predicate dependsOnChild(Expr child);
|
||||
}
|
||||
|
||||
import SimpleRangeAnalysisInternal
|
||||
|
||||
/**
|
||||
* This class exists to prevent the QL front end from emitting compile errors
|
||||
* inside `SimpleRangeAnalysis.qll` about certain conjuncts being empty
|
||||
* because the overrides of `SimpleRangeAnalysisExpr` that happen to be in
|
||||
* scope do not make use of every feature it offers.
|
||||
*/
|
||||
private class Empty extends SimpleRangeAnalysisExpr {
|
||||
Empty() {
|
||||
// This predicate is complicated enough that the QL type checker doesn't
|
||||
// see it as empty but simple enough that the optimizer should.
|
||||
this = this and none()
|
||||
}
|
||||
|
||||
override float getLowerBounds() { none() }
|
||||
|
||||
override float getUpperBounds() { none() }
|
||||
|
||||
override predicate dependsOnChild(Expr child) { none() }
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* Provides a taint-tracking configuration for reasoning about private information flowing unencrypted to an external location.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.dataflow.TaintTracking
|
||||
import experimental.semmle.code.cpp.security.PrivateData
|
||||
import semmle.code.cpp.security.FileWrite
|
||||
import semmle.code.cpp.security.BufferWrite
|
||||
import semmle.code.cpp.dataflow.TaintTracking
|
||||
|
||||
module PrivateCleartextWrite {
|
||||
/**
|
||||
* A data flow source for private information flowing unencrypted to an external location.
|
||||
*/
|
||||
abstract class Source extends DataFlow::ExprNode { }
|
||||
|
||||
/**
|
||||
* A data flow sink for private information flowing unencrypted to an external location.
|
||||
*/
|
||||
abstract class Sink extends DataFlow::ExprNode { }
|
||||
|
||||
/**
|
||||
* A sanitizer for private information flowing unencrypted to an external location.
|
||||
*/
|
||||
abstract class Sanitizer extends DataFlow::ExprNode { }
|
||||
|
||||
/** A call to any method whose name suggests that it encodes or encrypts the parameter. */
|
||||
class ProtectSanitizer extends Sanitizer {
|
||||
ProtectSanitizer() {
|
||||
exists(Function m, string s |
|
||||
this.getExpr().(FunctionCall).getTarget() = m and
|
||||
m.getName().regexpMatch("(?i).*" + s + ".*")
|
||||
|
|
||||
s = "protect" or s = "encode" or s = "encrypt"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class WriteConfig extends TaintTracking::Configuration {
|
||||
WriteConfig() { this = "Write configuration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
}
|
||||
|
||||
class PrivateDataSource extends Source {
|
||||
PrivateDataSource() { this.getExpr() instanceof PrivateDataExpr }
|
||||
}
|
||||
|
||||
class WriteSink extends Sink {
|
||||
WriteSink() {
|
||||
exists(FileWrite f, BufferWrite b |
|
||||
this.asExpr() = f.getASource()
|
||||
or
|
||||
this.asExpr() = b.getAChild()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* Provides classes and predicates for identifying private data and functions for security.
|
||||
*
|
||||
* 'Private' data in general is anything that would compromise user privacy if exposed. This
|
||||
* library tries to guess where private data may either be stored in a variable or produced by a
|
||||
* function.
|
||||
*
|
||||
* This library is not concerned with credentials. See `SensitiveActions` for expressions related
|
||||
* to credentials.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
/** A string for `match` that identifies strings that look like they represent private data. */
|
||||
private string privateNames() {
|
||||
// Inspired by the list on https://cwe.mitre.org/data/definitions/359.html
|
||||
// Government identifiers, such as Social Security Numbers
|
||||
result = "%social%security%number%" or
|
||||
// Contact information, such as home addresses and telephone numbers
|
||||
result = "%postcode%" or
|
||||
result = "%zipcode%" or
|
||||
// result = "%telephone%" or
|
||||
// Geographic location - where the user is (or was)
|
||||
result = "%latitude%" or
|
||||
result = "%longitude%" or
|
||||
// Financial data - such as credit card numbers, salary, bank accounts, and debts
|
||||
result = "%creditcard%" or
|
||||
result = "%salary%" or
|
||||
result = "%bankaccount%" or
|
||||
// Communications - e-mail addresses, private e-mail messages, SMS text messages, chat logs, etc.
|
||||
// result = "%email%" or
|
||||
// result = "%mobile%" or
|
||||
result = "%employer%" or
|
||||
// Health - medical conditions, insurance status, prescription records
|
||||
result = "%medical%"
|
||||
}
|
||||
|
||||
/** An expression that might contain private data. */
|
||||
abstract class PrivateDataExpr extends Expr { }
|
||||
|
||||
/** A functiond call that might produce private data. */
|
||||
class PrivateFunctionCall extends PrivateDataExpr, FunctionCall {
|
||||
PrivateFunctionCall() {
|
||||
exists(string s | this.getTarget().getName().toLowerCase() = s | s.matches(privateNames()))
|
||||
}
|
||||
}
|
||||
|
||||
/** An access to a variable that might contain private data. */
|
||||
class PrivateVariableAccess extends PrivateDataExpr, VariableAccess {
|
||||
PrivateVariableAccess() {
|
||||
exists(string s | this.getTarget().getName().toLowerCase() = s | s.matches(privateNames()))
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
import cpp
|
||||
private import RangeAnalysisUtils
|
||||
private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
|
||||
import RangeSSA
|
||||
import SimpleRangeAnalysisCached
|
||||
private import NanAnalysis
|
||||
|
@ -156,6 +157,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 +183,8 @@ private predicate analyzableExpr(Expr e) {
|
|||
or
|
||||
e instanceof SubExpr
|
||||
or
|
||||
e instanceof UnsignedMulExpr
|
||||
or
|
||||
e instanceof AssignExpr
|
||||
or
|
||||
e instanceof AssignAddExpr
|
||||
|
@ -207,6 +214,9 @@ private predicate analyzableExpr(Expr e) {
|
|||
or
|
||||
// `>>` by a constant
|
||||
exists(e.(RShiftExpr).getRightOperand().getValue())
|
||||
or
|
||||
// A modeled expression for range analysis
|
||||
e instanceof SimpleRangeAnalysisExpr
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -278,6 +288,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 |
|
||||
|
@ -318,6 +332,16 @@ private predicate exprDependsOnDef(Expr e, RangeSsaDefinition srcDef, StackVaria
|
|||
)
|
||||
or
|
||||
e = srcDef.getAUse(srcVar)
|
||||
or
|
||||
// A modeled expression for range analysis
|
||||
exists(SimpleRangeAnalysisExpr rae | rae = e |
|
||||
rae.dependsOnDef(srcDef, srcVar)
|
||||
or
|
||||
exists(Expr child |
|
||||
rae.dependsOnChild(child) and
|
||||
exprDependsOnDef(child, srcDef, srcVar)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -381,9 +405,17 @@ private predicate assignmentDef(RangeSsaDefinition def, StackVariable v, Expr ex
|
|||
)
|
||||
}
|
||||
|
||||
/** See comment above sourceDef. */
|
||||
/** See comment above assignmentDef. */
|
||||
private predicate analyzableDef(RangeSsaDefinition def, StackVariable v) {
|
||||
assignmentDef(def, v, _) or defDependsOnDef(def, v, _, _)
|
||||
assignmentDef(def, v, _)
|
||||
or
|
||||
analyzableExpr(def.(AssignOperation)) and
|
||||
v = def.getAVariable()
|
||||
or
|
||||
analyzableExpr(def.(CrementOperation)) and
|
||||
v = def.getAVariable()
|
||||
or
|
||||
phiDependsOnDef(def, v, _, _)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -435,13 +467,6 @@ private float addRoundingDownSmall(float x, float small) {
|
|||
if (x + small) - x > small then result = (x + small).nextDown() else result = (x + small)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the truncated lower bounds of the fully converted expression.
|
||||
*/
|
||||
private float getFullyConvertedLowerBounds(Expr expr) {
|
||||
result = getTruncatedLowerBounds(expr.getFullyConverted())
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lower bounds of the expression.
|
||||
*
|
||||
|
@ -488,13 +513,6 @@ private float getTruncatedLowerBounds(Expr expr) {
|
|||
result = exprMinVal(expr)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the truncated upper bounds of the fully converted expression.
|
||||
*/
|
||||
private float getFullyConvertedUpperBounds(Expr expr) {
|
||||
result = getTruncatedUpperBounds(expr.getFullyConverted())
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the upper bounds of the expression.
|
||||
*
|
||||
|
@ -625,6 +643,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())
|
||||
|
@ -711,7 +736,9 @@ private float getLowerBoundsImpl(Expr expr) {
|
|||
or
|
||||
// Use SSA to get the lower bounds for a variable use.
|
||||
exists(RangeSsaDefinition def, StackVariable v | expr = def.getAUse(v) |
|
||||
result = getDefLowerBounds(def, v)
|
||||
result = getDefLowerBounds(def, v) and
|
||||
// Not explicitly modeled by a SimpleRangeAnalysisExpr
|
||||
not expr instanceof SimpleRangeAnalysisExpr
|
||||
)
|
||||
or
|
||||
// unsigned `&` (tighter bounds may exist)
|
||||
|
@ -727,6 +754,12 @@ private float getLowerBoundsImpl(Expr expr) {
|
|||
right = rsExpr.getRightOperand().getFullyConverted().getValue().toInt() and
|
||||
result = safeFloor(left / 2.pow(right))
|
||||
)
|
||||
or
|
||||
// A modeled expression for range analysis
|
||||
exists(SimpleRangeAnalysisExpr rangeAnalysisExpr |
|
||||
rangeAnalysisExpr = expr and
|
||||
result = rangeAnalysisExpr.getLowerBounds()
|
||||
)
|
||||
}
|
||||
|
||||
/** Only to be called by `getTruncatedUpperBounds`. */
|
||||
|
@ -794,6 +827,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())
|
||||
|
@ -878,7 +918,9 @@ private float getUpperBoundsImpl(Expr expr) {
|
|||
or
|
||||
// Use SSA to get the upper bounds for a variable use.
|
||||
exists(RangeSsaDefinition def, StackVariable v | expr = def.getAUse(v) |
|
||||
result = getDefUpperBounds(def, v)
|
||||
result = getDefUpperBounds(def, v) and
|
||||
// Not explicitly modeled by a SimpleRangeAnalysisExpr
|
||||
not expr instanceof SimpleRangeAnalysisExpr
|
||||
)
|
||||
or
|
||||
// unsigned `&` (tighter bounds may exist)
|
||||
|
@ -896,6 +938,12 @@ private float getUpperBoundsImpl(Expr expr) {
|
|||
right = rsExpr.getRightOperand().getFullyConverted().getValue().toInt() and
|
||||
result = safeFloor(left / 2.pow(right))
|
||||
)
|
||||
or
|
||||
// A modeled expression for range analysis
|
||||
exists(SimpleRangeAnalysisExpr rangeAnalysisExpr |
|
||||
rangeAnalysisExpr = expr and
|
||||
result = rangeAnalysisExpr.getUpperBounds()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1480,3 +1528,25 @@ private module SimpleRangeAnalysisCached {
|
|||
convertedExprMightOverflowPositively(expr)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: do not use. This module contains utilities for use in the
|
||||
* experimental `SimpleRangeAnalysisExpr` module.
|
||||
*/
|
||||
module SimpleRangeAnalysisInternal {
|
||||
/**
|
||||
* Gets the truncated lower bounds of the fully converted expression.
|
||||
*/
|
||||
float getFullyConvertedLowerBounds(Expr expr) {
|
||||
result = getTruncatedLowerBounds(expr.getFullyConverted())
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the truncated upper bounds of the fully converted expression.
|
||||
*/
|
||||
float getFullyConvertedUpperBounds(Expr expr) {
|
||||
result = getTruncatedUpperBounds(expr.getFullyConverted())
|
||||
}
|
||||
}
|
||||
|
||||
private import SimpleRangeAnalysisInternal
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
/// Adds its arguments (has custom modeling in QL)
|
||||
int custom_add_function(int a, int b);
|
||||
|
||||
int test_extensibility_add(int x) {
|
||||
if (x >= -10 && x <= 10) {
|
||||
int result = custom_add_function(x, 100);
|
||||
return result; // 90 .. 110
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
| extensibility.c:5:7:5:7 | x | -2.147483648E9 | 2.147483647E9 |
|
||||
| extensibility.c:5:19:5:19 | x | -10.0 | 2.147483647E9 |
|
||||
| extensibility.c:6:38:6:38 | x | -10.0 | 10.0 |
|
||||
| extensibility.c:7:12:7:17 | result | 90.0 | 110.0 |
|
|
@ -0,0 +1,32 @@
|
|||
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||
import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
|
||||
|
||||
class CustomAddFunctionCall extends SimpleRangeAnalysisExpr, FunctionCall {
|
||||
CustomAddFunctionCall() { this.getTarget().hasGlobalName("custom_add_function") }
|
||||
|
||||
override float getLowerBounds() {
|
||||
exists(float lower0, float lower1 |
|
||||
lower0 = getFullyConvertedLowerBounds(this.getArgument(0)) and
|
||||
lower1 = getFullyConvertedLowerBounds(this.getArgument(1)) and
|
||||
// Note: this rounds toward 0, not -Inf as it should
|
||||
result = lower0 + lower1
|
||||
)
|
||||
}
|
||||
|
||||
override float getUpperBounds() {
|
||||
exists(float upper0, float upper1 |
|
||||
upper0 = getFullyConvertedUpperBounds(this.getArgument(0)) and
|
||||
upper1 = getFullyConvertedUpperBounds(this.getArgument(1)) and
|
||||
// Note: this rounds toward 0, not Inf as it should
|
||||
result = upper0 + upper1
|
||||
)
|
||||
}
|
||||
|
||||
override predicate dependsOnChild(Expr child) { child = this.getAnArgument() }
|
||||
}
|
||||
|
||||
from VariableAccess expr, float lower, float upper
|
||||
where
|
||||
lower = lowerBound(expr) and
|
||||
upper = upperBound(expr)
|
||||
select expr, lower, upper
|
|
@ -0,0 +1,21 @@
|
|||
edges
|
||||
| test.cpp:77:16:77:22 | medical | test.cpp:78:24:78:27 | temp |
|
||||
| test.cpp:81:17:81:20 | call to func | test.cpp:82:24:82:28 | buff5 |
|
||||
| test.cpp:81:22:81:28 | medical | test.cpp:81:17:81:20 | call to func |
|
||||
nodes
|
||||
| test.cpp:57:9:57:18 | theZipcode | semmle.label | theZipcode |
|
||||
| test.cpp:74:24:74:30 | medical | semmle.label | medical |
|
||||
| test.cpp:77:16:77:22 | medical | semmle.label | medical |
|
||||
| test.cpp:78:24:78:27 | temp | semmle.label | temp |
|
||||
| test.cpp:81:17:81:20 | call to func | semmle.label | call to func |
|
||||
| test.cpp:81:22:81:28 | medical | semmle.label | medical |
|
||||
| test.cpp:82:24:82:28 | buff5 | semmle.label | buff5 |
|
||||
| test.cpp:96:37:96:46 | theZipcode | semmle.label | theZipcode |
|
||||
| test.cpp:99:42:99:51 | theZipcode | semmle.label | theZipcode |
|
||||
#select
|
||||
| test.cpp:57:9:57:18 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@ | test.cpp:57:9:57:18 | theZipcode | this source. |
|
||||
| test.cpp:74:24:74:30 | medical | This write into the external location 'medical' may contain unencrypted data from $@ | test.cpp:74:24:74:30 | medical | this source. |
|
||||
| test.cpp:78:24:78:27 | temp | This write into the external location 'temp' may contain unencrypted data from $@ | test.cpp:77:16:77:22 | medical | this source. |
|
||||
| test.cpp:82:24:82:28 | buff5 | This write into the external location 'buff5' may contain unencrypted data from $@ | test.cpp:81:22:81:28 | medical | this source. |
|
||||
| test.cpp:96:37:96:46 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@ | test.cpp:96:37:96:46 | theZipcode | this source. |
|
||||
| test.cpp:99:42:99:51 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@ | test.cpp:99:42:99:51 | theZipcode | this source. |
|
|
@ -0,0 +1 @@
|
|||
experimental/Security/CWE/CWE-359/PrivateCleartextWrite.ql
|
|
@ -0,0 +1,105 @@
|
|||
#define FILE int
|
||||
#define wchar char
|
||||
#define size_t int
|
||||
typedef int streamsize;
|
||||
|
||||
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||
int fputs(const char *s, FILE *stream);
|
||||
int fputc(int c, FILE *stream);
|
||||
int fprintf(FILE *stream, const char *format, ...);
|
||||
int sprintf(char *s, const char *format, ...);
|
||||
size_t strlen(const char *s);
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <class charT>
|
||||
struct char_traits;
|
||||
|
||||
template <class charT, class traits = char_traits<charT>>
|
||||
class basic_ostream /*: virtual public basic_ios<charT,traits> - not needed for this test */
|
||||
{
|
||||
public:
|
||||
typedef charT char_type;
|
||||
basic_ostream<charT, traits> &write(const char_type *s, streamsize n);
|
||||
};
|
||||
|
||||
template <class charT, class traits = char_traits<charT>>
|
||||
class basic_ofstream : public basic_ostream<charT, traits>
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
||||
template <class charT, class traits>
|
||||
basic_ostream<charT, traits> &operator<<(basic_ostream<charT, traits> &, const charT *);
|
||||
|
||||
typedef basic_ostream<char> ostream;
|
||||
typedef basic_ofstream<char> ofstream;
|
||||
}; // namespace std
|
||||
|
||||
using namespace std;
|
||||
|
||||
char *encrypt(char *buffer)
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
char *func(char *buffer)
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// test for CleartextFileWrite
|
||||
void file()
|
||||
{
|
||||
char *theZipcode = "cleartext zipcode!";
|
||||
FILE *file;
|
||||
|
||||
// BAD: write zipcode to file in cleartext
|
||||
fputs(theZipcode, file);
|
||||
|
||||
// GOOD: encrypt first
|
||||
char *encrypted = encrypt(theZipcode);
|
||||
fwrite(encrypted, sizeof(encrypted), 1, file);
|
||||
}
|
||||
|
||||
// test for CleartextBufferWrite
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *medical = "medical";
|
||||
char *buff1;
|
||||
char *buff2;
|
||||
char *buff3;
|
||||
char *buff4;
|
||||
|
||||
// BAD: write medical to buffer in cleartext
|
||||
sprintf(buff1, "%s", medical);
|
||||
|
||||
// BAD: write medical to buffer in cleartext
|
||||
char *temp = medical;
|
||||
sprintf(buff2, "%s", temp);
|
||||
|
||||
// BAD: write medical to buffer in cleartext
|
||||
char *buff5 = func(medical);
|
||||
sprintf(buff3, "%s", buff5);
|
||||
|
||||
char *buff6 = encrypt(medical);
|
||||
// GOOD: encrypt first
|
||||
sprintf(buff4, "%s", buff6);
|
||||
}
|
||||
|
||||
// test for CleartextFileWrite
|
||||
void stream()
|
||||
{
|
||||
char *theZipcode = "cleartext zipcode!";
|
||||
ofstream mystream;
|
||||
|
||||
// BAD: write zipcode to file in cleartext
|
||||
mystream << "the zipcode is: " << theZipcode;
|
||||
|
||||
// BAD: write zipcode to file in cleartext
|
||||
(mystream << "the zipcode is: ").write(theZipcode, strlen(theZipcode));
|
||||
|
||||
// GOOD: encrypt first
|
||||
char *encrypted = encrypt(theZipcode);
|
||||
mystream << "the zipcode is: " << encrypted;
|
||||
(mystream << "the zipcode is: ").write(encrypted, strlen(encrypted));
|
||||
}
|
|
@ -308,205 +308,230 @@
|
|||
| 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: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 |
|
||||
| string.cpp:24:12:24:17 | call to source | string.cpp:28:7:28:7 | a | |
|
||||
| string.cpp:25:16:25:20 | 123 | string.cpp:25:16:25:21 | call to basic_string | TAINT |
|
||||
| string.cpp:25:16:25:21 | call to basic_string | string.cpp:29:7:29:7 | b | |
|
||||
| string.cpp:25:16:25:21 | call to basic_string | string.cpp:31:7:31:7 | b | |
|
||||
| string.cpp:26:16:26:21 | call to source | string.cpp:26:16:26:24 | call to basic_string | TAINT |
|
||||
| string.cpp:26:16:26:24 | call to basic_string | string.cpp:30:7:30:7 | c | |
|
||||
| string.cpp:26:16:26:24 | call to basic_string | string.cpp:32:7:32:7 | c | |
|
||||
| string.cpp:31:7:31:7 | b | string.cpp:31:9:31:13 | call to c_str | TAINT |
|
||||
| string.cpp:32:7:32:7 | c | string.cpp:32:9:32:13 | call to c_str | TAINT |
|
||||
| string.cpp:37:16:37:28 | call to basic_string | string.cpp:38:7:38:11 | path1 | |
|
||||
| string.cpp:37:17:37:26 | call to user_input | string.cpp:37:16:37:28 | call to basic_string | TAINT |
|
||||
| string.cpp:38:7:38:11 | path1 | string.cpp:38:13:38:17 | call to c_str | TAINT |
|
||||
| string.cpp:41:10:41:19 | call to user_input | string.cpp:41:10:41:21 | call to basic_string | TAINT |
|
||||
| string.cpp:41:10:41:21 | call to basic_string | string.cpp:41:2:41:21 | ... = ... | |
|
||||
| string.cpp:41:10:41:21 | call to basic_string | string.cpp:42:7:42:11 | path2 | |
|
||||
| string.cpp:42:7:42:11 | path2 | string.cpp:42:13:42:17 | call to c_str | TAINT |
|
||||
| string.cpp:44:15:44:24 | call to user_input | string.cpp:44:15:44:27 | call to basic_string | TAINT |
|
||||
| string.cpp:44:15:44:27 | call to basic_string | string.cpp:45:7:45:11 | path3 | |
|
||||
| string.cpp:45:7:45:11 | path3 | string.cpp:45:13:45:17 | call to c_str | TAINT |
|
||||
| string.cpp:50:19:50:24 | call to source | string.cpp:53:17:53:18 | cs | |
|
||||
| string.cpp:50:19:50:24 | call to source | string.cpp:55:7:55:8 | cs | |
|
||||
| string.cpp:53:17:53:18 | cs | string.cpp:53:17:53:19 | call to basic_string | TAINT |
|
||||
| string.cpp:53:17:53:19 | call to basic_string | string.cpp:56:7:56:8 | ss | |
|
||||
| string.cpp:61:19:61:24 | call to source | string.cpp:64:17:64:18 | cs | |
|
||||
| string.cpp:64:17:64:18 | cs | string.cpp:64:17:64:19 | call to basic_string | TAINT |
|
||||
| string.cpp:64:17:64:19 | call to basic_string | string.cpp:67:7:67:8 | ss | |
|
||||
| string.cpp:64:17:64:19 | call to basic_string | string.cpp:70:7:70:8 | ss | |
|
||||
| string.cpp:67:7:67:8 | ss | string.cpp:67:10:67:14 | call to c_str | TAINT |
|
||||
| string.cpp:67:10:67:14 | call to c_str | string.cpp:67:2:67:16 | ... = ... | |
|
||||
| string.cpp:67:10:67:14 | call to c_str | string.cpp:69:7:69:8 | cs | |
|
||||
| string.cpp:76:18:76:24 | hello | string.cpp:76:18:76:25 | call to basic_string | TAINT |
|
||||
| string.cpp:76:18:76:25 | call to basic_string | string.cpp:81:8:81:9 | s1 | |
|
||||
| string.cpp:77:19:77:26 | call to basic_string | string.cpp:82:8:82:9 | s2 | |
|
||||
| string.cpp:77:20:77:26 | hello | string.cpp:77:19:77:26 | call to basic_string | TAINT |
|
||||
| string.cpp:79:8:79:14 | call to basic_string | string.cpp:79:3:79:14 | ... = ... | |
|
||||
| string.cpp:79:8:79:14 | call to basic_string | string.cpp:83:8:83:9 | s3 | |
|
||||
| string.cpp:79:8:79:14 | hello | string.cpp:79:8:79:14 | call to basic_string | TAINT |
|
||||
| string.cpp:87:18:87:23 | call to source | string.cpp:87:18:87:26 | call to basic_string | TAINT |
|
||||
| string.cpp:87:18:87:26 | call to basic_string | string.cpp:92:8:92:9 | s1 | |
|
||||
| string.cpp:88:19:88:27 | call to basic_string | string.cpp:93:8:93:9 | s2 | |
|
||||
| string.cpp:88:20:88:25 | call to source | string.cpp:88:19:88:27 | call to basic_string | TAINT |
|
||||
| string.cpp:90:8:90:13 | call to source | string.cpp:90:8:90:15 | call to basic_string | TAINT |
|
||||
| string.cpp:90:8:90:15 | call to basic_string | string.cpp:90:3:90:15 | ... = ... | |
|
||||
| string.cpp:90:8:90:15 | call to basic_string | string.cpp:94:8:94:9 | s3 | |
|
||||
| string.cpp:98:15:98:16 | call to basic_string | string.cpp:99:20:99:21 | s1 | |
|
||||
| string.cpp:98:15:98:16 | call to basic_string | string.cpp:101:8:101:9 | s1 | |
|
||||
| string.cpp:98:15:98:16 | call to basic_string | string.cpp:103:8:103:9 | s1 | |
|
||||
| string.cpp:99:20:99:21 | s1 | string.cpp:104:8:104:9 | s2 | |
|
||||
| string.cpp:101:8:101:9 | s1 | string.cpp:101:3:101:9 | ... = ... | |
|
||||
| string.cpp:101:8:101:9 | s1 | string.cpp:105:8:105:9 | s3 | |
|
||||
| string.cpp:109:19:109:40 | call to basic_string | string.cpp:113:8:113:9 | s1 | |
|
||||
| string.cpp:109:32:109:37 | call to source | string.cpp:109:19:109:40 | call to basic_string | TAINT |
|
||||
| string.cpp:111:8:111:28 | call to basic_string | string.cpp:111:3:111:28 | ... = ... | |
|
||||
| string.cpp:111:8:111:28 | call to basic_string | string.cpp:114:8:114:9 | s2 | |
|
||||
| string.cpp:111:20:111:25 | call to source | string.cpp:111:8:111:28 | call to basic_string | TAINT |
|
||||
| string.cpp:119:16:119:21 | call to source | string.cpp:119:16:119:24 | call to basic_string | TAINT |
|
||||
| string.cpp:119:16:119:24 | call to basic_string | string.cpp:120:15:120:15 | s | |
|
||||
| string.cpp:119:16:119:24 | call to basic_string | string.cpp:124:33:124:33 | s | |
|
||||
| string.cpp:119:16:119:24 | call to basic_string | string.cpp:124:50:124:50 | s | |
|
||||
| string.cpp:119:16:119:24 | call to basic_string | string.cpp:128:16:128:16 | s | |
|
||||
| string.cpp:120:15:120:15 | call to begin | string.cpp:120:15:120:15 | (__begin) | |
|
||||
| string.cpp:120:15:120:15 | call to begin | string.cpp:120:15:120:15 | (__begin) | |
|
||||
| string.cpp:120:15:120:15 | call to begin | string.cpp:120:15:120:15 | (__begin) | |
|
||||
| string.cpp:120:15:120:15 | call to end | string.cpp:120:15:120:15 | (__end) | |
|
||||
| string.cpp:120:15:120:15 | call to operator* | string.cpp:121:8:121:8 | c | |
|
||||
| string.cpp:120:15:120:15 | ref arg (__begin) | string.cpp:120:15:120:15 | (__begin) | |
|
||||
| string.cpp:120:15:120:15 | ref arg (__begin) | string.cpp:120:15:120:15 | (__begin) | |
|
||||
| string.cpp:120:15:120:15 | ref arg (__begin) | string.cpp:120:15:120:15 | (__begin) | |
|
||||
| string.cpp:120:15:120:15 | ref arg (__range) | string.cpp:120:15:120:15 | (__range) | |
|
||||
| string.cpp:120:15:120:15 | s | string.cpp:120:15:120:15 | (__range) | |
|
||||
| string.cpp:120:15:120:15 | s | string.cpp:120:15:120:15 | (__range) | |
|
||||
| string.cpp:120:15:120:15 | s | string.cpp:120:15:120:15 | call to operator* | TAINT |
|
||||
| string.cpp:124:33:124:33 | ref arg s | string.cpp:124:50:124:50 | s | |
|
||||
| string.cpp:124:33:124:33 | ref arg s | string.cpp:128:16:128:16 | s | |
|
||||
| string.cpp:124:35:124:39 | call to begin | string.cpp:124:44:124:45 | it | |
|
||||
| string.cpp:124:35:124:39 | call to begin | string.cpp:124:61:124:62 | it | |
|
||||
| string.cpp:124:35:124:39 | call to begin | string.cpp:125:9:125:10 | it | |
|
||||
| string.cpp:124:50:124:50 | ref arg s | string.cpp:124:50:124:50 | s | |
|
||||
| string.cpp:124:50:124:50 | ref arg s | string.cpp:128:16:128:16 | s | |
|
||||
| string.cpp:124:61:124:62 | ref arg it | string.cpp:124:44:124:45 | it | |
|
||||
| string.cpp:124:61:124:62 | ref arg it | string.cpp:124:61:124:62 | it | |
|
||||
| string.cpp:124:61:124:62 | ref arg it | string.cpp:125:9:125:10 | it | |
|
||||
| string.cpp:128:16:128:16 | call to begin | string.cpp:128:16:128:16 | (__begin) | |
|
||||
| string.cpp:128:16:128:16 | call to begin | string.cpp:128:16:128:16 | (__begin) | |
|
||||
| string.cpp:128:16:128:16 | call to begin | string.cpp:128:16:128:16 | (__begin) | |
|
||||
| string.cpp:128:16:128:16 | call to end | string.cpp:128:16:128:16 | (__end) | |
|
||||
| string.cpp:128:16:128:16 | call to operator* | string.cpp:129:8:129:8 | c | |
|
||||
| string.cpp:128:16:128:16 | ref arg (__begin) | string.cpp:128:16:128:16 | (__begin) | |
|
||||
| string.cpp:128:16:128:16 | ref arg (__begin) | string.cpp:128:16:128:16 | (__begin) | |
|
||||
| string.cpp:128:16:128:16 | ref arg (__begin) | string.cpp:128:16:128:16 | (__begin) | |
|
||||
| string.cpp:128:16:128:16 | ref arg (__range) | string.cpp:128:16:128:16 | (__range) | |
|
||||
| string.cpp:128:16:128:16 | s | string.cpp:128:16:128:16 | (__range) | |
|
||||
| string.cpp:128:16:128:16 | s | string.cpp:128:16:128:16 | (__range) | |
|
||||
| string.cpp:128:16:128:16 | s | string.cpp:128:16:128:16 | call to operator* | TAINT |
|
||||
| string.cpp:132:28:132:33 | call to source | string.cpp:132:28:132:36 | call to basic_string | TAINT |
|
||||
| string.cpp:132:28:132:36 | call to basic_string | string.cpp:133:22:133:28 | const_s | |
|
||||
| string.cpp:133:22:133:22 | call to begin | string.cpp:133:22:133:22 | (__begin) | |
|
||||
| string.cpp:133:22:133:22 | call to begin | string.cpp:133:22:133:22 | (__begin) | |
|
||||
| string.cpp:133:22:133:22 | call to begin | string.cpp:133:22:133:22 | (__begin) | |
|
||||
| string.cpp:133:22:133:22 | call to end | string.cpp:133:22:133:22 | (__end) | |
|
||||
| string.cpp:133:22:133:22 | call to operator* | string.cpp:134:8:134:8 | c | |
|
||||
| string.cpp:133:22:133:22 | ref arg (__begin) | string.cpp:133:22:133:22 | (__begin) | |
|
||||
| string.cpp:133:22:133:22 | ref arg (__begin) | string.cpp:133:22:133:22 | (__begin) | |
|
||||
| string.cpp:133:22:133:22 | ref arg (__begin) | string.cpp:133:22:133:22 | (__begin) | |
|
||||
| string.cpp:133:22:133:28 | const_s | string.cpp:133:22:133:22 | (__range) | |
|
||||
| string.cpp:133:22:133:28 | const_s | string.cpp:133:22:133:22 | (__range) | |
|
||||
| string.cpp:133:22:133:28 | const_s | string.cpp:133:22:133:22 | call to operator* | TAINT |
|
||||
| string.cpp:140:18:140:24 | hello | string.cpp:140:18:140:25 | call to basic_string | TAINT |
|
||||
| string.cpp:140:18:140:25 | call to basic_string | string.cpp:143:8:143:9 | s1 | |
|
||||
| string.cpp:140:18:140:25 | call to basic_string | string.cpp:143:13:143:14 | s1 | |
|
||||
| string.cpp:140:18:140:25 | call to basic_string | string.cpp:144:8:144:9 | s1 | |
|
||||
| string.cpp:140:18:140:25 | call to basic_string | string.cpp:145:13:145:14 | s1 | |
|
||||
| string.cpp:140:18:140:25 | call to basic_string | string.cpp:148:8:148:9 | s1 | |
|
||||
| string.cpp:140:18:140:25 | call to basic_string | string.cpp:149:8:149:9 | s1 | |
|
||||
| string.cpp:141:18:141:23 | call to source | string.cpp:141:18:141:26 | call to basic_string | TAINT |
|
||||
| string.cpp:141:18:141:26 | call to basic_string | string.cpp:144:13:144:14 | s2 | |
|
||||
| string.cpp:141:18:141:26 | call to basic_string | string.cpp:145:8:145:9 | s2 | |
|
||||
| string.cpp:141:18:141:26 | call to basic_string | string.cpp:146:8:146:9 | s2 | |
|
||||
| string.cpp:141:18:141:26 | call to basic_string | string.cpp:146:13:146:14 | s2 | |
|
||||
| string.cpp:143:8:143:9 | s1 | string.cpp:143:11:143:11 | call to operator+ | TAINT |
|
||||
| string.cpp:143:13:143:14 | s1 | string.cpp:143:11:143:11 | call to operator+ | TAINT |
|
||||
| string.cpp:144:8:144:9 | s1 | string.cpp:144:11:144:11 | call to operator+ | TAINT |
|
||||
| string.cpp:144:13:144:14 | s2 | string.cpp:144:11:144:11 | call to operator+ | TAINT |
|
||||
| string.cpp:145:8:145:9 | s2 | string.cpp:145:11:145:11 | call to operator+ | TAINT |
|
||||
| string.cpp:145:13:145:14 | s1 | string.cpp:145:11:145:11 | call to operator+ | TAINT |
|
||||
| string.cpp:146:8:146:9 | s2 | string.cpp:146:11:146:11 | call to operator+ | TAINT |
|
||||
| string.cpp:146:13:146:14 | s2 | string.cpp:146:11:146:11 | call to operator+ | TAINT |
|
||||
| string.cpp:148:8:148:9 | s1 | string.cpp:148:11:148:11 | call to operator+ | TAINT |
|
||||
| string.cpp:148:13:148:20 | world | string.cpp:148:11:148:11 | call to operator+ | TAINT |
|
||||
| string.cpp:149:8:149:9 | s1 | string.cpp:149:11:149:11 | call to operator+ | TAINT |
|
||||
| string.cpp:149:13:149:18 | call to source | string.cpp:149:11:149:11 | call to operator+ | TAINT |
|
||||
| string.cpp:153:18:153:22 | abc | string.cpp:153:18:153:23 | call to basic_string | TAINT |
|
||||
| string.cpp:153:18:153:23 | call to basic_string | string.cpp:157:8:157:9 | s3 | |
|
||||
| string.cpp:153:18:153:23 | call to basic_string | string.cpp:160:8:160:9 | s3 | |
|
||||
| string.cpp:153:18:153:23 | call to basic_string | string.cpp:164:8:164:9 | s3 | |
|
||||
| string.cpp:153:18:153:23 | call to basic_string | string.cpp:169:8:169:9 | s3 | |
|
||||
| string.cpp:153:18:153:23 | call to basic_string | string.cpp:173:8:173:9 | s3 | |
|
||||
| string.cpp:154:18:154:23 | call to source | string.cpp:154:18:154:26 | call to basic_string | TAINT |
|
||||
| string.cpp:154:18:154:26 | call to basic_string | string.cpp:157:13:157:14 | s4 | |
|
||||
| string.cpp:154:18:154:26 | call to basic_string | string.cpp:161:9:161:10 | s4 | |
|
||||
| string.cpp:154:18:154:26 | call to basic_string | string.cpp:170:13:170:14 | s4 | |
|
||||
| string.cpp:157:8:157:9 | s3 | string.cpp:157:11:157:11 | call to operator+ | TAINT |
|
||||
| string.cpp:157:11:157:11 | call to operator+ | string.cpp:157:3:157:14 | ... = ... | |
|
||||
| string.cpp:157:11:157:11 | call to operator+ | string.cpp:158:8:158:9 | s5 | |
|
||||
| string.cpp:157:13:157:14 | s4 | string.cpp:157:11:157:11 | call to operator+ | TAINT |
|
||||
| string.cpp:160:8:160:9 | s3 | string.cpp:160:3:160:9 | ... = ... | |
|
||||
| string.cpp:160:8:160:9 | s3 | string.cpp:161:3:161:4 | s6 | |
|
||||
| string.cpp:160:8:160:9 | s3 | string.cpp:162:8:162:9 | s6 | |
|
||||
| string.cpp:161:3:161:4 | ref arg s6 | string.cpp:162:8:162:9 | s6 | |
|
||||
| string.cpp:161:9:161:10 | s4 | string.cpp:161:3:161:4 | ref arg s6 | TAINT |
|
||||
| string.cpp:161:9:161:10 | s4 | string.cpp:161:6:161:6 | call to operator+= | TAINT |
|
||||
| string.cpp:164:8:164:9 | s3 | string.cpp:164:3:164:9 | ... = ... | |
|
||||
| string.cpp:164:8:164:9 | s3 | string.cpp:165:3:165:4 | s7 | |
|
||||
| string.cpp:164:8:164:9 | s3 | string.cpp:166:3:166:4 | s7 | |
|
||||
| string.cpp:164:8:164:9 | s3 | string.cpp:167:8:167:9 | s7 | |
|
||||
| string.cpp:165:3:165:4 | ref arg s7 | string.cpp:166:3:166:4 | s7 | |
|
||||
| string.cpp:165:3:165:4 | ref arg s7 | string.cpp:167:8:167:9 | s7 | |
|
||||
| string.cpp:165:9:165:14 | call to source | string.cpp:165:3:165:4 | ref arg s7 | TAINT |
|
||||
| string.cpp:165:9:165:14 | call to source | string.cpp:165:6:165:6 | call to operator+= | TAINT |
|
||||
| string.cpp:166:3:166:4 | ref arg s7 | string.cpp:167:8:167:9 | s7 | |
|
||||
| string.cpp:166:9:166:11 | | string.cpp:166:3:166:4 | ref arg s7 | TAINT |
|
||||
| string.cpp:166:9:166:11 | | string.cpp:166:6:166:6 | call to operator+= | TAINT |
|
||||
| string.cpp:169:8:169:9 | s3 | string.cpp:169:3:169:9 | ... = ... | |
|
||||
| string.cpp:169:8:169:9 | s3 | string.cpp:170:3:170:4 | s8 | |
|
||||
| string.cpp:169:8:169:9 | s3 | string.cpp:171:8:171:9 | s8 | |
|
||||
| string.cpp:170:3:170:4 | ref arg s8 | string.cpp:171:8:171:9 | s8 | |
|
||||
| string.cpp:170:13:170:14 | s4 | string.cpp:170:3:170:4 | ref arg s8 | TAINT |
|
||||
| string.cpp:170:13:170:14 | s4 | string.cpp:170:6:170:11 | call to append | TAINT |
|
||||
| string.cpp:173:8:173:9 | s3 | string.cpp:173:3:173:9 | ... = ... | |
|
||||
| string.cpp:173:8:173:9 | s3 | string.cpp:174:3:174:4 | s9 | |
|
||||
| string.cpp:173:8:173:9 | s3 | string.cpp:175:3:175:4 | s9 | |
|
||||
| string.cpp:173:8:173:9 | s3 | string.cpp:176:8:176:9 | s9 | |
|
||||
| string.cpp:174:3:174:4 | ref arg s9 | string.cpp:175:3:175:4 | s9 | |
|
||||
| string.cpp:174:3:174:4 | ref arg s9 | string.cpp:176:8:176:9 | s9 | |
|
||||
| string.cpp:174:13:174:18 | call to source | string.cpp:174:3:174:4 | ref arg s9 | TAINT |
|
||||
| string.cpp:174:13:174:18 | call to source | string.cpp:174:6:174:11 | call to append | TAINT |
|
||||
| string.cpp:175:3:175:4 | ref arg s9 | string.cpp:176:8:176:9 | s9 | |
|
||||
| string.cpp:175:13:175:15 | | string.cpp:175:3:175:4 | ref arg s9 | TAINT |
|
||||
| string.cpp:175:13:175:15 | | string.cpp:175:6:175:11 | call to append | TAINT |
|
||||
| string.cpp:180:19:180:23 | abc | string.cpp:180:19:180:24 | call to basic_string | TAINT |
|
||||
| string.cpp:180:19:180:24 | call to basic_string | string.cpp:183:3:183:5 | s10 | |
|
||||
| string.cpp:180:19:180:24 | call to basic_string | string.cpp:184:8:184:10 | s10 | |
|
||||
| string.cpp:181:12:181:26 | call to source | string.cpp:183:17:183:17 | c | |
|
||||
| string.cpp:183:3:183:5 | ref arg s10 | string.cpp:184:8:184:10 | s10 | |
|
||||
| string.cpp:183:17:183:17 | c | string.cpp:183:3:183:5 | ref arg s10 | TAINT |
|
||||
| string.cpp:183:17:183:17 | c | string.cpp:183:7:183:12 | call to append | TAINT |
|
||||
| stringstream.cpp:13:20:13:22 | call to basic_stringstream | stringstream.cpp:16:2:16:4 | ss1 | |
|
||||
| stringstream.cpp:13:20:13:22 | call to basic_stringstream | stringstream.cpp:22:7:22:9 | ss1 | |
|
||||
| stringstream.cpp:13:20:13:22 | call to basic_stringstream | stringstream.cpp:27:7:27:9 | ss1 | |
|
||||
| stringstream.cpp:13:25:13:27 | call to basic_stringstream | stringstream.cpp:17:2:17:4 | ss2 | |
|
||||
| stringstream.cpp:13:25:13:27 | call to basic_stringstream | stringstream.cpp:23:7:23:9 | ss2 | |
|
||||
| stringstream.cpp:13:25:13:27 | call to basic_stringstream | stringstream.cpp:28:7:28:9 | ss2 | |
|
||||
| stringstream.cpp:13:30:13:32 | call to basic_stringstream | stringstream.cpp:18:2:18:4 | ss3 | |
|
||||
| stringstream.cpp:13:30:13:32 | call to basic_stringstream | stringstream.cpp:24:7:24:9 | ss3 | |
|
||||
| stringstream.cpp:13:30:13:32 | call to basic_stringstream | stringstream.cpp:29:7:29:9 | ss3 | |
|
||||
| stringstream.cpp:13:35:13:37 | call to basic_stringstream | stringstream.cpp:19:2:19:4 | ss4 | |
|
||||
| stringstream.cpp:13:35:13:37 | call to basic_stringstream | stringstream.cpp:25:7:25:9 | ss4 | |
|
||||
| stringstream.cpp:13:35:13:37 | call to basic_stringstream | stringstream.cpp:30:7:30:9 | ss4 | |
|
||||
| stringstream.cpp:13:40:13:42 | call to basic_stringstream | stringstream.cpp:20:2:20:4 | ss5 | |
|
||||
| stringstream.cpp:13:40:13:42 | call to basic_stringstream | stringstream.cpp:26:7:26:9 | ss5 | |
|
||||
| stringstream.cpp:13:40:13:42 | call to basic_stringstream | stringstream.cpp:31:7:31:9 | ss5 | |
|
||||
| stringstream.cpp:14:16:14:21 | call to source | stringstream.cpp:14:16:14:24 | call to basic_string | TAINT |
|
||||
| stringstream.cpp:14:16:14:24 | call to basic_string | stringstream.cpp:20:9:20:9 | t | |
|
||||
| stringstream.cpp:16:2:16:4 | ref arg ss1 | stringstream.cpp:22:7:22:9 | ss1 | |
|
||||
| stringstream.cpp:16:2:16:4 | ref arg ss1 | stringstream.cpp:27:7:27:9 | ss1 | |
|
||||
| stringstream.cpp:17:2:17:4 | ref arg ss2 | stringstream.cpp:23:7:23:9 | ss2 | |
|
||||
| stringstream.cpp:17:2:17:4 | ref arg ss2 | stringstream.cpp:28:7:28:9 | ss2 | |
|
||||
| stringstream.cpp:18:2:18:4 | ref arg ss3 | stringstream.cpp:24:7:24:9 | ss3 | |
|
||||
| stringstream.cpp:18:2:18:4 | ref arg ss3 | stringstream.cpp:29:7:29:9 | ss3 | |
|
||||
| stringstream.cpp:19:2:19:4 | ref arg ss4 | stringstream.cpp:25:7:25:9 | ss4 | |
|
||||
| stringstream.cpp:19:2:19:4 | ref arg ss4 | stringstream.cpp:30:7:30:9 | ss4 | |
|
||||
| stringstream.cpp:20:2:20:4 | ref arg ss5 | stringstream.cpp:26:7:26:9 | ss5 | |
|
||||
| stringstream.cpp:20:2:20:4 | ref arg ss5 | stringstream.cpp:31:7:31:9 | ss5 | |
|
||||
| stringstream.cpp:34:32:34:37 | source | stringstream.cpp:39:9:39:14 | source | |
|
||||
| stringstream.cpp:36:20:36:22 | call to basic_stringstream | stringstream.cpp:38:2:38:4 | ss1 | |
|
||||
| stringstream.cpp:36:20:36:22 | call to basic_stringstream | stringstream.cpp:41:7:41:9 | ss1 | |
|
||||
| stringstream.cpp:36:20:36:22 | call to basic_stringstream | stringstream.cpp:43:7:43:9 | ss1 | |
|
||||
| stringstream.cpp:36:25:36:27 | call to basic_stringstream | stringstream.cpp:39:2:39:4 | ss2 | |
|
||||
| stringstream.cpp:36:25:36:27 | call to basic_stringstream | stringstream.cpp:42:7:42:9 | ss2 | |
|
||||
| stringstream.cpp:36:25:36:27 | call to basic_stringstream | stringstream.cpp:44:7:44:9 | ss2 | |
|
||||
| stringstream.cpp:38:2:38:4 | ref arg ss1 | stringstream.cpp:41:7:41:9 | ss1 | |
|
||||
| stringstream.cpp:38:2:38:4 | ref arg ss1 | stringstream.cpp:43:7:43:9 | ss1 | |
|
||||
| stringstream.cpp:39:2:39:4 | ref arg ss2 | stringstream.cpp:42:7:42:9 | ss2 | |
|
||||
| stringstream.cpp:39:2:39:4 | ref arg ss2 | stringstream.cpp:44:7:44:9 | ss2 | |
|
||||
| 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] | |
|
||||
|
@ -1305,3 +1330,57 @@
|
|||
| taint.cpp:483:18:483:19 | ref arg & ... | taint.cpp:483:19:483:19 | n [inner post update] | |
|
||||
| taint.cpp:483:19:483:19 | n | taint.cpp:483:18:483:19 | & ... | |
|
||||
| taint.cpp:483:28:483:34 | source1 | taint.cpp:483:11:483:15 | ref arg & ... | TAINT |
|
||||
| vector.cpp:8:43:8:49 | source1 | vector.cpp:12:21:12:27 | source1 | |
|
||||
| vector.cpp:8:43:8:49 | source1 | vector.cpp:26:33:26:39 | source1 | |
|
||||
| vector.cpp:12:21:12:27 | source1 | vector.cpp:12:21:12:28 | call to vector | TAINT |
|
||||
| vector.cpp:12:21:12:28 | call to vector | vector.cpp:14:14:14:14 | v | |
|
||||
| vector.cpp:12:21:12:28 | call to vector | vector.cpp:18:38:18:38 | v | |
|
||||
| vector.cpp:12:21:12:28 | call to vector | vector.cpp:18:55:18:55 | v | |
|
||||
| vector.cpp:12:21:12:28 | call to vector | vector.cpp:22:15:22:15 | v | |
|
||||
| vector.cpp:14:14:14:14 | call to begin | vector.cpp:14:14:14:14 | (__begin) | |
|
||||
| vector.cpp:14:14:14:14 | call to begin | vector.cpp:14:14:14:14 | (__begin) | |
|
||||
| vector.cpp:14:14:14:14 | call to begin | vector.cpp:14:14:14:14 | (__begin) | |
|
||||
| vector.cpp:14:14:14:14 | call to end | vector.cpp:14:14:14:14 | (__end) | |
|
||||
| vector.cpp:14:14:14:14 | call to operator* | vector.cpp:15:8:15:8 | x | |
|
||||
| vector.cpp:14:14:14:14 | ref arg (__begin) | vector.cpp:14:14:14:14 | (__begin) | |
|
||||
| vector.cpp:14:14:14:14 | ref arg (__begin) | vector.cpp:14:14:14:14 | (__begin) | |
|
||||
| vector.cpp:14:14:14:14 | ref arg (__begin) | vector.cpp:14:14:14:14 | (__begin) | |
|
||||
| vector.cpp:14:14:14:14 | ref arg (__range) | vector.cpp:14:14:14:14 | (__range) | |
|
||||
| vector.cpp:14:14:14:14 | v | vector.cpp:14:14:14:14 | (__range) | |
|
||||
| vector.cpp:14:14:14:14 | v | vector.cpp:14:14:14:14 | (__range) | |
|
||||
| vector.cpp:14:14:14:14 | v | vector.cpp:14:14:14:14 | call to operator* | TAINT |
|
||||
| vector.cpp:18:38:18:38 | ref arg v | vector.cpp:18:55:18:55 | v | |
|
||||
| vector.cpp:18:38:18:38 | ref arg v | vector.cpp:22:15:22:15 | v | |
|
||||
| vector.cpp:18:40:18:44 | call to begin | vector.cpp:18:49:18:50 | it | |
|
||||
| vector.cpp:18:40:18:44 | call to begin | vector.cpp:18:66:18:67 | it | |
|
||||
| vector.cpp:18:40:18:44 | call to begin | vector.cpp:19:9:19:10 | it | |
|
||||
| vector.cpp:18:55:18:55 | ref arg v | vector.cpp:18:55:18:55 | v | |
|
||||
| vector.cpp:18:55:18:55 | ref arg v | vector.cpp:22:15:22:15 | v | |
|
||||
| vector.cpp:18:66:18:67 | ref arg it | vector.cpp:18:49:18:50 | it | |
|
||||
| vector.cpp:18:66:18:67 | ref arg it | vector.cpp:18:66:18:67 | it | |
|
||||
| vector.cpp:18:66:18:67 | ref arg it | vector.cpp:19:9:19:10 | it | |
|
||||
| vector.cpp:22:15:22:15 | call to begin | vector.cpp:22:15:22:15 | (__begin) | |
|
||||
| vector.cpp:22:15:22:15 | call to begin | vector.cpp:22:15:22:15 | (__begin) | |
|
||||
| vector.cpp:22:15:22:15 | call to begin | vector.cpp:22:15:22:15 | (__begin) | |
|
||||
| vector.cpp:22:15:22:15 | call to end | vector.cpp:22:15:22:15 | (__end) | |
|
||||
| vector.cpp:22:15:22:15 | call to operator* | vector.cpp:23:8:23:8 | x | |
|
||||
| vector.cpp:22:15:22:15 | ref arg (__begin) | vector.cpp:22:15:22:15 | (__begin) | |
|
||||
| vector.cpp:22:15:22:15 | ref arg (__begin) | vector.cpp:22:15:22:15 | (__begin) | |
|
||||
| vector.cpp:22:15:22:15 | ref arg (__begin) | vector.cpp:22:15:22:15 | (__begin) | |
|
||||
| vector.cpp:22:15:22:15 | ref arg (__range) | vector.cpp:22:15:22:15 | (__range) | |
|
||||
| vector.cpp:22:15:22:15 | v | vector.cpp:22:15:22:15 | (__range) | |
|
||||
| vector.cpp:22:15:22:15 | v | vector.cpp:22:15:22:15 | (__range) | |
|
||||
| vector.cpp:22:15:22:15 | v | vector.cpp:22:15:22:15 | call to operator* | TAINT |
|
||||
| vector.cpp:26:33:26:39 | source1 | vector.cpp:26:33:26:40 | call to vector | TAINT |
|
||||
| vector.cpp:26:33:26:40 | call to vector | vector.cpp:27:21:27:27 | const_v | |
|
||||
| vector.cpp:27:21:27:21 | call to begin | vector.cpp:27:21:27:21 | (__begin) | |
|
||||
| vector.cpp:27:21:27:21 | call to begin | vector.cpp:27:21:27:21 | (__begin) | |
|
||||
| vector.cpp:27:21:27:21 | call to begin | vector.cpp:27:21:27:21 | (__begin) | |
|
||||
| vector.cpp:27:21:27:21 | call to end | vector.cpp:27:21:27:21 | (__end) | |
|
||||
| vector.cpp:27:21:27:21 | call to operator* | vector.cpp:28:8:28:8 | x | |
|
||||
| vector.cpp:27:21:27:21 | ref arg (__begin) | vector.cpp:27:21:27:21 | (__begin) | |
|
||||
| vector.cpp:27:21:27:21 | ref arg (__begin) | vector.cpp:27:21:27:21 | (__begin) | |
|
||||
| vector.cpp:27:21:27:21 | ref arg (__begin) | vector.cpp:27:21:27:21 | (__begin) | |
|
||||
| vector.cpp:27:21:27:27 | const_v | vector.cpp:27:21:27:21 | (__range) | |
|
||||
| vector.cpp:27:21:27:27 | const_v | vector.cpp:27:21:27:21 | (__range) | |
|
||||
| vector.cpp:27:21:27:27 | const_v | vector.cpp:27:21:27:21 | call to operator* | TAINT |
|
||||
|
|
|
@ -1,310 +0,0 @@
|
|||
|
||||
typedef unsigned long size_t;
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<class charT> struct char_traits;
|
||||
|
||||
typedef size_t streamsize;
|
||||
|
||||
struct ptrdiff_t;
|
||||
|
||||
template <class iterator_category,
|
||||
class value_type,
|
||||
class difference_type = ptrdiff_t,
|
||||
class pointer_type = value_type*,
|
||||
class reference_type = value_type&>
|
||||
struct iterator {
|
||||
iterator &operator++();
|
||||
iterator operator++(int);
|
||||
bool operator==(iterator other) const;
|
||||
bool operator!=(iterator other) const;
|
||||
reference_type operator*() const;
|
||||
};
|
||||
|
||||
struct input_iterator_tag {};
|
||||
struct forward_iterator_tag : public input_iterator_tag {};
|
||||
struct bidirectional_iterator_tag : public forward_iterator_tag {};
|
||||
struct random_access_iterator_tag : public bidirectional_iterator_tag {};
|
||||
|
||||
template <class T> class allocator {
|
||||
public:
|
||||
allocator() throw();
|
||||
};
|
||||
|
||||
template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
|
||||
class basic_string {
|
||||
public:
|
||||
explicit basic_string(const Allocator& a = Allocator());
|
||||
basic_string(const charT* s, const Allocator& a = Allocator());
|
||||
|
||||
const charT* c_str() const;
|
||||
|
||||
typedef std::iterator<random_access_iterator_tag, charT> iterator;
|
||||
typedef std::iterator<random_access_iterator_tag, const charT> const_iterator;
|
||||
|
||||
iterator begin();
|
||||
iterator end();
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
const_iterator cbegin() const;
|
||||
const_iterator cend() const;
|
||||
};
|
||||
|
||||
typedef basic_string<char> string;
|
||||
|
||||
template <class charT, class traits = char_traits<charT> >
|
||||
class basic_istream /*: virtual public basic_ios<charT,traits> - not needed for this test */ {
|
||||
public:
|
||||
basic_istream<charT,traits>& operator>>(int& n);
|
||||
};
|
||||
|
||||
template <class charT, class traits = char_traits<charT> >
|
||||
class basic_ostream /*: virtual public basic_ios<charT,traits> - not needed for this test */ {
|
||||
public:
|
||||
typedef charT char_type;
|
||||
basic_ostream<charT,traits>& write(const char_type* s, streamsize n);
|
||||
|
||||
basic_ostream<charT, traits>& operator<<(int n);
|
||||
};
|
||||
|
||||
template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const charT*);
|
||||
template<class charT, class traits, class Allocator> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str);
|
||||
|
||||
template<class charT, class traits = char_traits<charT>>
|
||||
class basic_iostream : public basic_istream<charT, traits>, public basic_ostream<charT, traits> {
|
||||
public:
|
||||
};
|
||||
|
||||
template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
|
||||
class basic_stringstream : public basic_iostream<charT, traits> {
|
||||
public:
|
||||
explicit basic_stringstream(/*ios_base::openmode which = ios_base::out|ios_base::in - not needed for this test*/);
|
||||
|
||||
basic_string<charT, traits, Allocator> str() const;
|
||||
};
|
||||
|
||||
using stringstream = basic_stringstream<char>;
|
||||
}
|
||||
|
||||
char *source();
|
||||
void sink(const char *s) {};
|
||||
void sink(const std::string &s) {};
|
||||
void sink(const std::stringstream &s) {};
|
||||
|
||||
void test_string()
|
||||
{
|
||||
char *a = source();
|
||||
std::string b("123");
|
||||
std::string c(source());
|
||||
|
||||
sink(a); // tainted
|
||||
sink(b);
|
||||
sink(c); // tainted
|
||||
sink(b.c_str());
|
||||
sink(c.c_str()); // tainted
|
||||
}
|
||||
|
||||
void test_stringstream()
|
||||
{
|
||||
std::stringstream ss1, ss2, ss3, ss4, ss5;
|
||||
std::string t(source());
|
||||
|
||||
ss1 << "1234";
|
||||
ss2 << source();
|
||||
ss3 << "123" << source();
|
||||
ss4 << source() << "456";
|
||||
ss5 << t;
|
||||
|
||||
sink(ss1);
|
||||
sink(ss2); // tainted [NOT DETECTED]
|
||||
sink(ss3); // tainted [NOT DETECTED]
|
||||
sink(ss4); // tainted [NOT DETECTED]
|
||||
sink(ss5); // tainted [NOT DETECTED]
|
||||
sink(ss1.str());
|
||||
sink(ss2.str()); // tainted [NOT DETECTED]
|
||||
sink(ss3.str()); // tainted [NOT DETECTED]
|
||||
sink(ss4.str()); // tainted [NOT DETECTED]
|
||||
sink(ss5.str()); // tainted [NOT DETECTED]
|
||||
}
|
||||
|
||||
void test_stringstream_int(int source)
|
||||
{
|
||||
std::stringstream ss1, ss2;
|
||||
|
||||
ss1 << 1234;
|
||||
ss2 << source;
|
||||
|
||||
sink(ss1);
|
||||
sink(ss2); // tainted [NOT DETECTED]
|
||||
sink(ss1.str());
|
||||
sink(ss2.str()); // tainted [NOT DETECTED]
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
||||
char *user_input() {
|
||||
return source();
|
||||
}
|
||||
|
||||
void sink(const char *filename, const char *mode);
|
||||
|
||||
void test_strings2()
|
||||
{
|
||||
string path1 = user_input();
|
||||
sink(path1.c_str(), "r"); // tainted
|
||||
|
||||
string path2;
|
||||
path2 = user_input();
|
||||
sink(path2.c_str(), "r"); // tainted
|
||||
|
||||
string path3(user_input());
|
||||
sink(path3.c_str(), "r"); // tainted
|
||||
}
|
||||
|
||||
void test_string3()
|
||||
{
|
||||
const char *cs = source();
|
||||
|
||||
// convert char * -> std::string
|
||||
std::string ss(cs);
|
||||
|
||||
sink(cs); // tainted
|
||||
sink(ss); // tainted
|
||||
}
|
||||
|
||||
void test_string4()
|
||||
{
|
||||
const char *cs = source();
|
||||
|
||||
// convert char * -> std::string
|
||||
std::string ss(cs);
|
||||
|
||||
// convert back std::string -> char *
|
||||
cs = ss.c_str();
|
||||
|
||||
sink(cs); // tainted
|
||||
sink(ss); // tainted
|
||||
}
|
||||
|
||||
void test_string_constructors_assignments()
|
||||
{
|
||||
{
|
||||
std::string s1("hello");
|
||||
std::string s2 = "hello";
|
||||
std::string s3;
|
||||
s3 = "hello";
|
||||
|
||||
sink(s1);
|
||||
sink(s2);
|
||||
sink(s3);
|
||||
}
|
||||
|
||||
{
|
||||
std::string s1(source());
|
||||
std::string s2 = source();
|
||||
std::string s3;
|
||||
s3 = source();
|
||||
|
||||
sink(s1); // tainted
|
||||
sink(s2); // tainted
|
||||
sink(s3); // tainted
|
||||
}
|
||||
|
||||
{
|
||||
std::string s1;
|
||||
std::string s2 = s1;
|
||||
std::string s3;
|
||||
s3 = s1;
|
||||
|
||||
sink(s1);
|
||||
sink(s2);
|
||||
sink(s3);
|
||||
}
|
||||
|
||||
{
|
||||
std::string s1 = std::string(source());
|
||||
std::string s2;
|
||||
s2 = std::string(source());
|
||||
|
||||
sink(s1); // tainted
|
||||
sink(s2); // tainted
|
||||
}
|
||||
}
|
||||
|
||||
void sink(char) {}
|
||||
|
||||
void test_range_based_for_loop_string() {
|
||||
std::string s(source());
|
||||
for(char c : s) {
|
||||
sink(c); // tainted [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
for(std::string::iterator it = s.begin(); it != s.end(); ++it) {
|
||||
sink(*it); // tainted [NOT DETECTED]
|
||||
}
|
||||
|
||||
for(char& c : s) {
|
||||
sink(c); // tainted [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
const std::string const_s(source());
|
||||
for(const char& c : const_s) {
|
||||
sink(c); // tainted [NOT DETECTED by IR]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace std {
|
||||
template <class T>
|
||||
class vector {
|
||||
private:
|
||||
void *data_;
|
||||
public:
|
||||
vector(int size);
|
||||
|
||||
T& operator[](int idx);
|
||||
const T& operator[](int idx) const;
|
||||
|
||||
typedef std::iterator<random_access_iterator_tag, T> iterator;
|
||||
typedef std::iterator<random_access_iterator_tag, const T> const_iterator;
|
||||
|
||||
iterator begin() noexcept;
|
||||
iterator end() noexcept;
|
||||
|
||||
const_iterator begin() const noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
};
|
||||
}
|
||||
|
||||
void sink(int);
|
||||
|
||||
void test_range_based_for_loop_vector(int source1) {
|
||||
// Tainting the vector by allocating a tainted length. This doesn't represent
|
||||
// how a vector would typically get tainted, but it allows this test to avoid
|
||||
// being concerned with std::vector modeling.
|
||||
std::vector<int> v(source1);
|
||||
|
||||
for(int x : v) {
|
||||
sink(x); // tainted [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
for(std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
|
||||
sink(*it); // tainted [NOT DETECTED]
|
||||
}
|
||||
|
||||
for(int& x : v) {
|
||||
sink(x); // tainted [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
const std::vector<int> const_v(source1);
|
||||
for(const int& x : const_v) {
|
||||
sink(x); // tainted [NOT DETECTED by IR]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
|
||||
typedef unsigned long size_t;
|
||||
|
||||
// --- string ---
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<class charT> struct char_traits;
|
||||
|
||||
typedef size_t streamsize;
|
||||
|
||||
struct ptrdiff_t;
|
||||
|
||||
template <class iterator_category,
|
||||
class value_type,
|
||||
class difference_type = ptrdiff_t,
|
||||
class pointer_type = value_type*,
|
||||
class reference_type = value_type&>
|
||||
struct iterator {
|
||||
iterator &operator++();
|
||||
iterator operator++(int);
|
||||
bool operator==(iterator other) const;
|
||||
bool operator!=(iterator other) const;
|
||||
reference_type operator*() const;
|
||||
};
|
||||
|
||||
struct input_iterator_tag {};
|
||||
struct forward_iterator_tag : public input_iterator_tag {};
|
||||
struct bidirectional_iterator_tag : public forward_iterator_tag {};
|
||||
struct random_access_iterator_tag : public bidirectional_iterator_tag {};
|
||||
|
||||
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());
|
||||
|
||||
const charT* c_str() const;
|
||||
|
||||
typedef std::iterator<random_access_iterator_tag, charT> iterator;
|
||||
typedef std::iterator<random_access_iterator_tag, const charT> const_iterator;
|
||||
|
||||
iterator begin();
|
||||
iterator end();
|
||||
const_iterator begin() const;
|
||||
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> >
|
||||
class basic_istream /*: virtual public basic_ios<charT,traits> - not needed for this test */ {
|
||||
public:
|
||||
basic_istream<charT,traits>& operator>>(int& n);
|
||||
};
|
||||
|
||||
template <class charT, class traits = char_traits<charT> >
|
||||
class basic_ostream /*: virtual public basic_ios<charT,traits> - not needed for this test */ {
|
||||
public:
|
||||
typedef charT char_type;
|
||||
basic_ostream<charT,traits>& write(const char_type* s, streamsize n);
|
||||
|
||||
basic_ostream<charT, traits>& operator<<(int n);
|
||||
};
|
||||
|
||||
template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const charT*);
|
||||
template<class charT, class traits, class Allocator> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str);
|
||||
|
||||
template<class charT, class traits = char_traits<charT>>
|
||||
class basic_iostream : public basic_istream<charT, traits>, public basic_ostream<charT, traits> {
|
||||
public:
|
||||
};
|
||||
|
||||
template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
|
||||
class basic_stringstream : public basic_iostream<charT, traits> {
|
||||
public:
|
||||
explicit basic_stringstream(/*ios_base::openmode which = ios_base::out|ios_base::in - not needed for this test*/);
|
||||
|
||||
basic_string<charT, traits, Allocator> str() const;
|
||||
};
|
||||
|
||||
using stringstream = basic_stringstream<char>;
|
||||
}
|
||||
|
||||
// --- vector ---
|
||||
|
||||
namespace std {
|
||||
template <class T>
|
||||
class vector {
|
||||
private:
|
||||
void *data_;
|
||||
public:
|
||||
vector(int size);
|
||||
|
||||
T& operator[](int idx);
|
||||
const T& operator[](int idx) const;
|
||||
|
||||
typedef std::iterator<random_access_iterator_tag, T> iterator;
|
||||
typedef std::iterator<random_access_iterator_tag, const T> const_iterator;
|
||||
|
||||
iterator begin() noexcept;
|
||||
iterator end() noexcept;
|
||||
|
||||
const_iterator begin() const noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,186 @@
|
|||
|
||||
#include "stl.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
char *source();
|
||||
|
||||
namespace ns_char
|
||||
{
|
||||
char source();
|
||||
}
|
||||
|
||||
char *user_input() {
|
||||
return source();
|
||||
}
|
||||
|
||||
void sink(const char *s) {};
|
||||
void sink(const std::string &s) {};
|
||||
void sink(const char *filename, const char *mode);
|
||||
void sink(char) {}
|
||||
|
||||
void test_string()
|
||||
{
|
||||
char *a = source();
|
||||
std::string b("123");
|
||||
std::string c(source());
|
||||
|
||||
sink(a); // tainted
|
||||
sink(b);
|
||||
sink(c); // tainted
|
||||
sink(b.c_str());
|
||||
sink(c.c_str()); // tainted
|
||||
}
|
||||
|
||||
void test_strings2()
|
||||
{
|
||||
string path1 = user_input();
|
||||
sink(path1.c_str(), "r"); // tainted
|
||||
|
||||
string path2;
|
||||
path2 = user_input();
|
||||
sink(path2.c_str(), "r"); // tainted
|
||||
|
||||
string path3(user_input());
|
||||
sink(path3.c_str(), "r"); // tainted
|
||||
}
|
||||
|
||||
void test_string3()
|
||||
{
|
||||
const char *cs = source();
|
||||
|
||||
// convert char * -> std::string
|
||||
std::string ss(cs);
|
||||
|
||||
sink(cs); // tainted
|
||||
sink(ss); // tainted
|
||||
}
|
||||
|
||||
void test_string4()
|
||||
{
|
||||
const char *cs = source();
|
||||
|
||||
// convert char * -> std::string
|
||||
std::string ss(cs);
|
||||
|
||||
// convert back std::string -> char *
|
||||
cs = ss.c_str();
|
||||
|
||||
sink(cs); // tainted
|
||||
sink(ss); // tainted
|
||||
}
|
||||
|
||||
void test_string_constructors_assignments()
|
||||
{
|
||||
{
|
||||
std::string s1("hello");
|
||||
std::string s2 = "hello";
|
||||
std::string s3;
|
||||
s3 = "hello";
|
||||
|
||||
sink(s1);
|
||||
sink(s2);
|
||||
sink(s3);
|
||||
}
|
||||
|
||||
{
|
||||
std::string s1(source());
|
||||
std::string s2 = source();
|
||||
std::string s3;
|
||||
s3 = source();
|
||||
|
||||
sink(s1); // tainted
|
||||
sink(s2); // tainted
|
||||
sink(s3); // tainted
|
||||
}
|
||||
|
||||
{
|
||||
std::string s1;
|
||||
std::string s2 = s1;
|
||||
std::string s3;
|
||||
s3 = s1;
|
||||
|
||||
sink(s1);
|
||||
sink(s2);
|
||||
sink(s3);
|
||||
}
|
||||
|
||||
{
|
||||
std::string s1 = std::string(source());
|
||||
std::string s2;
|
||||
s2 = std::string(source());
|
||||
|
||||
sink(s1); // tainted
|
||||
sink(s2); // tainted
|
||||
}
|
||||
}
|
||||
|
||||
void test_range_based_for_loop_string() {
|
||||
std::string s(source());
|
||||
for(char c : s) {
|
||||
sink(c); // tainted [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
for(std::string::iterator it = s.begin(); it != s.end(); ++it) {
|
||||
sink(*it); // tainted [NOT DETECTED]
|
||||
}
|
||||
|
||||
for(char& c : s) {
|
||||
sink(c); // tainted [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
const std::string const_s(source());
|
||||
for(const char& c : const_s) {
|
||||
sink(c); // tainted [NOT DETECTED by IR]
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
|
||||
#include "stl.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
char *source();
|
||||
|
||||
void sink(const std::string &s) {};
|
||||
void sink(const std::stringstream &s) {};
|
||||
|
||||
void test_stringstream()
|
||||
{
|
||||
std::stringstream ss1, ss2, ss3, ss4, ss5;
|
||||
std::string t(source());
|
||||
|
||||
ss1 << "1234";
|
||||
ss2 << source();
|
||||
ss3 << "123" << source();
|
||||
ss4 << source() << "456";
|
||||
ss5 << t;
|
||||
|
||||
sink(ss1);
|
||||
sink(ss2); // tainted [NOT DETECTED]
|
||||
sink(ss3); // tainted [NOT DETECTED]
|
||||
sink(ss4); // tainted [NOT DETECTED]
|
||||
sink(ss5); // tainted [NOT DETECTED]
|
||||
sink(ss1.str());
|
||||
sink(ss2.str()); // tainted [NOT DETECTED]
|
||||
sink(ss3.str()); // tainted [NOT DETECTED]
|
||||
sink(ss4.str()); // tainted [NOT DETECTED]
|
||||
sink(ss5.str()); // tainted [NOT DETECTED]
|
||||
}
|
||||
|
||||
void test_stringstream_int(int source)
|
||||
{
|
||||
std::stringstream ss1, ss2;
|
||||
|
||||
ss1 << 1234;
|
||||
ss2 << source;
|
||||
|
||||
sink(ss1);
|
||||
sink(ss2); // tainted [NOT DETECTED]
|
||||
sink(ss1.str());
|
||||
sink(ss2.str()); // tainted [NOT DETECTED]
|
||||
}
|
|
@ -32,27 +32,34 @@
|
|||
| 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 |
|
||||
| string.cpp:28:7:28:7 | a | string.cpp:24:12:24:17 | call to source |
|
||||
| string.cpp:30:7:30:7 | c | string.cpp:26:16:26:21 | call to source |
|
||||
| string.cpp:32:9:32:13 | call to c_str | string.cpp:26:16:26:21 | call to source |
|
||||
| string.cpp:38:13:38:17 | call to c_str | string.cpp:14:10:14:15 | call to source |
|
||||
| string.cpp:42:13:42:17 | call to c_str | string.cpp:14:10:14:15 | call to source |
|
||||
| string.cpp:45:13:45:17 | call to c_str | string.cpp:14:10:14:15 | call to source |
|
||||
| string.cpp:55:7:55:8 | cs | string.cpp:50:19:50:24 | call to source |
|
||||
| string.cpp:56:7:56:8 | ss | string.cpp:50:19:50:24 | call to source |
|
||||
| string.cpp:69:7:69:8 | cs | string.cpp:61:19:61:24 | call to source |
|
||||
| string.cpp:70:7:70:8 | ss | string.cpp:61:19:61:24 | call to source |
|
||||
| string.cpp:92:8:92:9 | s1 | string.cpp:87:18:87:23 | call to source |
|
||||
| string.cpp:93:8:93:9 | s2 | string.cpp:88:20:88:25 | call to source |
|
||||
| string.cpp:94:8:94:9 | s3 | string.cpp:90:8:90:13 | call to source |
|
||||
| string.cpp:113:8:113:9 | s1 | string.cpp:109:32:109:37 | call to source |
|
||||
| string.cpp:114:8:114:9 | s2 | string.cpp:111:20:111:25 | call to source |
|
||||
| string.cpp:121:8:121:8 | c | string.cpp:119:16:119:21 | call to source |
|
||||
| string.cpp:129:8:129:8 | c | string.cpp:119:16:119:21 | call to source |
|
||||
| string.cpp:134:8:134:8 | c | string.cpp:132:28:132:33 | call to source |
|
||||
| string.cpp:144:11:144:11 | call to operator+ | string.cpp:141:18:141:23 | call to source |
|
||||
| string.cpp:145:11:145:11 | call to operator+ | string.cpp:141:18:141:23 | call to source |
|
||||
| string.cpp:146:11:146:11 | call to operator+ | string.cpp:141:18:141:23 | call to source |
|
||||
| string.cpp:149:11:149:11 | call to operator+ | string.cpp:149:13:149:18 | call to source |
|
||||
| string.cpp:158:8:158:9 | s5 | string.cpp:154:18:154:23 | call to source |
|
||||
| string.cpp:162:8:162:9 | s6 | string.cpp:154:18:154:23 | call to source |
|
||||
| string.cpp:167:8:167:9 | s7 | string.cpp:165:9:165:14 | call to source |
|
||||
| string.cpp:171:8:171:9 | s8 | string.cpp:154:18:154:23 | call to source |
|
||||
| string.cpp:176:8:176:9 | s9 | string.cpp:174:13:174:18 | call to source |
|
||||
| string.cpp:184:8:184:10 | s10 | string.cpp:181:12:181:26 | call to source |
|
||||
| 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 |
|
||||
|
@ -159,3 +166,6 @@
|
|||
| taint.cpp:470:7:470:7 | x | taint.cpp:462:6:462:11 | call to source |
|
||||
| taint.cpp:471:7:471:7 | y | taint.cpp:462:6:462:11 | call to source |
|
||||
| taint.cpp:485:7:485:10 | line | taint.cpp:480:26:480:32 | source1 |
|
||||
| vector.cpp:15:8:15:8 | x | vector.cpp:8:43:8:49 | source1 |
|
||||
| vector.cpp:23:8:23:8 | x | vector.cpp:8:43:8:49 | source1 |
|
||||
| vector.cpp:28:8:28:8 | x | vector.cpp:8:43:8:49 | source1 |
|
||||
|
|
|
@ -30,26 +30,33 @@
|
|||
| 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 |
|
||||
| string.cpp:30:7:30:7 | string.cpp:26:16:26:21 | AST only |
|
||||
| string.cpp:32:9:32:13 | string.cpp:26:16:26:21 | AST only |
|
||||
| string.cpp:38:13:38:17 | string.cpp:14:10:14:15 | AST only |
|
||||
| string.cpp:42:13:42:17 | string.cpp:14:10:14:15 | AST only |
|
||||
| string.cpp:45:13:45:17 | string.cpp:14:10:14:15 | AST only |
|
||||
| string.cpp:55:7:55:8 | string.cpp:50:19:50:26 | IR only |
|
||||
| string.cpp:56:7:56:8 | string.cpp:50:19:50:24 | AST only |
|
||||
| string.cpp:69:7:69:8 | string.cpp:61:19:61:24 | AST only |
|
||||
| string.cpp:70:7:70:8 | string.cpp:61:19:61:24 | AST only |
|
||||
| string.cpp:92:8:92:9 | string.cpp:87:18:87:23 | AST only |
|
||||
| string.cpp:93:8:93:9 | string.cpp:88:20:88:25 | AST only |
|
||||
| string.cpp:94:8:94:9 | string.cpp:90:8:90:13 | AST only |
|
||||
| string.cpp:113:8:113:9 | string.cpp:109:32:109:37 | AST only |
|
||||
| string.cpp:114:8:114:9 | string.cpp:111:20:111:25 | AST only |
|
||||
| string.cpp:121:8:121:8 | string.cpp:119:16:119:21 | AST only |
|
||||
| string.cpp:129:8:129:8 | string.cpp:119:16:119:21 | AST only |
|
||||
| string.cpp:134:8:134:8 | string.cpp:132:28:132:33 | AST only |
|
||||
| string.cpp:144:11:144:11 | string.cpp:141:18:141:23 | AST only |
|
||||
| string.cpp:145:11:145:11 | string.cpp:141:18:141:23 | AST only |
|
||||
| string.cpp:146:11:146:11 | string.cpp:141:18:141:23 | AST only |
|
||||
| string.cpp:149:11:149:11 | string.cpp:149:13:149:18 | AST only |
|
||||
| string.cpp:158:8:158:9 | string.cpp:154:18:154:23 | AST only |
|
||||
| string.cpp:162:8:162:9 | string.cpp:154:18:154:23 | AST only |
|
||||
| string.cpp:167:8:167:9 | string.cpp:165:9:165:14 | AST only |
|
||||
| string.cpp:171:8:171:9 | string.cpp:154:18:154:23 | AST only |
|
||||
| string.cpp:176:8:176:9 | string.cpp:174:13:174:18 | AST only |
|
||||
| string.cpp:184:8:184:10 | string.cpp:181:12:181:26 | AST only |
|
||||
| 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 |
|
||||
|
@ -94,3 +101,6 @@
|
|||
| taint.cpp:446:7:446:7 | taint.cpp:445:14:445:28 | AST only |
|
||||
| taint.cpp:447:9:447:17 | taint.cpp:445:14:445:28 | AST only |
|
||||
| taint.cpp:471:7:471:7 | taint.cpp:462:6:462:11 | AST only |
|
||||
| vector.cpp:15:8:15:8 | vector.cpp:8:43:8:49 | AST only |
|
||||
| vector.cpp:23:8:23:8 | vector.cpp:8:43:8:49 | AST only |
|
||||
| vector.cpp:28:8:28:8 | vector.cpp:8:43:8:49 | AST only |
|
||||
|
|
|
@ -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 *)... |
|
||||
| string.cpp:28:7:28:7 | (const char *)... | string.cpp:24:12:24:17 | call to source |
|
||||
| string.cpp:28:7:28:7 | a | string.cpp:24:12:24:17 | call to source |
|
||||
| string.cpp:55:7:55:8 | cs | string.cpp:50:19:50:24 | call to source |
|
||||
| string.cpp:55:7:55:8 | cs | string.cpp:50:19:50:26 | (const char *)... |
|
||||
| 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 |
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
#include "stl.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void sink(int);
|
||||
|
||||
void test_range_based_for_loop_vector(int source1) {
|
||||
// Tainting the vector by allocating a tainted length. This doesn't represent
|
||||
// how a vector would typically get tainted, but it allows this test to avoid
|
||||
// being concerned with std::vector modeling.
|
||||
std::vector<int> v(source1);
|
||||
|
||||
for(int x : v) {
|
||||
sink(x); // tainted [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
for(std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
|
||||
sink(*it); // tainted [NOT DETECTED]
|
||||
}
|
||||
|
||||
for(int& x : v) {
|
||||
sink(x); // tainted [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
const std::vector<int> const_v(source1);
|
||||
for(const int& x : const_v) {
|
||||
sink(x); // tainted [NOT DETECTED by IR]
|
||||
}
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,4 +1,4 @@
|
|||
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||
|
||||
from VariableAccess expr
|
||||
select expr, lowerBound(expr)
|
||||
select expr, lowerBound(expr).toString()
|
||||
|
|
|
@ -422,7 +422,7 @@ void test17() {
|
|||
out(i); // 50
|
||||
|
||||
i = 20 + (j -= 10);
|
||||
out(i); // 60 [BUG: the analysis thinks it's 2^-31 .. 2^31-1]
|
||||
out(i); // 60
|
||||
}
|
||||
|
||||
// Tests for unsigned multiplication.
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,4 +1,4 @@
|
|||
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||
|
||||
from VariableAccess expr
|
||||
select expr, upperBound(expr)
|
||||
select expr, upperBound(expr).toString()
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
|
|
|
@ -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. |
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import csharp
|
||||
private import semmle.code.csharp.frameworks.System
|
||||
private import semmle.code.csharp.dataflow.DataFlow2
|
||||
private import semmle.code.csharp.dataflow.DataFlow3
|
||||
|
||||
/** The `System.Xml` namespace. */
|
||||
class SystemXmlNamespace extends Namespace {
|
||||
|
@ -163,7 +163,7 @@ class XmlReaderSettingsCreation extends ObjectCreation {
|
|||
}
|
||||
}
|
||||
|
||||
private class SettingsDataFlowConfig extends DataFlow2::Configuration {
|
||||
private class SettingsDataFlowConfig extends DataFlow3::Configuration {
|
||||
SettingsDataFlowConfig() { this = "SettingsDataFlowConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
public class XSS extends HttpServlet {
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
// BAD: a request parameter is written directly to an error response page
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND,
|
||||
"The page \"" + request.getParameter("page") + "\" was not found.");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
public class SQLInjection extends HttpServlet {
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
|
||||
StringBuilder sqlQueryBuilder = new StringBuilder();
|
||||
sqlQueryBuilder.append("SELECT * FROM user WHERE user_id='");
|
||||
sqlQueryBuilder.append(request.getParameter("user_id"));
|
||||
sqlQueryBuilder.append("'");
|
||||
|
||||
// ...
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>Using unsanitized untrusted data in an external API can cause a variety of security issues. This query reports
|
||||
all external APIs that are used with untrusted data, along with how frequently the API is used, and how many
|
||||
unique sources of untrusted data flow to this API. This query is designed primarily to help identify which APIs
|
||||
may be relevant for security analysis of this application.</p>
|
||||
|
||||
<p>An external API is defined as a method call to a method that is not defined in the source code, not overridden
|
||||
in the source code, and is not modeled as a taint step in the default taint library. External APIs may be from the
|
||||
Java standard library, third party dependencies or from internal dependencies. The query will report the method
|
||||
signature with a fully qualified name, along with either <code>[param x]</code>, where <code>x</code> indicates the
|
||||
position of the parameter receiving the untrusted data or <code>[qualifier]</code> indicating the untrusted data is
|
||||
used as the qualifier to the method call.</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>For each result:</p>
|
||||
|
||||
<ul>
|
||||
<li>If the result highlights a known sink, no action is required.</li>
|
||||
<li>If the result highlights an unknown sink for a problem, then add modeling for the sink to the relevant query.</li>
|
||||
<li>If the result represents a call to an external API which transfers taint, add the appropriate modeling, and
|
||||
re-run the query to determine what new results have appeared due to this additional modeling.</li>
|
||||
</ul>
|
||||
|
||||
<p>Otherwise, the result is likely uninteresting. Custom versions of this query can extend the <code>SafeExternalAPIMethod</code>
|
||||
class to exclude known safe external APIs from future analysis.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>If the query were to return the API <code>javax.servlet.http.HttpServletResponse.sendError(int, java.lang.String) [param 1]</code>
|
||||
then we should first consider whether this a security relevant sink. In this case, this is writing to a HTTP response, so we should
|
||||
consider whether this is an XSS sink. If it is, we should confirm that it is handled by the XSS query.</p>
|
||||
|
||||
<p>If the query were to return the API <code>java.lang.StringBuilder.append(java.lang.String) [param 0]</code>, then this should be
|
||||
reviewed as a possible taint step, because tainted data would flow from the 0th argument to the qualifier of the call.</p>
|
||||
|
||||
<p>Note that both examples are correctly handled by the standard taint tracking library and XSS query.</p>
|
||||
</example>
|
||||
<references>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
|
@ -0,0 +1,18 @@
|
|||
/**
|
||||
* @name Frequency counts for external APIs that are used with untrusted data
|
||||
* @description This reports the external APIs that are used with untrusted data, along with how
|
||||
* frequently the API is called, and how many unique sources of untrusted data flow
|
||||
* to it.
|
||||
* @id java/count-untrusted-data-external-api
|
||||
* @kind table
|
||||
* @tags security external/cwe/cwe-20
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.security.ExternalAPIs
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
|
||||
from ExternalAPIUsedWithUntrustedData externalAPI
|
||||
select externalAPI, count(externalAPI.getUntrustedDataNode()) as numberOfUses,
|
||||
externalAPI.getNumberOfUntrustedSources() as numberOfUntrustedSources order by
|
||||
numberOfUntrustedSources desc
|
|
@ -0,0 +1,57 @@
|
|||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>Using unsanitized untrusted data in an external API can cause a variety of security issues. This query reports
|
||||
external APIs that use untrusted data. The results are not filtered so that you can audit all examples. The query provides data for security reviews of the application and you can also use it to identify external APIs that should be modeled as either taint steps, or sinks for specific problems.</p>
|
||||
|
||||
<p>An external API is defined as a method call to a method that is not defined in the source code, not overridden
|
||||
in the source code, and is not modeled as a taint step in the default taint library. External APIs may be from the
|
||||
Java standard library, third-party dependencies or from internal dependencies. The query reports uses of
|
||||
untrusted data in either the qualifier or as one of the arguments of external APIs.</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>For each result:</p>
|
||||
|
||||
<ul>
|
||||
<li>If the result highlights a known sink, confirm that the result is reported by the relevant query, or
|
||||
that the result is a false positive because this data is sanitized.</li>
|
||||
<li>If the result highlights an unknown sink for a problem, then add modeling for the sink to the relevant query,
|
||||
and confirm that the result is either found, or is safe due to appropriate sanitization.</li>
|
||||
<li>If the result represents a call to an external API that transfers taint, add the appropriate modeling, and
|
||||
re-run the query to determine what new results have appeared due to this additional modeling.</li>
|
||||
</ul>
|
||||
|
||||
<p>Otherwise, the result is likely uninteresting. Custom versions of this query can extend the <code>SafeExternalAPIMethod</code>
|
||||
class to exclude known safe external APIs from future analysis.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>In this first example, a request parameter is read from <code>HttpServletRequest</code> and then ultimately used in a call to the
|
||||
<code>HttpServletResponse.sendError</code> external API:</p>
|
||||
|
||||
<sample src="ExternalAPISinkExample.java" />
|
||||
|
||||
<p>This is an XSS sink. The XSS query should therefore be reviewed to confirm that this sink is appropriately modeled,
|
||||
and if it is, to confirm that the query reports this particular result, or that the result is a false positive due to
|
||||
some existing sanitization.</p>
|
||||
|
||||
<p>In this second example, again a request parameter is read from <code>HttpServletRequest</code>.</p>
|
||||
|
||||
<sample src="ExternalAPITaintStepExample.java" />
|
||||
|
||||
<p>If the query reported the call to <code>StringBuilder.append</code> on line 7, this would suggest that this external API is
|
||||
not currently modeled as a taint step in the taint tracking library. The next step would be to model this as a taint step, then
|
||||
re-run the query to determine what additional results might be found. In this example, it seems likely that the result of the
|
||||
<code>StringBuilder</code> will be executed as an SQL query, potentially leading to an SQL injection vulnerability.</p>
|
||||
|
||||
<p>Note that both examples are correctly handled by the standard taint tracking library and XSS query.</p>
|
||||
</example>
|
||||
<references>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* @name Untrusted data passed to external API
|
||||
* @description Data provided remotely is used in this external API without sanitization, which could be a security risk.
|
||||
* @id java/untrusted-data-to-external-api
|
||||
* @kind path-problem
|
||||
* @precision low
|
||||
* @problem.severity error
|
||||
* @tags security external/cwe/cwe-20
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.security.ExternalAPIs
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from UntrustedDataToExternalAPIConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where config.hasFlowPath(source, sink)
|
||||
select sink, source, sink,
|
||||
"Call to " + sink.getNode().(ExternalAPIDataNode).getMethodDescription() +
|
||||
" with untrusted data from $@.", source, source.toString()
|
|
@ -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()
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
/**
|
||||
* Definitions for reasoning about untrusted data used in APIs defined outside the
|
||||
* database.
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
|
||||
/**
|
||||
* A `Method` that is considered a "safe" external API from a security perspective.
|
||||
*/
|
||||
abstract class SafeExternalAPIMethod extends Method { }
|
||||
|
||||
/** The default set of "safe" external APIs. */
|
||||
private class DefaultSafeExternalAPIMethod extends SafeExternalAPIMethod {
|
||||
DefaultSafeExternalAPIMethod() {
|
||||
this instanceof EqualsMethod
|
||||
or
|
||||
getName().regexpMatch("size|length|compareTo|getClass|lastIndexOf")
|
||||
or
|
||||
this.getDeclaringType().hasQualifiedName("org.apache.commons.lang3", "Validate")
|
||||
or
|
||||
getQualifiedName() = "Objects.equals"
|
||||
or
|
||||
getDeclaringType() instanceof TypeString and getName() = "equals"
|
||||
or
|
||||
getDeclaringType().hasQualifiedName("com.google.common.base", "Preconditions")
|
||||
or
|
||||
getDeclaringType().getPackage().getName().matches("org.junit%")
|
||||
or
|
||||
getDeclaringType().hasQualifiedName("com.google.common.base", "Strings") and
|
||||
getName() = "isNullOrEmpty"
|
||||
or
|
||||
getDeclaringType().hasQualifiedName("org.apache.commons.lang3", "StringUtils") and
|
||||
getName() = "isNotEmpty"
|
||||
or
|
||||
getDeclaringType().hasQualifiedName("java.lang", "Character") and
|
||||
getName() = "isDigit"
|
||||
or
|
||||
getDeclaringType().hasQualifiedName("java.lang", "String") and
|
||||
getName().regexpMatch("equalsIgnoreCase|regionMatches")
|
||||
or
|
||||
getDeclaringType().hasQualifiedName("java.lang", "Boolean") and
|
||||
getName() = "parseBoolean"
|
||||
or
|
||||
getDeclaringType().hasQualifiedName("org.apache.commons.io", "IOUtils") and
|
||||
getName() = "closeQuietly"
|
||||
or
|
||||
getDeclaringType().hasQualifiedName("org.springframework.util", "StringUtils") and
|
||||
getName().regexpMatch("hasText|isEmpty")
|
||||
}
|
||||
}
|
||||
|
||||
/** A node representing data being passed to an external API. */
|
||||
class ExternalAPIDataNode extends DataFlow::Node {
|
||||
Call call;
|
||||
int i;
|
||||
|
||||
ExternalAPIDataNode() {
|
||||
(
|
||||
// Argument to call to a method
|
||||
this.asExpr() = call.getArgument(i)
|
||||
or
|
||||
// Qualifier to call to a method which returns non trivial value
|
||||
this.asExpr() = call.getQualifier() and
|
||||
i = -1 and
|
||||
not call.getCallee().getReturnType() instanceof VoidType and
|
||||
not call.getCallee().getReturnType() instanceof BooleanType
|
||||
) and
|
||||
// Defined outside the source archive
|
||||
not call.getCallee().fromSource() and
|
||||
// Not a call to an method which is overridden in source
|
||||
not exists(Method m |
|
||||
m.getASourceOverriddenMethod() = call.getCallee().getSourceDeclaration() and
|
||||
m.fromSource()
|
||||
) and
|
||||
// Not already modeled as a taint step
|
||||
not exists(DataFlow::Node next | TaintTracking::localTaintStep(this, next)) and
|
||||
// Not a call to a known safe external API
|
||||
not call.getCallee() instanceof SafeExternalAPIMethod
|
||||
}
|
||||
|
||||
/** Gets the called API `Method`. */
|
||||
Method getMethod() { result = call.getCallee() }
|
||||
|
||||
/** Gets the index which is passed untrusted data (where -1 indicates the qualifier). */
|
||||
int getIndex() { result = i }
|
||||
|
||||
/** Gets the description of the method being called. */
|
||||
string getMethodDescription() {
|
||||
result = getMethod().getDeclaringType().getPackage() + "." + getMethod().getQualifiedName()
|
||||
}
|
||||
}
|
||||
|
||||
/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalAPIDataNode`s. */
|
||||
class UntrustedDataToExternalAPIConfig extends TaintTracking::Configuration {
|
||||
UntrustedDataToExternalAPIConfig() { this = "UntrustedDataToExternalAPIConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof ExternalAPIDataNode }
|
||||
}
|
||||
|
||||
/** A node representing untrusted data being passed to an external API. */
|
||||
class UntrustedExternalAPIDataNode extends ExternalAPIDataNode {
|
||||
UntrustedExternalAPIDataNode() { any(UntrustedDataToExternalAPIConfig c).hasFlow(_, this) }
|
||||
|
||||
/** Gets a source of untrusted data which is passed to this external API data node. */
|
||||
DataFlow::Node getAnUntrustedSource() {
|
||||
any(UntrustedDataToExternalAPIConfig c).hasFlow(result, this)
|
||||
}
|
||||
}
|
||||
|
||||
private newtype TExternalAPI =
|
||||
TExternalAPIParameter(Method m, int index) {
|
||||
exists(UntrustedExternalAPIDataNode n |
|
||||
m = n.getMethod() and
|
||||
index = n.getIndex()
|
||||
)
|
||||
}
|
||||
|
||||
/** An external API which is used with untrusted data. */
|
||||
class ExternalAPIUsedWithUntrustedData extends TExternalAPI {
|
||||
/** Gets a possibly untrusted use of this external API. */
|
||||
UntrustedExternalAPIDataNode getUntrustedDataNode() {
|
||||
this = TExternalAPIParameter(result.getMethod(), result.getIndex())
|
||||
}
|
||||
|
||||
/** Gets the number of untrusted sources used with this external API. */
|
||||
int getNumberOfUntrustedSources() {
|
||||
result = count(getUntrustedDataNode().getAnUntrustedSource())
|
||||
}
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() {
|
||||
exists(Method m, int index, string indexString |
|
||||
if index = -1 then indexString = "qualifier" else indexString = "param " + index
|
||||
|
|
||||
this = TExternalAPIParameter(m, index) and
|
||||
result =
|
||||
m.getDeclaringType().(RefType).getQualifiedName() + "." + m.getSignature() + " [" +
|
||||
indexString + "]"
|
||||
)
|
||||
}
|
||||
}
|
|
@ -97,6 +97,7 @@ class WritingMethod extends Method {
|
|||
(
|
||||
this.getName().matches("print%") or
|
||||
this.getName() = "append" or
|
||||
this.getName() = "format" or
|
||||
this.getName() = "write"
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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 + ".");
|
||||
|
|
|
@ -24,5 +24,6 @@ where
|
|||
// ignore ambient, abstract, and overloaded declarations in TypeScript
|
||||
f.hasBody() and
|
||||
g.hasBody()
|
||||
select f.getId(), "Declaration of " + f.describe() + " conflicts with $@ in the same scope.",
|
||||
g.getId(), "another declaration"
|
||||
select f.getIdentifier(),
|
||||
"Declaration of " + f.describe() + " conflicts with $@ in the same scope.", g.getIdentifier(),
|
||||
"another declaration"
|
||||
|
|
|
@ -42,11 +42,11 @@ where
|
|||
access.isAmbient()
|
||||
) and
|
||||
// don't flag function expressions
|
||||
not exists(FunctionExpr fe | dead = fe.getId()) and
|
||||
not exists(FunctionExpr fe | dead = fe.getIdentifier()) and
|
||||
// don't flag function declarations nested inside blocks or other compound statements;
|
||||
// their meaning is only partially specified by the standard
|
||||
not exists(FunctionDeclStmt fd, StmtContainer outer |
|
||||
dead = fd.getId() and outer = fd.getEnclosingContainer()
|
||||
dead = fd.getIdentifier() and outer = fd.getEnclosingContainer()
|
||||
|
|
||||
not fd = outer.getBody().(BlockStmt).getAStmt()
|
||||
) and
|
||||
|
|
|
@ -22,6 +22,6 @@ where
|
|||
not decl.isAmbient() and
|
||||
not redecl.isAmbient() and
|
||||
// Redeclaring a namespace extends the previous definition.
|
||||
not decl = any(NamespaceDeclaration ns).getId() and
|
||||
not redecl = any(NamespaceDeclaration ns).getId()
|
||||
not decl = any(NamespaceDeclaration ns).getIdentifier() and
|
||||
not redecl = any(NamespaceDeclaration ns).getIdentifier()
|
||||
select redecl, "This variable has already been declared $@.", decl, "here"
|
||||
|
|
|
@ -93,7 +93,7 @@ predicate isEnumMember(VarDecl decl) { decl = any(EnumMember member).getIdentifi
|
|||
* "function f", "variable v" or "class c".
|
||||
*/
|
||||
string describeVarDecl(VarDecl vd) {
|
||||
if vd = any(Function f).getId()
|
||||
if vd = any(Function f).getIdentifier()
|
||||
then result = "function " + vd.getName()
|
||||
else
|
||||
if vd = any(ClassDefinition c).getIdentifier()
|
||||
|
@ -115,7 +115,7 @@ class ImportVarDeclProvider extends Stmt {
|
|||
*/
|
||||
VarDecl getAVarDecl() {
|
||||
result = this.(ImportDeclaration).getASpecifier().getLocal() or
|
||||
result = this.(ImportEqualsDeclaration).getId()
|
||||
result = this.(ImportEqualsDeclaration).getIdentifier()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,7 +23,7 @@ private import semmle.javascript.dataflow.InferredTypes
|
|||
* if it is part of a const enum access, so we conservatively silence the alert in that case.
|
||||
*/
|
||||
predicate namespaceOrConstEnumAccess(VarAccess e) {
|
||||
exists(NamespaceDeclaration decl | e.getVariable().getADeclaration() = decl.getId())
|
||||
exists(NamespaceDeclaration decl | e.getVariable().getADeclaration() = decl.getIdentifier())
|
||||
or
|
||||
exists(EnumDeclaration decl | e.getVariable().getADeclaration() = decl.getIdentifier() |
|
||||
decl.isConst()
|
||||
|
|
|
@ -43,6 +43,10 @@ where
|
|||
or
|
||||
// target is a HTTP URL to a domain on any TLD
|
||||
target.regexpMatch("(?i)https?://([a-z0-9-]+\\.)+([a-z]+)(:[0-9]+)?/?")
|
||||
or
|
||||
// target is a HTTP URL to a domain on any TLD with path elements, and the check is an includes check
|
||||
check instanceof StringOps::Includes and
|
||||
target.regexpMatch("(?i)https?://([a-z0-9-]+\\.)+([a-z]+)(:[0-9]+)?/[a-z0-9/_-]+")
|
||||
) and
|
||||
(
|
||||
if check instanceof StringOps::StartsWith
|
||||
|
|
|
@ -30,15 +30,17 @@ private predicate defn(ControlFlowNode def, Expr lhs, AST::ValueNode rhs) {
|
|||
or
|
||||
exists(VariableDeclarator vd | def = vd | lhs = vd.getBindingPattern() and rhs = vd.getInit())
|
||||
or
|
||||
exists(Function f | def = f.getId() | lhs = def and rhs = f)
|
||||
exists(Function f | def = f.getIdentifier() | lhs = def and rhs = f)
|
||||
or
|
||||
exists(ClassDefinition c | lhs = c.getIdentifier() | def = c and rhs = c and not c.isAmbient())
|
||||
or
|
||||
exists(NamespaceDeclaration n | def = n | lhs = n.getId() and rhs = n)
|
||||
exists(NamespaceDeclaration n | def = n | lhs = n.getIdentifier() and rhs = n)
|
||||
or
|
||||
exists(EnumDeclaration ed | def = ed.getIdentifier() | lhs = def and rhs = ed)
|
||||
or
|
||||
exists(ImportEqualsDeclaration i | def = i | lhs = i.getId() and rhs = i.getImportedEntity())
|
||||
exists(ImportEqualsDeclaration i | def = i |
|
||||
lhs = i.getIdentifier() and rhs = i.getImportedEntity()
|
||||
)
|
||||
or
|
||||
exists(ImportSpecifier i | def = i | lhs = i.getLocal() and rhs = i)
|
||||
or
|
||||
|
@ -149,7 +151,7 @@ class RValue extends RefExpr {
|
|||
or
|
||||
this = any(UpdateExpr u).getOperand().getUnderlyingReference()
|
||||
or
|
||||
this = any(NamespaceDeclaration decl).getId()
|
||||
this = any(NamespaceDeclaration decl).getIdentifier()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -330,7 +330,7 @@ class ExportDefaultDeclaration extends ExportDeclaration, @exportdefaultdeclarat
|
|||
/** Gets the declaration, if any, exported by this default export. */
|
||||
VarDecl getADecl() {
|
||||
exists(ExprOrStmt op | op = getOperand() |
|
||||
result = op.(FunctionDeclStmt).getId() or
|
||||
result = op.(FunctionDeclStmt).getIdentifier() or
|
||||
result = op.(ClassDeclStmt).getIdentifier()
|
||||
)
|
||||
}
|
||||
|
@ -364,13 +364,13 @@ class ExportNamedDeclaration extends ExportDeclaration, @exportnameddeclaration
|
|||
Identifier getAnExportedDecl() {
|
||||
exists(ExprOrStmt op | op = getOperand() |
|
||||
result = op.(DeclStmt).getADecl().getBindingPattern().getABindingVarRef() or
|
||||
result = op.(FunctionDeclStmt).getId() or
|
||||
result = op.(FunctionDeclStmt).getIdentifier() or
|
||||
result = op.(ClassDeclStmt).getIdentifier() or
|
||||
result = op.(NamespaceDeclaration).getId() or
|
||||
result = op.(NamespaceDeclaration).getIdentifier() or
|
||||
result = op.(EnumDeclaration).getIdentifier() or
|
||||
result = op.(InterfaceDeclaration).getIdentifier() or
|
||||
result = op.(TypeAliasDeclaration).getIdentifier() or
|
||||
result = op.(ImportEqualsDeclaration).getId()
|
||||
result = op.(ImportEqualsDeclaration).getIdentifier()
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -77,8 +77,15 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
|||
result = getDocumentation().getATagByTitle("this").getType()
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getIdentifier()` instead.
|
||||
*
|
||||
* Gets the identifier specifying the name of this function, if any.
|
||||
*/
|
||||
deprecated VarDecl getId() { result = getIdentifier() }
|
||||
|
||||
/** Gets the identifier specifying the name of this function, if any. */
|
||||
VarDecl getId() { result = getChildExpr(-1) }
|
||||
VarDecl getIdentifier() { result = getChildExpr(-1) }
|
||||
|
||||
/**
|
||||
* Gets the name of this function if it has one, or a name inferred from its context.
|
||||
|
@ -89,9 +96,9 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
|||
* can be inferred, there is no result.
|
||||
*/
|
||||
string getName() {
|
||||
result = getId().getName()
|
||||
result = getIdentifier().getName()
|
||||
or
|
||||
not exists(getId()) and
|
||||
not exists(getIdentifier()) and
|
||||
(
|
||||
exists(VarDef vd | this = vd.getSource() | result = vd.getTarget().(VarRef).getName())
|
||||
or
|
||||
|
@ -111,7 +118,7 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
|||
}
|
||||
|
||||
/** Gets the variable holding this function. */
|
||||
Variable getVariable() { result = getId().getVariable() }
|
||||
Variable getVariable() { result = getIdentifier().getVariable() }
|
||||
|
||||
/** Gets the `arguments` variable of this function, if any. */
|
||||
ArgumentsVariable getArgumentsVariable() { result.getFunction() = this }
|
||||
|
@ -183,11 +190,11 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
|||
not exists(getAParameter()) and
|
||||
(
|
||||
// if the function has a name, the opening parenthesis comes right after it
|
||||
result = getId().getLastToken().getNextToken()
|
||||
result = getIdentifier().getLastToken().getNextToken()
|
||||
or
|
||||
// otherwise this must be an arrow function with no parameters, so the opening
|
||||
// parenthesis is the very first token of the function
|
||||
not exists(getId()) and result = getFirstToken()
|
||||
not exists(getIdentifier()) and result = getFirstToken()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -309,8 +316,8 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
|||
*/
|
||||
private string inferNameFromVarDef() {
|
||||
// in ambiguous cases like `var f = function g() {}`, prefer `g` to `f`
|
||||
if exists(getId())
|
||||
then result = "function " + getId().getName()
|
||||
if exists(getIdentifier())
|
||||
then result = "function " + getIdentifier().getName()
|
||||
else
|
||||
exists(VarDef vd | this = vd.getSource() |
|
||||
result = "function " + vd.getTarget().(VarRef).getName()
|
||||
|
|
|
@ -267,7 +267,7 @@ module AccessPath {
|
|||
or
|
||||
exists(FunctionDeclStmt fun |
|
||||
node = DataFlow::valueNode(fun) and
|
||||
result = fun.getId().(GlobalVarDecl).getName() and
|
||||
result = fun.getIdentifier().(GlobalVarDecl).getName() and
|
||||
root.isGlobal()
|
||||
)
|
||||
or
|
||||
|
@ -285,7 +285,7 @@ module AccessPath {
|
|||
or
|
||||
exists(NamespaceDeclaration decl |
|
||||
node = DataFlow::valueNode(decl) and
|
||||
result = decl.getId().(GlobalVarDecl).getName() and
|
||||
result = decl.getIdentifier().(GlobalVarDecl).getName() and
|
||||
root.isGlobal()
|
||||
)
|
||||
}
|
||||
|
|
|
@ -8,13 +8,16 @@ import javascript
|
|||
*/
|
||||
class NamespaceDefinition extends Stmt, @namespacedefinition, AST::ValueNode {
|
||||
/**
|
||||
* DEPRECATED: Use `getIdentifier()` instead.
|
||||
*
|
||||
* Gets the identifier naming the namespace.
|
||||
*/
|
||||
Identifier getId() {
|
||||
result = this.(NamespaceDeclaration).getId()
|
||||
or
|
||||
result = this.(EnumDeclaration).getIdentifier()
|
||||
}
|
||||
deprecated Identifier getId() { result = getIdentifier() }
|
||||
|
||||
/**
|
||||
* Gets the identifier naming the namespace.
|
||||
*/
|
||||
Identifier getIdentifier() { none() } // Overridden in subtypes.
|
||||
|
||||
/**
|
||||
* Gets unqualified name of the namespace being defined.
|
||||
|
@ -29,7 +32,7 @@ class NamespaceDefinition extends Stmt, @namespacedefinition, AST::ValueNode {
|
|||
* Gets the local namespace name induced by this namespace.
|
||||
*/
|
||||
LocalNamespaceName getLocalNamespaceName() {
|
||||
result = getId().(LocalNamespaceDecl).getLocalNamespaceName()
|
||||
result = getIdentifier().(LocalNamespaceDecl).getLocalNamespaceName()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,10 +58,10 @@ class NamespaceDefinition extends Stmt, @namespacedefinition, AST::ValueNode {
|
|||
*/
|
||||
class NamespaceDeclaration extends NamespaceDefinition, StmtContainer, @namespacedeclaration {
|
||||
/** Gets the name of this namespace. */
|
||||
override Identifier getId() { result = getChildExpr(-1) }
|
||||
override Identifier getIdentifier() { result = getChildExpr(-1) }
|
||||
|
||||
/** Gets the name of this namespace as a string. */
|
||||
override string getName() { result = getId().getName() }
|
||||
override string getName() { result = getIdentifier().getName() }
|
||||
|
||||
/** Gets the `i`th statement in this namespace. */
|
||||
Stmt getStmt(int i) {
|
||||
|
@ -83,7 +86,7 @@ class NamespaceDeclaration extends NamespaceDefinition, StmtContainer, @namespac
|
|||
predicate isInstantiated() { isInstantiated(this) }
|
||||
|
||||
override ControlFlowNode getFirstControlFlowNode() {
|
||||
if hasDeclareKeyword(this) then result = this else result = getId()
|
||||
if hasDeclareKeyword(this) then result = this else result = getIdentifier()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,13 +181,20 @@ class GlobalAugmentationDeclaration extends Stmt, StmtContainer, @globalaugmenta
|
|||
|
||||
/** A TypeScript "import-equals" declaration. */
|
||||
class ImportEqualsDeclaration extends Stmt, @importequalsdeclaration {
|
||||
/**
|
||||
* DEPRECATED: Use `getIdentifier()` instead.
|
||||
*
|
||||
* Gets the name under which the imported entity is imported.
|
||||
*/
|
||||
deprecated Identifier getId() { result = getIdentifier() }
|
||||
|
||||
/** Gets the name under which the imported entity is imported. */
|
||||
Identifier getId() { result = getChildExpr(0) }
|
||||
Identifier getIdentifier() { result = getChildExpr(0) }
|
||||
|
||||
/** Gets the expression specifying the imported module or entity. */
|
||||
Expr getImportedEntity() { result = getChildExpr(1) }
|
||||
|
||||
override ControlFlowNode getFirstControlFlowNode() { result = getId() }
|
||||
override ControlFlowNode getFirstControlFlowNode() { result = getIdentifier() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -348,7 +358,7 @@ class TypeDecl extends Identifier, TypeRef, LexicalDecl {
|
|||
this = any(ClassOrInterface ci).getIdentifier() or
|
||||
this = any(TypeParameter tp).getIdentifier() or
|
||||
this = any(ImportSpecifier im).getLocal() or
|
||||
this = any(ImportEqualsDeclaration im).getId() or
|
||||
this = any(ImportEqualsDeclaration im).getIdentifier() or
|
||||
this = any(TypeAliasDeclaration td).getIdentifier() or
|
||||
this = any(EnumDeclaration ed).getIdentifier() or
|
||||
this = any(EnumMember member).getIdentifier()
|
||||
|
@ -1226,8 +1236,8 @@ abstract class NamespaceRef extends ASTNode { }
|
|||
*/
|
||||
class LocalNamespaceDecl extends VarDecl, NamespaceRef {
|
||||
LocalNamespaceDecl() {
|
||||
any(NamespaceDeclaration nd).getId() = this or
|
||||
any(ImportEqualsDeclaration im).getId() = this or
|
||||
any(NamespaceDeclaration nd).getIdentifier() = this or
|
||||
any(ImportEqualsDeclaration im).getIdentifier() = this or
|
||||
any(ImportSpecifier im).getLocal() = this or
|
||||
any(EnumDeclaration ed).getIdentifier() = this
|
||||
}
|
||||
|
@ -1325,7 +1335,7 @@ class ImportVarTypeAccess extends VarTypeAccess, ImportTypeExpr, @importvartypea
|
|||
*/
|
||||
class EnumDeclaration extends NamespaceDefinition, @enumdeclaration, AST::ValueNode {
|
||||
/** Gets the name of this enum, such as `E` in `enum E { A, B }`. */
|
||||
Identifier getIdentifier() { result = getChildExpr(0) }
|
||||
override Identifier getIdentifier() { result = getChildExpr(0) }
|
||||
|
||||
/** Gets the name of this enum as a string. */
|
||||
override string getName() { result = getIdentifier().getName() }
|
||||
|
|
|
@ -312,8 +312,11 @@ class LocalVariable extends Variable {
|
|||
this = result.getScope().getAVariable()
|
||||
or
|
||||
exists(VarDecl d | d = getADeclaration() |
|
||||
if d = any(FunctionDeclStmt fds).getId()
|
||||
then exists(FunctionDeclStmt fds | d = fds.getId() | result = fds.getEnclosingContainer())
|
||||
if d = any(FunctionDeclStmt fds).getIdentifier()
|
||||
then
|
||||
exists(FunctionDeclStmt fds | d = fds.getIdentifier() |
|
||||
result = fds.getEnclosingContainer()
|
||||
)
|
||||
else result = d.getContainer()
|
||||
)
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ private class AnalyzedNamespaceDeclaration extends DataFlow::AnalyzedValueNode {
|
|||
|
||||
AbstractValue getPreviousValue() {
|
||||
exists(AnalyzedSsaDefinition def |
|
||||
def.getVariable().getAUse() = astNode.getId() and
|
||||
def.getVariable().getAUse() = astNode.getIdentifier() and
|
||||
result = def.getAnRhsValue()
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Provides classes for modelling cryptographic libraries.
|
||||
* Provides classes for modeling cryptographic libraries.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import javascript
|
||||
|
||||
query predicate test_getId(Function f, VarDecl res0, string res1) {
|
||||
res0 = f.getId() and res1 = f.getName()
|
||||
res0 = f.getIdentifier() and res1 = f.getName()
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ class ResolveCall extends CallExpr {
|
|||
string getDeclaredValue() {
|
||||
result = getVariable().getAnAssignedExpr().getStringValue()
|
||||
or
|
||||
exists(NamespaceDeclaration decl | decl.getId() = getVariable().getADeclaration() |
|
||||
exists(NamespaceDeclaration decl | decl.getIdentifier() = getVariable().getADeclaration() |
|
||||
result = getNamespaceName(decl)
|
||||
)
|
||||
}
|
||||
|
@ -21,7 +21,8 @@ string getNamespaceName(NamespaceDeclaration decl) {
|
|||
or
|
||||
not decl.getStmt(0).(ExprStmt).getExpr() instanceof ConstantString and
|
||||
result =
|
||||
"Namespace " + decl.getId() + " on line " + decl.getFirstToken().getLocation().getStartLine()
|
||||
"Namespace " + decl.getIdentifier() + " on line " +
|
||||
decl.getFirstToken().getLocation().getStartLine()
|
||||
}
|
||||
|
||||
from ResolveCall resolve
|
||||
|
|
|
@ -20,3 +20,6 @@
|
|||
| tst-IncompleteUrlSubstringSanitization.js:63:4:63:33 | x.index ... !== -1 | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:63:14:63:25 | "secure.com" | secure.com |
|
||||
| tst-IncompleteUrlSubstringSanitization.js:64:3:64:26 | x.inclu ... e.com") | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:64:14:64:25 | "secure.com" | secure.com |
|
||||
| tst-IncompleteUrlSubstringSanitization.js:66:6:66:29 | x.inclu ... e.com") | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:66:17:66:28 | "secure.com" | secure.com |
|
||||
| tst-IncompleteUrlSubstringSanitization.js:73:5:73:48 | x.index ... ") >= 0 | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:73:15:73:42 | "https: ... oo/bar" | https://secure.com/foo/bar |
|
||||
| tst-IncompleteUrlSubstringSanitization.js:74:5:74:40 | x.index ... ") >= 0 | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:74:15:74:34 | "https://secure.com" | https://secure.com |
|
||||
| tst-IncompleteUrlSubstringSanitization.js:75:5:75:52 | x.index ... ") >= 0 | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:75:15:75:46 | "https: ... ar-baz" | https://secure.com/foo/bar-baz |
|
||||
|
|
|
@ -67,5 +67,10 @@
|
|||
|
||||
} else {
|
||||
doSomeThingWithTrustedURL(x);
|
||||
}
|
||||
}
|
||||
|
||||
x.startsWith("https://secure.com/foo/bar"); // OK - a forward slash after the domain makes prefix checks safe.
|
||||
x.indexOf("https://secure.com/foo/bar") >= 0 // NOT OK - the url can be anywhere in the string.
|
||||
x.indexOf("https://secure.com") >= 0 // NOT OK
|
||||
x.indexOf("https://secure.com/foo/bar-baz") >= 0 // NOT OK - the url can be anywhere in the string.
|
||||
});
|
||||
|
|
|
@ -26,7 +26,7 @@ predicate all_defined(ModuleValue exporter) {
|
|||
}
|
||||
|
||||
from ImportStar imp, ModuleValue exporter
|
||||
where import_star(imp, exporter) and not all_defined(exporter)
|
||||
where import_star(imp, exporter) and not all_defined(exporter) and not exporter.isAbsent()
|
||||
select imp,
|
||||
"Import pollutes the enclosing namespace, as the imported module $@ does not define '__all__'.",
|
||||
exporter, exporter.getName()
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import callGraphConfig
|
||||
import experimental.dataflow.callGraphConfig
|
||||
|
||||
from DataFlow::Node sink
|
||||
where exists(CallGraphConfig cfg | cfg.isSink(sink))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import callGraphConfig
|
||||
import experimental.dataflow.callGraphConfig
|
||||
|
||||
from DataFlow::Node source
|
||||
where exists(CallGraphConfig cfg | cfg.isSource(source))
|
||||
|
|
|
@ -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. |
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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() |
|
|
@ -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.
|
|
@ -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> |
|
||||
|
|
|
@ -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 method’s __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 iterator’s 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 iterator’s 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 function’s documentation string, or None if unavailable; __name__ is the function’s 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)
|
|
@ -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 |
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
|
@ -1,2 +1,3 @@
|
|||
| imports_test.py:21:1:21:20 | from module import * | Using 'from ... import *' pollutes the namespace |
|
||||
| imports_test.py:22:1:22:32 | from module_without_all import * | Using 'from ... import *' pollutes the namespace |
|
||||
| imports_test.py:65:1:65:40 | from module_that_does_not_exist import * | Using 'from ... import *' pollutes the namespace |
|
||||
|
|
|
@ -61,3 +61,5 @@ import module1 as different
|
|||
#Use it
|
||||
different
|
||||
|
||||
# FP reported in https://github.com/github/codeql/issues/4003
|
||||
from module_that_does_not_exist import *
|
||||
|
|
Загрузка…
Ссылка в новой задаче