This commit is contained in:
Erik Krogh Kristensen 2020-08-28 10:27:49 +02:00
Родитель eb84f97e7f afe234dade
Коммит 038cca814a
168 изменённых файлов: 5387 добавлений и 1294 удалений

Просмотреть файл

@ -27,6 +27,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. |
| Ambiguous HTML id attribute (`js/duplicate-html-id`) | Results no longer shown | Precision tag reduced to "low". The query is no longer run by default. |
## Changes to libraries

Просмотреть файл

@ -0,0 +1,22 @@
# Improvements to Python analysis
The following changes in version 1.26 affect Python analysis in all applications.
## General improvements
## New queries
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|----------------------------|------------------------|------------------------------------------------------------------|
## Changes to libraries
* Added taint tracking support for string formatting through f-strings.

Просмотреть файл

@ -325,6 +325,10 @@
"csharp/ql/src/experimental/ir/implementation/raw/gvn/internal/ValueNumberingImports.qll",
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingImports.qll"
],
"Inline Test Expectations": [
"cpp/ql/test/TestUtilities/InlineExpectationsTest.qll",
"python/ql/test/TestUtilities/InlineExpectationsTest.qll"
],
"XML": [
"cpp/ql/src/semmle/code/cpp/XML.qll",
"csharp/ql/src/semmle/code/csharp/XML.qll",

Просмотреть файл

@ -0,0 +1,11 @@
void test(char *arg1, int *arg2) {
if (arg1[0] == 'A') {
if (arg2 != NULL) { //maybe redundant
*arg2 = 42;
}
}
if (arg1[1] == 'B')
{
*arg2 = 54; //dereferenced without checking first
}
}

Просмотреть файл

@ -0,0 +1,29 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>This rule finds comparisons of a function parameter to null that occur when in another path the parameter is dereferenced without a guard check. It's
likely either the check is not required and can be removed, or it should be added before the dereference
so that a null pointer dereference does not occur.</p>
</overview>
<recommendation>
<p>A check should be added to before the dereference, in a way that prevents a null pointer value from
being dereferenced. If it's clear that the pointer cannot be null, consider removing the check instead.</p>
</recommendation>
<example>
<sample src="RedundantNullCheckParam.cpp" />
</example>
<references>
<li>
<a href="https://www.owasp.org/index.php/Null_Dereference">
Null Dereference
</a>
</li>
</references>
</qhelp>

Просмотреть файл

@ -0,0 +1,56 @@
/**
* @name Redundant null check or missing null check of parameter
* @description Checking a parameter for nullness in one path,
* and not in another is likely to be a sign that either
* the check can be removed, or added in the other case.
* @kind problem
* @id cpp/redundant-null-check-param
* @problem.severity recommendation
* @tags reliability
* security
* external/cwe/cwe-476
*/
import cpp
predicate blockDominates(Block check, Block access) {
check.getLocation().getStartLine() <= access.getLocation().getStartLine() and
check.getLocation().getEndLine() >= access.getLocation().getEndLine()
}
predicate isCheckedInstruction(VariableAccess unchecked, VariableAccess checked) {
checked = any(VariableAccess va | va.getTarget() = unchecked.getTarget()) and
//Simple test if the first access in this code path is dereferenced
not dereferenced(checked) and
blockDominates(checked.getEnclosingBlock(), unchecked.getEnclosingBlock())
}
predicate candidateResultUnchecked(VariableAccess unchecked) {
not isCheckedInstruction(unchecked, _)
}
predicate candidateResultChecked(VariableAccess check, EqualityOperation eqop) {
//not dereferenced to check against pointer, not its pointed value
not dereferenced(check) and
//assert macros are not taken into account
not check.isInMacroExpansion() and
// is part of a comparison against some constant NULL
eqop.getAnOperand() = check and
eqop.getAnOperand() instanceof NullValue
}
from VariableAccess unchecked, VariableAccess check, EqualityOperation eqop, Parameter param
where
// a dereference
dereferenced(unchecked) and
// for a function parameter
unchecked.getTarget() = param and
// this function parameter is not overwritten
count(param.getAnAssignment()) = 0 and
check.getTarget() = param and
// which is once checked
candidateResultChecked(check, eqop) and
// and which has not been checked before in this code path
candidateResultUnchecked(unchecked)
select check, "This null check is redundant or there is a missing null check before $@ ", unchecked,
"where dereferencing happens"

Просмотреть файл

@ -484,6 +484,17 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
// Expr -> Expr
exprToExprStep_nocfg(nodeFrom.asExpr(), nodeTo.asExpr())
or
// Assignment -> LValue post-update node
//
// This is used for assignments whose left-hand side is not a variable
// assignment or a storeStep but is still modeled by other means. It could be
// a call to `operator*` or `operator[]` where taint should flow to the
// post-update node of the qualifier.
exists(AssignExpr assign |
nodeFrom.asExpr() = assign and
nodeTo.(PostUpdateNode).getPreUpdateNode().asExpr() = assign.getLValue()
)
or
// Node -> FlowVar -> VariableAccess
exists(FlowVar var |
(

Просмотреть файл

@ -82,6 +82,19 @@ predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeT
exprToDefinitionByReferenceStep(nodeFrom.asExpr(), nodeTo.asDefiningArgument())
or
exprToPartialDefinitionStep(nodeFrom.asExpr(), nodeTo.asPartialDefinition())
or
// Reverse taint: taint that flows from the post-update node of a reference
// returned by a function call, back into the qualifier of that function.
// This allows taint to flow 'in' through references returned by a modeled
// function such as `operator[]`.
exists(TaintFunction f, Call call, FunctionInput inModel, FunctionOutput outModel |
call.getTarget() = f and
inModel.isReturnValueDeref() and
outModel.isQualifierObject() and
f.hasTaintFlow(inModel, outModel) and
nodeFrom.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() = call and
nodeTo.asDefiningArgument() = call.getQualifier()
)
}
/**

Просмотреть файл

@ -14,10 +14,7 @@ import semmle.code.cpp.models.interfaces.Taint
*/
class StdSequenceContainerConstructor extends Constructor, TaintFunction {
StdSequenceContainerConstructor() {
this.getDeclaringType().hasQualifiedName("std", "vector") or
this.getDeclaringType().hasQualifiedName("std", "deque") or
this.getDeclaringType().hasQualifiedName("std", "list") or
this.getDeclaringType().hasQualifiedName("std", "forward_list")
this.getDeclaringType().hasQualifiedName("std", ["vector", "deque", "list", "forward_list"])
}
/**
@ -26,7 +23,7 @@ class StdSequenceContainerConstructor extends Constructor, TaintFunction {
*/
int getAValueTypeParameterIndex() {
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
getDeclaringType().getTemplateArgument(0) // i.e. the `T` of this `std::vector<T>`
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>`
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@ -36,16 +33,32 @@ class StdSequenceContainerConstructor extends Constructor, TaintFunction {
}
}
/**
* The standard container function `data`.
*/
class StdSequenceContainerData extends TaintFunction {
StdSequenceContainerData() { this.hasQualifiedName("std", ["array", "vector"], "data") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from container itself (qualifier) to return value
input.isQualifierObject() and
output.isReturnValueDeref()
or
// reverse flow from returned reference to the qualifier (for writes to
// `data`)
input.isReturnValueDeref() and
output.isQualifierObject()
}
}
/**
* The standard container functions `push_back` and `push_front`.
*/
class StdSequenceContainerPush extends TaintFunction {
StdSequenceContainerPush() {
this.hasQualifiedName("std", "vector", "push_back") or
this.hasQualifiedName("std", "deque", "push_back") or
this.hasQualifiedName("std", "deque", "push_front") or
this.hasQualifiedName("std", "list", "push_back") or
this.hasQualifiedName("std", "list", "push_front") or
this.hasQualifiedName("std", "deque", ["push_back", "push_front"]) or
this.hasQualifiedName("std", "list", ["push_back", "push_front"]) or
this.hasQualifiedName("std", "forward_list", "push_front")
}
@ -61,14 +74,10 @@ class StdSequenceContainerPush extends TaintFunction {
*/
class StdSequenceContainerFrontBack extends TaintFunction {
StdSequenceContainerFrontBack() {
this.hasQualifiedName("std", "array", "front") or
this.hasQualifiedName("std", "array", "back") or
this.hasQualifiedName("std", "vector", "front") or
this.hasQualifiedName("std", "vector", "back") or
this.hasQualifiedName("std", "deque", "front") or
this.hasQualifiedName("std", "deque", "back") or
this.hasQualifiedName("std", "list", "front") or
this.hasQualifiedName("std", "list", "back") or
this.hasQualifiedName("std", "array", ["front", "back"]) or
this.hasQualifiedName("std", "vector", ["front", "back"]) or
this.hasQualifiedName("std", "deque", ["front", "back"]) or
this.hasQualifiedName("std", "list", ["front", "back"]) or
this.hasQualifiedName("std", "forward_list", "front")
}
@ -79,16 +88,36 @@ class StdSequenceContainerFrontBack extends TaintFunction {
}
}
/**
* The standard container function `assign`.
*/
class StdSequenceContainerAssign extends TaintFunction {
StdSequenceContainerAssign() {
this.hasQualifiedName("std", ["vector", "deque", "list", "forward_list"], "assign")
}
/**
* Gets the index of a parameter to this function that is a reference to the
* value type of the container.
*/
int getAValueTypeParameterIndex() {
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>`
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from parameter to string itself (qualifier) and return value
input.isParameterDeref(getAValueTypeParameterIndex()) and
output.isQualifierObject()
}
}
/**
* The standard container `swap` functions.
*/
class StdSequenceContainerSwap extends TaintFunction {
StdSequenceContainerSwap() {
this.hasQualifiedName("std", "array", "swap") or
this.hasQualifiedName("std", "vector", "swap") or
this.hasQualifiedName("std", "deque", "swap") or
this.hasQualifiedName("std", "list", "swap") or
this.hasQualifiedName("std", "forward_list", "swap")
this.hasQualifiedName("std", ["array", "vector", "deque", "list", "forward_list"], "swap")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@ -100,3 +129,22 @@ class StdSequenceContainerSwap extends TaintFunction {
output.isQualifierObject()
}
}
/**
* The standard container functions `at` and `operator[]`.
*/
class StdSequenceContainerAt extends TaintFunction {
StdSequenceContainerAt() {
this.hasQualifiedName("std", ["vector", "array", "deque"], ["at", "operator[]"])
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to referenced return value
input.isQualifierObject() and
output.isReturnValueDeref()
or
// reverse flow from returned reference to the qualifier
input.isReturnValueDeref() and
output.isQualifierObject()
}
}

Просмотреть файл

@ -8,18 +8,33 @@ class StdBasicString extends TemplateClass {
}
/**
* The `std::string` functions `c_str` and `data`.
* The `std::string` function `c_str`.
*/
class StdStringCStr extends TaintFunction {
StdStringCStr() {
this.hasQualifiedName("std", "basic_string", "c_str") or
this.hasQualifiedName("std", "basic_string", "data")
}
StdStringCStr() { this.hasQualifiedName("std", "basic_string", "c_str") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from string itself (qualifier) to return value
input.isQualifierObject() and
output.isReturnValue()
output.isReturnValueDeref()
}
}
/**
* The `std::string` function `data`.
*/
class StdStringData extends TaintFunction {
StdStringData() { this.hasQualifiedName("std", "basic_string", "data") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from string itself (qualifier) to return value
input.isQualifierObject() and
output.isReturnValueDeref()
or
// reverse flow from returned reference to the qualifier (for writes to
// `data`)
input.isReturnValueDeref() and
output.isQualifierObject()
}
}
@ -49,27 +64,25 @@ class StdStringPlus extends TaintFunction {
*/
class StdStringAppend extends TaintFunction {
StdStringAppend() {
this.hasQualifiedName("std", "basic_string", "operator+=") or
this.hasQualifiedName("std", "basic_string", "append") or
this.hasQualifiedName("std", "basic_string", "insert") or
this.hasQualifiedName("std", "basic_string", "replace")
this.hasQualifiedName("std", "basic_string", ["operator+=", "append", "insert", "replace"])
}
/**
* Gets the index of a parameter to this function that is a string (or
* character).
*/
int getAStringParameter() {
int getAStringParameterIndex() {
getParameter(result).getType() instanceof PointerType or
getParameter(result).getType() instanceof ReferenceType or
getParameter(result).getType() = getDeclaringType().getTemplateArgument(0) // i.e. `std::basic_string::CharT`
getParameter(result).getUnspecifiedType() =
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from string and parameter to string (qualifier) and return value
(
input.isQualifierObject() or
input.isParameterDeref(getAStringParameter())
input.isParameterDeref(getAStringParameterIndex())
) and
(
output.isQualifierObject() or
@ -88,15 +101,16 @@ class StdStringAssign extends TaintFunction {
* Gets the index of a parameter to this function that is a string (or
* character).
*/
int getAStringParameter() {
int getAStringParameterIndex() {
getParameter(result).getType() instanceof PointerType or
getParameter(result).getType() instanceof ReferenceType or
getParameter(result).getType() = getDeclaringType().getTemplateArgument(0) // i.e. `std::basic_string::CharT`
getParameter(result).getUnspecifiedType() =
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // 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
input.isParameterDeref(getAStringParameterIndex()) and
(
output.isQualifierObject() or
output.isReturnValueDeref()
@ -145,3 +159,20 @@ class StdStringSwap extends TaintFunction {
output.isQualifierObject()
}
}
/**
* The `std::string` functions `at` and `operator[]`.
*/
class StdStringAt extends TaintFunction {
StdStringAt() { this.hasQualifiedName("std", "basic_string", ["at", "operator[]"]) }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to referenced return value
input.isQualifierObject() and
output.isReturnValueDeref()
or
// reverse flow from returned reference to the qualifier
input.isReturnValueDeref() and
output.isQualifierObject()
}
}

Просмотреть файл

@ -10,7 +10,8 @@ private newtype TFunctionInput =
TInParameter(ParameterIndex i) or
TInParameterDeref(ParameterIndex i) or
TInQualifierObject() or
TInQualifierAddress()
TInQualifierAddress() or
TInReturnValueDeref()
/**
* An input to a function. This can be:
@ -106,6 +107,31 @@ class FunctionInput extends TFunctionInput {
* (with type `C const *`) on entry to the function.
*/
predicate isQualifierAddress() { none() }
/**
* Holds if this is the input value pointed to by the return value of a
* function, if the function returns a pointer, or the input value referred
* to by the return value of a function, if the function returns a reference.
*
* Example:
* ```
* char* getPointer();
* float& getReference();
* int getInt();
* ```
* - `isReturnValueDeref()` holds for the `FunctionInput` that represents the
* value of `*getPointer()` (with type `char`).
* - `isReturnValueDeref()` holds for the `FunctionInput` that represents the
* value of `getReference()` (with type `float`).
* - There is no `FunctionInput` of `getInt()` for which
* `isReturnValueDeref()` holds because the return type of `getInt()` is
* neither a pointer nor a reference.
*
* Note that data flows in through function return values are relatively
* rare, but they do occur when a function returns a reference to itself,
* part of itself, or one of its other inputs.
*/
predicate isReturnValueDeref() { none() }
}
/**
@ -199,6 +225,34 @@ class InQualifierAddress extends FunctionInput, TInQualifierAddress {
override predicate isQualifierAddress() { any() }
}
/**
* The input value pointed to by the return value of a function, if the
* function returns a pointer, or the input value referred to by the return
* value of a function, if the function returns a reference.
*
* Example:
* ```
* char* getPointer();
* float& getReference();
* int getInt();
* ```
* - `InReturnValueDeref` represents the value of `*getPointer()` (with type
* `char`).
* - `InReturnValueDeref` represents the value of `getReference()` (with type
* `float`).
* - `InReturnValueDeref` does not represent the return value of `getInt()`
* because the return type of `getInt()` is neither a pointer nor a reference.
*
* Note that data flows in through function return values are relatively
* rare, but they do occur when a function returns a reference to itself,
* part of itself, or one of its other inputs.
*/
class InReturnValueDeref extends FunctionInput, TInReturnValueDeref {
override string toString() { result = "InReturnValueDeref" }
override predicate isReturnValueDeref() { any() }
}
private newtype TFunctionOutput =
TOutParameterDeref(ParameterIndex i) or
TOutQualifierObject() or

Просмотреть файл

@ -2,6 +2,11 @@
* Provides a library for writing QL tests whose success or failure is based on expected results
* embedded in the test source code as comments, rather than a `.expected` file.
*
* To add this framework to a new language:
* - Add a file `InlineExpectationsTestPrivate.qll` that defines a `LineComment` class. This class
* must support a `getContents` method that returns the contents of the given comment, _excluding_
* the comment indicator itself. It should also define `toString` and `getLocation` as usual.
*
* To create a new inline expectations test:
* - Declare a class that extends `InlineExpectationsTest`. In the characteristic predicate of the
* new class, bind `this` to a unique string (usually the name of the test).
@ -13,7 +18,7 @@
* `hasActualResult()`. Often this is just a single tag.
*
* Example:
* ```
* ```ql
* class ConstantValueTest extends InlineExpectationsTest {
* ConstantValueTest() { this = "ConstantValueTest" }
*
@ -23,11 +28,11 @@
* }
*
* override predicate hasActualResult(
* Location location, string element, string tag, string valuesasas
* Location location, string element, string tag, string value
* ) {
* exists(Expr e |
* tag = "const" and // The tag for this test.
* valuesasas = e.getValue() and // The expected value. Will only hold for constant expressions.
* value = e.getValue() and // The expected value. Will only hold for constant expressions.
* location = e.getLocation() and // The location of the result to be reported.
* element = e.toString() // The display text for the result.
* )
@ -38,10 +43,10 @@
* There is no need to write a `select` clause or query predicate. All of the differences between
* expected results and actual results will be reported in the `failures()` query predicate.
*
* To annotate the test source code with an expected result, place a C++-style (`//`) comment on the
* To annotate the test source code with an expected result, place a comment on the
* same line as the expected result, with text of the following format as the body of the comment:
*
* `// $tag=expected-value`
* `$tag=expected-value`
*
* Where `tag` is the value of the `tag` parameter from `hasActualResult()`, and `expected-value` is
* the value of the `value` parameter from `hasActualResult()`. The `=expected-value` portion may be
@ -53,7 +58,7 @@
* "Missing result: tag=expected-value".
*
* Example:
* ```
* ```cpp
* int i = x + 5; // $const=5
* int j = y + (7 - 3) // $const=7 $const=3 $const=4 // The result of the subtraction is a constant.
* ```
@ -62,8 +67,8 @@
* annotate that a particular expected result is known to be a false positive, or that a particular
* missing result is known to be a false negative:
*
* `// $f+:tag=expected-value` // False positive
* `// $f-:tag=expected-value` // False negative
* `$f+:tag=expected-value` // False positive
* `$f-:tag=expected-value` // False negative
*
* A false positive expectation is treated as any other expected result, except that if there is no
* matching actual result, the message will be of the form "Fixed false positive: tag=value". A
@ -74,14 +79,14 @@
* If the same result value is expected for two or more tags on the same line, there is a shorthand
* notation available:
*
* `// $tag1,tag2=expected-value`
* `$tag1,tag2=expected-value`
*
* is equivalent to:
*
* `// $tag1=expected-value $tag2=expected-value`
* `$tag1=expected-value $tag2=expected-value`
*/
import cpp
private import InlineExpectationsTestPrivate
/**
* Base class for tests with inline expectations. The test extends this class to provide the actual
@ -150,12 +155,12 @@ abstract class InlineExpectationsTest extends string {
}
/**
* RegEx pattern to match a comment containing one or more expected results. The comment must be a
* C++-style (`//`) comment with `$` as its first non-whitespace character. Any subsequent character
* RegEx pattern to match a comment containing one or more expected results. The comment must have
* `$` as its first non-whitespace character. Any subsequent character
* is treated as part of the expected results, except that the comment may contain a `//` sequence
* to treat the remainder of the line as a regular (non-interpreted) comment.
*/
private string expectationCommentPattern() { result = "//\\s*(\\$(?:[^/]|/[^/])*)(?://.*)?" }
private string expectationCommentPattern() { result = "\\s*(\\$(?:[^/]|/[^/])*)(?://.*)?" }
/**
* RegEx pattern to match a single expected result, not including the leading `$`. It starts with an
@ -166,7 +171,7 @@ private string expectationPattern() {
result = "(?:(f(?:\\+|-)):)?((?:[A-Za-z-_]+)(?:\\s*,\\s*[A-Za-z-_]+)*)(?:=(.*))?"
}
private string getAnExpectation(CppStyleComment comment) {
private string getAnExpectation(LineComment comment) {
result = comment.getContents().regexpCapture(expectationCommentPattern(), 1).splitAt("$").trim() and
result != ""
}
@ -177,7 +182,7 @@ private newtype TFailureLocatable =
) {
test.hasActualResult(location, element, tag, value)
} or
TValidExpectation(CppStyleComment comment, string tag, string value, string knownFailure) {
TValidExpectation(LineComment comment, string tag, string value, string knownFailure) {
exists(string expectation |
expectation = getAnExpectation(comment) and
expectation.regexpMatch(expectationPattern()) and
@ -194,7 +199,7 @@ private newtype TFailureLocatable =
)
)
} or
TInvalidExpectation(CppStyleComment comment, string expectation) {
TInvalidExpectation(LineComment comment, string expectation) {
expectation = getAnExpectation(comment) and
not expectation.regexpMatch(expectationPattern())
}
@ -232,7 +237,7 @@ class ActualResult extends FailureLocatable, TActualResult {
}
abstract private class Expectation extends FailureLocatable {
CppStyleComment comment;
LineComment comment;
override string toString() { result = comment.toString() }

Просмотреть файл

@ -0,0 +1,23 @@
import cpp
private newtype TLineComment = MkLineComment(CppStyleComment c)
/**
* Represents a line comment in the CPP style.
* Unlike the `CppStyleComment` class, however, the string returned by `getContents` does _not_
* include the preceding comment marker (`//`).
*/
class LineComment extends TLineComment {
CppStyleComment comment;
LineComment() { this = MkLineComment(comment) }
/** Returns the contents of the given comment, _without_ the preceding comment marker (`//`). */
string getContents() { result = comment.getContents().suffix(2) }
/** Gets a textual representation of this element. */
string toString() { result = comment.toString() }
/** Gets the location of this comment. */
Location getLocation() { result = comment.getLocation() }
}

Просмотреть файл

@ -7,11 +7,14 @@
| example.c:17:19:17:22 | {...} | example.c:26:19:26:24 | coords |
| example.c:24:2:24:7 | coords [post update] | example.c:26:2:26:7 | coords |
| example.c:24:2:24:7 | coords [post update] | example.c:26:19:26:24 | coords |
| example.c:24:2:24:30 | ... = ... | example.c:24:9:24:9 | x [post update] |
| example.c:24:13:24:18 | coords [post update] | example.c:24:2:24:7 | coords |
| example.c:24:13:24:18 | coords [post update] | example.c:26:2:26:7 | coords |
| example.c:24:13:24:18 | coords [post update] | example.c:26:19:26:24 | coords |
| example.c:24:13:24:30 | ... = ... | example.c:24:2:24:30 | ... = ... |
| example.c:24:13:24:30 | ... = ... | example.c:24:20:24:20 | y [post update] |
| example.c:24:24:24:30 | ... + ... | example.c:24:13:24:30 | ... = ... |
| example.c:26:2:26:25 | ... = ... | example.c:26:9:26:9 | x [post update] |
| example.c:26:13:26:16 | call to getX | example.c:26:2:26:25 | ... = ... |
| example.c:26:18:26:24 | ref arg & ... | example.c:26:2:26:7 | coords |
| example.c:26:18:26:24 | ref arg & ... | example.c:26:19:26:24 | coords [inner post update] |

Просмотреть файл

@ -0,0 +1,147 @@
int source();
void sink(int);
void sink(class MyInt);
void sink(class MyArray);
void test_pointer_deref_assignment()
{
int x = 0;
int *p_x = &x;
int *p2_x = &x;
int &r_x = x;
*p_x = source();
sink(x); // tainted [DETECTED BY IR ONLY]
sink(*p_x); // tainted [DETECTED BY IR ONLY]
sink(*p2_x); // tainted [DETECTED BY IR ONLY]
sink(r_x); // tainted [DETECTED BY IR ONLY]
}
void test_reference_deref_assignment()
{
int x = 0;
int *p_x = &x;
int &r_x = x;
int &r2_x = x;
r_x = source();
sink(x); // tainted [DETECTED BY IR ONLY]
sink(*p_x); // tainted [DETECTED BY IR ONLY]
sink(r_x); // tainted
sink(r2_x); // tainted [DETECTED BY IR ONLY]
}
class MyInt
{
public:
MyInt() : i(0) {}
int &get() { return i; }
MyInt &operator=(const int &other);
MyInt &operator=(const MyInt &other);
int i;
};
void test_myint_member_assignment()
{
MyInt mi;
mi.i = source();
sink(mi); // tainted [DETECTED BY IR ONLY]
sink(mi.get()); // tainted
}
void test_myint_method_assignment()
{
MyInt mi;
mi.get() = source();
sink(mi); // tainted [DETECTED BY IR ONLY]
sink(mi.get()); // tainted
}
void test_myint_overloaded_assignment()
{
MyInt mi, mi2;
mi = source();
mi2 = mi;
sink(mi); // tainted [NOT DETECTED]
sink(mi.get()); // tainted [NOT DETECTED]
sink(mi2); // tainted [NOT DETECTED]
sink(mi2.get()); // tainted [NOT DETECTED]
}
class MyArray
{
public:
MyArray() : values({0}) {}
int &get(int i) { return values[i]; }
int &operator[](int i);
int values[10];
};
void test_myarray_member_assignment()
{
MyArray ma;
ma.values[0] = source();
sink(ma.values[0]); // tainted
}
void test_myarray_method_assignment()
{
MyArray ma;
ma.get(0) = source();
sink(ma.get(0)); // tainted [NOT DETECTED]
}
void test_myarray_overloaded_assignment()
{
MyArray ma, ma2;
ma[0] = source();
ma2 = ma;
sink(ma[0]); // tainted [NOT DETECTED]
sink(ma2[0]); // tainted [NOT DETECTED]
}
void sink(int *);
void test_array_reference_assignment()
{
int arr1[10] = {0};
int arr2[10] = {0};
int arr3[10] = {0};
int &ref1 = arr1[5];
int *ptr2, *ptr3;
ref1 = source();
sink(ref1); // tainted
sink(arr1[5]); // tainted [DETECTED BY IR ONLY]
ptr2 = &(arr2[5]);
*ptr2 = source();
sink(*ptr2); // tainted [DETECTED BY IR ONLY]
sink(arr2[5]); // tainted [DETECTED BY IR ONLY]
ptr3 = arr3;
ptr3[5] = source();
sink(ptr3[5]); // tainted [DETECTED BY IR ONLY]
sink(arr3[5]); // tainted [DETECTED BY IR ONLY]
}

Просмотреть файл

@ -1,3 +1,127 @@
| arrayassignment.cpp:9:9:9:10 | 0 | arrayassignment.cpp:10:14:10:14 | x | |
| arrayassignment.cpp:9:9:9:10 | 0 | arrayassignment.cpp:11:15:11:15 | x | |
| arrayassignment.cpp:9:9:9:10 | 0 | arrayassignment.cpp:12:13:12:13 | x | |
| arrayassignment.cpp:9:9:9:10 | 0 | arrayassignment.cpp:16:7:16:7 | x | |
| arrayassignment.cpp:10:13:10:14 | & ... | arrayassignment.cpp:14:3:14:5 | p_x | |
| arrayassignment.cpp:10:13:10:14 | & ... | arrayassignment.cpp:17:8:17:10 | p_x | |
| arrayassignment.cpp:10:14:10:14 | x | arrayassignment.cpp:10:13:10:14 | & ... | |
| arrayassignment.cpp:11:14:11:15 | & ... | arrayassignment.cpp:18:8:18:11 | p2_x | |
| arrayassignment.cpp:11:15:11:15 | x | arrayassignment.cpp:11:14:11:15 | & ... | |
| arrayassignment.cpp:12:13:12:13 | x | arrayassignment.cpp:19:7:19:9 | r_x | |
| arrayassignment.cpp:14:3:14:5 | p_x | arrayassignment.cpp:14:2:14:5 | * ... | TAINT |
| arrayassignment.cpp:14:9:14:14 | call to source | arrayassignment.cpp:14:2:14:16 | ... = ... | |
| arrayassignment.cpp:17:8:17:10 | p_x | arrayassignment.cpp:17:7:17:10 | * ... | TAINT |
| arrayassignment.cpp:18:8:18:11 | p2_x | arrayassignment.cpp:18:7:18:11 | * ... | TAINT |
| arrayassignment.cpp:24:9:24:10 | 0 | arrayassignment.cpp:25:14:25:14 | x | |
| arrayassignment.cpp:24:9:24:10 | 0 | arrayassignment.cpp:26:13:26:13 | x | |
| arrayassignment.cpp:24:9:24:10 | 0 | arrayassignment.cpp:27:14:27:14 | x | |
| arrayassignment.cpp:24:9:24:10 | 0 | arrayassignment.cpp:31:7:31:7 | x | |
| arrayassignment.cpp:25:13:25:14 | & ... | arrayassignment.cpp:32:8:32:10 | p_x | |
| arrayassignment.cpp:25:14:25:14 | x | arrayassignment.cpp:25:13:25:14 | & ... | |
| arrayassignment.cpp:27:14:27:14 | x | arrayassignment.cpp:34:7:34:10 | r2_x | |
| arrayassignment.cpp:29:8:29:13 | call to source | arrayassignment.cpp:29:2:29:15 | ... = ... | |
| arrayassignment.cpp:29:8:29:13 | call to source | arrayassignment.cpp:33:7:33:9 | r_x | |
| arrayassignment.cpp:32:8:32:10 | p_x | arrayassignment.cpp:32:7:32:10 | * ... | TAINT |
| arrayassignment.cpp:37:7:37:7 | Unknown literal | arrayassignment.cpp:37:7:37:7 | constructor init of field i | TAINT |
| arrayassignment.cpp:37:7:37:7 | this | arrayassignment.cpp:37:7:37:7 | constructor init of field i [pre-this] | |
| arrayassignment.cpp:40:2:40:6 | this | arrayassignment.cpp:40:12:40:15 | constructor init of field i [pre-this] | |
| arrayassignment.cpp:40:12:40:15 | 0 | arrayassignment.cpp:40:12:40:15 | constructor init of field i | TAINT |
| arrayassignment.cpp:42:7:42:9 | this | arrayassignment.cpp:42:22:42:22 | this | |
| arrayassignment.cpp:52:8:52:9 | call to MyInt | arrayassignment.cpp:54:2:54:3 | mi | |
| arrayassignment.cpp:52:8:52:9 | call to MyInt | arrayassignment.cpp:56:7:56:8 | mi | |
| arrayassignment.cpp:52:8:52:9 | call to MyInt | arrayassignment.cpp:57:7:57:8 | mi | |
| arrayassignment.cpp:54:2:54:3 | mi [post update] | arrayassignment.cpp:56:7:56:8 | mi | |
| arrayassignment.cpp:54:2:54:3 | mi [post update] | arrayassignment.cpp:57:7:57:8 | mi | |
| arrayassignment.cpp:54:2:54:16 | ... = ... | arrayassignment.cpp:54:5:54:5 | i [post update] | |
| arrayassignment.cpp:54:9:54:14 | call to source | arrayassignment.cpp:54:2:54:16 | ... = ... | |
| arrayassignment.cpp:62:8:62:9 | call to MyInt | arrayassignment.cpp:64:2:64:3 | mi | |
| arrayassignment.cpp:62:8:62:9 | call to MyInt | arrayassignment.cpp:66:7:66:8 | mi | |
| arrayassignment.cpp:62:8:62:9 | call to MyInt | arrayassignment.cpp:67:7:67:8 | mi | |
| arrayassignment.cpp:64:2:64:3 | ref arg mi | arrayassignment.cpp:66:7:66:8 | mi | |
| arrayassignment.cpp:64:2:64:3 | ref arg mi | arrayassignment.cpp:67:7:67:8 | mi | |
| arrayassignment.cpp:64:2:64:20 | ... = ... | arrayassignment.cpp:64:5:64:7 | call to get [post update] | |
| arrayassignment.cpp:64:13:64:18 | call to source | arrayassignment.cpp:64:2:64:20 | ... = ... | |
| arrayassignment.cpp:72:8:72:9 | call to MyInt | arrayassignment.cpp:74:2:74:3 | mi | |
| arrayassignment.cpp:72:8:72:9 | call to MyInt | arrayassignment.cpp:75:8:75:9 | mi | |
| arrayassignment.cpp:72:8:72:9 | call to MyInt | arrayassignment.cpp:77:7:77:8 | mi | |
| arrayassignment.cpp:72:8:72:9 | call to MyInt | arrayassignment.cpp:78:7:78:8 | mi | |
| arrayassignment.cpp:72:12:72:14 | call to MyInt | arrayassignment.cpp:75:2:75:4 | mi2 | |
| arrayassignment.cpp:72:12:72:14 | call to MyInt | arrayassignment.cpp:79:7:79:9 | mi2 | |
| arrayassignment.cpp:72:12:72:14 | call to MyInt | arrayassignment.cpp:80:7:80:9 | mi2 | |
| arrayassignment.cpp:74:2:74:3 | ref arg mi | arrayassignment.cpp:75:8:75:9 | mi | |
| arrayassignment.cpp:74:2:74:3 | ref arg mi | arrayassignment.cpp:77:7:77:8 | mi | |
| arrayassignment.cpp:74:2:74:3 | ref arg mi | arrayassignment.cpp:78:7:78:8 | mi | |
| arrayassignment.cpp:75:2:75:4 | ref arg mi2 | arrayassignment.cpp:79:7:79:9 | mi2 | |
| arrayassignment.cpp:75:2:75:4 | ref arg mi2 | arrayassignment.cpp:80:7:80:9 | mi2 | |
| arrayassignment.cpp:75:8:75:9 | mi | arrayassignment.cpp:75:2:75:4 | ref arg mi2 | TAINT |
| arrayassignment.cpp:75:8:75:9 | mi | arrayassignment.cpp:75:6:75:6 | call to operator= | TAINT |
| arrayassignment.cpp:86:2:86:8 | this | arrayassignment.cpp:86:14:86:24 | constructor init of field values [pre-this] | |
| arrayassignment.cpp:86:14:86:24 | {...} | arrayassignment.cpp:86:14:86:24 | constructor init of field values | TAINT |
| arrayassignment.cpp:86:22:86:22 | 0 | arrayassignment.cpp:86:14:86:24 | {...} | TAINT |
| arrayassignment.cpp:88:7:88:9 | this | arrayassignment.cpp:88:27:88:32 | this | |
| arrayassignment.cpp:88:15:88:15 | i | arrayassignment.cpp:88:34:88:34 | i | |
| arrayassignment.cpp:88:27:88:32 | values | arrayassignment.cpp:88:27:88:35 | access to array | TAINT |
| arrayassignment.cpp:88:34:88:34 | i | arrayassignment.cpp:88:27:88:35 | access to array | TAINT |
| arrayassignment.cpp:97:10:97:11 | call to MyArray | arrayassignment.cpp:99:2:99:3 | ma | |
| arrayassignment.cpp:97:10:97:11 | call to MyArray | arrayassignment.cpp:101:7:101:8 | ma | |
| arrayassignment.cpp:99:2:99:3 | ma [post update] | arrayassignment.cpp:101:7:101:8 | ma | |
| arrayassignment.cpp:99:2:99:13 | access to array [post update] | arrayassignment.cpp:99:5:99:10 | values [inner post update] | |
| arrayassignment.cpp:99:2:99:24 | ... = ... | arrayassignment.cpp:99:2:99:13 | access to array [post update] | |
| arrayassignment.cpp:99:5:99:10 | values | arrayassignment.cpp:99:2:99:13 | access to array | TAINT |
| arrayassignment.cpp:99:12:99:12 | 0 | arrayassignment.cpp:99:2:99:13 | access to array | TAINT |
| arrayassignment.cpp:99:17:99:22 | call to source | arrayassignment.cpp:99:2:99:24 | ... = ... | |
| arrayassignment.cpp:101:10:101:15 | values | arrayassignment.cpp:101:7:101:18 | access to array | TAINT |
| arrayassignment.cpp:101:17:101:17 | 0 | arrayassignment.cpp:101:7:101:18 | access to array | TAINT |
| arrayassignment.cpp:106:10:106:11 | call to MyArray | arrayassignment.cpp:108:2:108:3 | ma | |
| arrayassignment.cpp:106:10:106:11 | call to MyArray | arrayassignment.cpp:110:7:110:8 | ma | |
| arrayassignment.cpp:108:2:108:3 | ref arg ma | arrayassignment.cpp:110:7:110:8 | ma | |
| arrayassignment.cpp:108:2:108:21 | ... = ... | arrayassignment.cpp:108:5:108:7 | call to get [post update] | |
| arrayassignment.cpp:108:14:108:19 | call to source | arrayassignment.cpp:108:2:108:21 | ... = ... | |
| arrayassignment.cpp:115:10:115:11 | call to MyArray | arrayassignment.cpp:117:2:117:3 | ma | |
| arrayassignment.cpp:115:10:115:11 | call to MyArray | arrayassignment.cpp:118:8:118:9 | ma | |
| arrayassignment.cpp:115:10:115:11 | call to MyArray | arrayassignment.cpp:120:7:120:8 | ma | |
| arrayassignment.cpp:117:2:117:3 | ref arg ma | arrayassignment.cpp:118:8:118:9 | ma | |
| arrayassignment.cpp:117:2:117:3 | ref arg ma | arrayassignment.cpp:120:7:120:8 | ma | |
| arrayassignment.cpp:117:2:117:17 | ... = ... | arrayassignment.cpp:117:4:117:4 | call to operator[] [post update] | |
| arrayassignment.cpp:117:10:117:15 | call to source | arrayassignment.cpp:117:2:117:17 | ... = ... | |
| arrayassignment.cpp:118:8:118:9 | ma | arrayassignment.cpp:118:2:118:9 | ... = ... | |
| arrayassignment.cpp:118:8:118:9 | ma | arrayassignment.cpp:121:7:121:9 | ma2 | |
| arrayassignment.cpp:128:16:128:19 | {...} | arrayassignment.cpp:131:14:131:17 | arr1 | |
| arrayassignment.cpp:128:16:128:19 | {...} | arrayassignment.cpp:136:7:136:10 | arr1 | |
| arrayassignment.cpp:128:18:128:18 | 0 | arrayassignment.cpp:128:16:128:19 | {...} | TAINT |
| arrayassignment.cpp:129:16:129:19 | {...} | arrayassignment.cpp:138:11:138:14 | arr2 | |
| arrayassignment.cpp:129:16:129:19 | {...} | arrayassignment.cpp:141:7:141:10 | arr2 | |
| arrayassignment.cpp:129:18:129:18 | 0 | arrayassignment.cpp:129:16:129:19 | {...} | TAINT |
| arrayassignment.cpp:130:16:130:19 | {...} | arrayassignment.cpp:143:9:143:12 | arr3 | |
| arrayassignment.cpp:130:16:130:19 | {...} | arrayassignment.cpp:146:7:146:10 | arr3 | |
| arrayassignment.cpp:130:18:130:18 | 0 | arrayassignment.cpp:130:16:130:19 | {...} | TAINT |
| arrayassignment.cpp:131:14:131:17 | arr1 | arrayassignment.cpp:131:14:131:20 | access to array | TAINT |
| arrayassignment.cpp:131:19:131:19 | 5 | arrayassignment.cpp:131:14:131:20 | access to array | TAINT |
| arrayassignment.cpp:134:9:134:14 | call to source | arrayassignment.cpp:134:2:134:16 | ... = ... | |
| arrayassignment.cpp:134:9:134:14 | call to source | arrayassignment.cpp:135:7:135:10 | ref1 | |
| arrayassignment.cpp:136:7:136:10 | arr1 | arrayassignment.cpp:136:7:136:13 | access to array | TAINT |
| arrayassignment.cpp:136:12:136:12 | 5 | arrayassignment.cpp:136:7:136:13 | access to array | TAINT |
| arrayassignment.cpp:138:9:138:18 | & ... | arrayassignment.cpp:138:2:138:18 | ... = ... | |
| arrayassignment.cpp:138:9:138:18 | & ... | arrayassignment.cpp:139:3:139:6 | ptr2 | |
| arrayassignment.cpp:138:9:138:18 | & ... | arrayassignment.cpp:140:8:140:11 | ptr2 | |
| arrayassignment.cpp:138:11:138:14 | arr2 | arrayassignment.cpp:138:11:138:17 | access to array | TAINT |
| arrayassignment.cpp:138:11:138:17 | access to array | arrayassignment.cpp:138:9:138:18 | & ... | |
| arrayassignment.cpp:138:16:138:16 | 5 | arrayassignment.cpp:138:11:138:17 | access to array | TAINT |
| arrayassignment.cpp:139:3:139:6 | ptr2 | arrayassignment.cpp:139:2:139:6 | * ... | TAINT |
| arrayassignment.cpp:139:10:139:15 | call to source | arrayassignment.cpp:139:2:139:17 | ... = ... | |
| arrayassignment.cpp:140:8:140:11 | ptr2 | arrayassignment.cpp:140:7:140:11 | * ... | TAINT |
| arrayassignment.cpp:141:7:141:10 | arr2 | arrayassignment.cpp:141:7:141:13 | access to array | TAINT |
| arrayassignment.cpp:141:12:141:12 | 5 | arrayassignment.cpp:141:7:141:13 | access to array | TAINT |
| arrayassignment.cpp:143:9:143:12 | arr3 | arrayassignment.cpp:143:2:143:12 | ... = ... | |
| arrayassignment.cpp:143:9:143:12 | arr3 | arrayassignment.cpp:144:2:144:5 | ptr3 | |
| arrayassignment.cpp:143:9:143:12 | arr3 | arrayassignment.cpp:145:7:145:10 | ptr3 | |
| arrayassignment.cpp:144:2:144:5 | ptr3 | arrayassignment.cpp:144:2:144:8 | access to array | TAINT |
| arrayassignment.cpp:144:7:144:7 | 5 | arrayassignment.cpp:144:2:144:8 | access to array | TAINT |
| arrayassignment.cpp:144:12:144:17 | call to source | arrayassignment.cpp:144:2:144:19 | ... = ... | |
| arrayassignment.cpp:145:7:145:10 | ptr3 | arrayassignment.cpp:145:7:145:13 | access to array | TAINT |
| arrayassignment.cpp:145:12:145:12 | 5 | arrayassignment.cpp:145:7:145:13 | access to array | TAINT |
| arrayassignment.cpp:146:7:146:10 | arr3 | arrayassignment.cpp:146:7:146:13 | access to array | TAINT |
| arrayassignment.cpp:146:12:146:12 | 5 | arrayassignment.cpp:146:7:146:13 | access to array | TAINT |
| copyableclass.cpp:8:2:8:16 | this | copyableclass.cpp:8:28:8:32 | constructor init of field v [pre-this] | |
| copyableclass.cpp:8:22:8:23 | _v | copyableclass.cpp:8:30:8:31 | _v | |
| copyableclass.cpp:8:30:8:31 | _v | copyableclass.cpp:8:28:8:32 | constructor init of field v | TAINT |
@ -9,6 +133,7 @@
| copyableclass.cpp:10:52:10:56 | other | copyableclass.cpp:11:7:11:11 | other | |
| copyableclass.cpp:11:3:11:3 | this | copyableclass.cpp:12:11:12:14 | this | |
| copyableclass.cpp:11:3:11:3 | this [post update] | copyableclass.cpp:12:11:12:14 | this | |
| copyableclass.cpp:11:3:11:13 | ... = ... | copyableclass.cpp:11:3:11:3 | v [post update] | |
| copyableclass.cpp:11:13:11:13 | v | copyableclass.cpp:11:3:11:13 | ... = ... | |
| copyableclass.cpp:12:11:12:14 | this | copyableclass.cpp:12:10:12:14 | * ... | TAINT |
| copyableclass.cpp:21:22:21:22 | 1 | copyableclass.cpp:21:22:21:23 | call to MyCopyableClass | TAINT |
@ -257,8 +382,10 @@
| movableclass.cpp:9:34:9:38 | other | movableclass.cpp:9:34:9:38 | other | |
| movableclass.cpp:9:34:9:38 | other | movableclass.cpp:10:7:10:11 | other | |
| movableclass.cpp:9:34:9:38 | other | movableclass.cpp:11:3:11:7 | other | |
| movableclass.cpp:10:3:10:13 | ... = ... | movableclass.cpp:10:3:10:3 | v [post update] | |
| movableclass.cpp:10:13:10:13 | v | movableclass.cpp:10:3:10:13 | ... = ... | |
| movableclass.cpp:11:3:11:7 | other [post update] | movableclass.cpp:9:34:9:38 | other | |
| movableclass.cpp:11:3:11:13 | ... = ... | movableclass.cpp:11:9:11:9 | v [post update] | |
| movableclass.cpp:11:13:11:13 | 0 | movableclass.cpp:11:3:11:13 | ... = ... | |
| movableclass.cpp:13:18:13:26 | this | movableclass.cpp:14:3:14:3 | this | |
| movableclass.cpp:13:45:13:49 | other | movableclass.cpp:13:45:13:49 | other | |
@ -266,8 +393,10 @@
| movableclass.cpp:13:45:13:49 | other | movableclass.cpp:15:3:15:7 | other | |
| movableclass.cpp:14:3:14:3 | this | movableclass.cpp:16:11:16:14 | this | |
| movableclass.cpp:14:3:14:3 | this [post update] | movableclass.cpp:16:11:16:14 | this | |
| movableclass.cpp:14:3:14:13 | ... = ... | movableclass.cpp:14:3:14:3 | v [post update] | |
| movableclass.cpp:14:13:14:13 | v | movableclass.cpp:14:3:14:13 | ... = ... | |
| movableclass.cpp:15:3:15:7 | other [post update] | movableclass.cpp:13:45:13:49 | other | |
| movableclass.cpp:15:3:15:13 | ... = ... | movableclass.cpp:15:9:15:9 | v [post update] | |
| movableclass.cpp:15:13:15:13 | 0 | movableclass.cpp:15:3:15:13 | ... = ... | |
| movableclass.cpp:16:11:16:14 | this | movableclass.cpp:16:10:16:14 | * ... | TAINT |
| movableclass.cpp:22:57:22:57 | 1 | movableclass.cpp:22:42:22:58 | call to MyMovableClass | TAINT |
@ -308,6 +437,12 @@
| 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.h:139:30:139:40 | call to allocator | stl.h:139:21:139:41 | noexcept(...) | TAINT |
| stl.h:139:30:139:40 | call to allocator | stl.h:139:21:139:41 | noexcept(...) | TAINT |
| stl.h:139:30:139:40 | call to allocator | stl.h:139:21:139:41 | noexcept(...) | TAINT |
| stl.h:139:30:139:40 | call to allocator | stl.h:139:21:139:41 | noexcept(...) | TAINT |
| stl.h:139:30:139:40 | call to allocator | stl.h:139:21:139:41 | noexcept(...) | TAINT |
| stl.h:139:53:139:63 | 0 | stl.h:139:46:139:64 | (no string representation) | TAINT |
| string.cpp:24:12:24:17 | call to source | string.cpp:28:7:28:7 | a | |
| string.cpp:25:16:25:20 | 123 | string.cpp:25:16:25:21 | call to basic_string | TAINT |
| string.cpp:25:16:25:21 | call to basic_string | string.cpp:29:7:29:7 | b | |
@ -677,6 +812,51 @@
| string.cpp:319:16:319:24 | call to basic_string | string.cpp:322:19:322:19 | b | |
| string.cpp:321:7:321:7 | a | string.cpp:321:9:321:14 | call to substr | TAINT |
| string.cpp:322:7:322:7 | b | string.cpp:322:9:322:14 | call to substr | TAINT |
| string.cpp:327:16:327:20 | 123 | string.cpp:327:16:327:21 | call to basic_string | TAINT |
| string.cpp:327:16:327:21 | call to basic_string | string.cpp:331:7:331:7 | a | |
| string.cpp:327:16:327:21 | call to basic_string | string.cpp:335:2:335:2 | a | |
| string.cpp:327:16:327:21 | call to basic_string | string.cpp:337:9:337:9 | a | |
| string.cpp:327:16:327:21 | call to basic_string | string.cpp:339:7:339:7 | a | |
| string.cpp:328:16:328:20 | 123 | string.cpp:328:16:328:21 | call to basic_string | TAINT |
| string.cpp:328:16:328:21 | call to basic_string | string.cpp:332:7:332:7 | b | |
| string.cpp:328:16:328:21 | call to basic_string | string.cpp:336:2:336:2 | b | |
| string.cpp:328:16:328:21 | call to basic_string | string.cpp:340:7:340:7 | b | |
| string.cpp:329:16:329:20 | 123 | string.cpp:329:16:329:21 | call to basic_string | TAINT |
| string.cpp:329:16:329:21 | call to basic_string | string.cpp:333:7:333:7 | c | |
| string.cpp:329:16:329:21 | call to basic_string | string.cpp:337:2:337:2 | c | |
| string.cpp:329:16:329:21 | call to basic_string | string.cpp:341:7:341:7 | c | |
| string.cpp:335:2:335:2 | a | string.cpp:335:3:335:3 | call to operator[] | TAINT |
| string.cpp:335:2:335:2 | ref arg a | string.cpp:337:9:337:9 | a | |
| string.cpp:335:2:335:2 | ref arg a | string.cpp:339:7:339:7 | a | |
| string.cpp:335:2:335:25 | ... = ... | string.cpp:335:3:335:3 | call to operator[] [post update] | |
| string.cpp:335:3:335:3 | call to operator[] [post update] | string.cpp:335:2:335:2 | ref arg a | TAINT |
| string.cpp:335:9:335:23 | call to source | string.cpp:335:2:335:25 | ... = ... | |
| string.cpp:336:2:336:2 | b | string.cpp:336:4:336:5 | call to at | TAINT |
| string.cpp:336:2:336:2 | ref arg b | string.cpp:340:7:340:7 | b | |
| string.cpp:336:2:336:28 | ... = ... | string.cpp:336:4:336:5 | call to at [post update] | |
| string.cpp:336:4:336:5 | call to at [post update] | string.cpp:336:2:336:2 | ref arg b | TAINT |
| string.cpp:336:12:336:26 | call to source | string.cpp:336:2:336:28 | ... = ... | |
| string.cpp:337:2:337:2 | c | string.cpp:337:3:337:3 | call to operator[] | TAINT |
| string.cpp:337:2:337:2 | ref arg c | string.cpp:341:7:341:7 | c | |
| string.cpp:337:2:337:12 | ... = ... | string.cpp:337:3:337:3 | call to operator[] [post update] | |
| string.cpp:337:3:337:3 | call to operator[] [post update] | string.cpp:337:2:337:2 | ref arg c | TAINT |
| string.cpp:337:9:337:9 | a | string.cpp:337:10:337:10 | call to operator[] | TAINT |
| string.cpp:337:9:337:9 | ref arg a | string.cpp:339:7:339:7 | a | |
| string.cpp:337:10:337:10 | call to operator[] | string.cpp:337:2:337:12 | ... = ... | |
| string.cpp:346:18:346:22 | 123 | string.cpp:346:18:346:23 | call to basic_string | TAINT |
| string.cpp:346:18:346:23 | call to basic_string | string.cpp:348:2:348:4 | str | |
| string.cpp:346:18:346:23 | call to basic_string | string.cpp:349:7:349:9 | str | |
| string.cpp:346:18:346:23 | call to basic_string | string.cpp:350:7:350:9 | str | |
| string.cpp:348:2:348:4 | ref arg str | string.cpp:349:7:349:9 | str | |
| string.cpp:348:2:348:4 | ref arg str | string.cpp:350:7:350:9 | str | |
| string.cpp:348:2:348:4 | str | string.cpp:348:6:348:9 | call to data | TAINT |
| string.cpp:348:2:348:14 | access to array [post update] | string.cpp:348:6:348:9 | call to data [inner post update] | |
| string.cpp:348:2:348:34 | ... = ... | string.cpp:348:2:348:14 | access to array [post update] | |
| string.cpp:348:6:348:9 | call to data | string.cpp:348:2:348:14 | access to array | TAINT |
| string.cpp:348:6:348:9 | call to data [inner post update] | string.cpp:348:2:348:4 | ref arg str | TAINT |
| string.cpp:348:13:348:13 | 1 | string.cpp:348:2:348:14 | access to array | TAINT |
| string.cpp:348:18:348:32 | call to source | string.cpp:348:2:348:34 | ... = ... | |
| string.cpp:350:7:350:9 | str | string.cpp:350:11:350:14 | call to data | 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 | |
@ -824,6 +1004,7 @@
| swap1.cpp:71:5:71:5 | x [post update] | swap1.cpp:73:10:73:10 | x | |
| swap1.cpp:71:5:71:5 | x [post update] | swap1.cpp:76:9:76:9 | x | |
| swap1.cpp:71:5:71:5 | x [post update] | swap1.cpp:79:10:79:10 | x | |
| swap1.cpp:71:5:71:22 | ... = ... | swap1.cpp:71:7:71:11 | data1 [post update] | |
| swap1.cpp:71:5:71:22 | ... = ... | swap1.cpp:73:12:73:16 | data1 | |
| swap1.cpp:71:5:71:22 | ... = ... | swap1.cpp:79:12:79:16 | data1 | |
| swap1.cpp:71:15:71:20 | call to source | swap1.cpp:71:5:71:22 | ... = ... | |
@ -839,6 +1020,7 @@
| swap1.cpp:82:5:82:6 | z1 [post update] | swap1.cpp:83:10:83:11 | z1 | |
| swap1.cpp:82:5:82:6 | z1 [post update] | swap1.cpp:85:10:85:11 | z1 | |
| swap1.cpp:82:5:82:6 | z1 [post update] | swap1.cpp:88:10:88:11 | z1 | |
| swap1.cpp:82:5:82:23 | ... = ... | swap1.cpp:82:8:82:12 | data1 [post update] | |
| swap1.cpp:82:5:82:23 | ... = ... | swap1.cpp:83:13:83:17 | data1 | |
| swap1.cpp:82:5:82:23 | ... = ... | swap1.cpp:88:13:88:17 | data1 | |
| swap1.cpp:82:16:82:21 | call to source | swap1.cpp:82:5:82:23 | ... = ... | |
@ -854,6 +1036,7 @@
| swap1.cpp:95:5:95:5 | x [post update] | swap1.cpp:97:10:97:10 | x | |
| swap1.cpp:95:5:95:5 | x [post update] | swap1.cpp:100:19:100:19 | x | |
| swap1.cpp:95:5:95:5 | x [post update] | swap1.cpp:103:10:103:10 | x | |
| swap1.cpp:95:5:95:22 | ... = ... | swap1.cpp:95:7:95:11 | data1 [post update] | |
| swap1.cpp:95:5:95:22 | ... = ... | swap1.cpp:97:12:97:16 | data1 | |
| swap1.cpp:95:5:95:22 | ... = ... | swap1.cpp:103:12:103:16 | data1 | |
| swap1.cpp:95:15:95:20 | call to source | swap1.cpp:95:5:95:22 | ... = ... | |
@ -870,6 +1053,7 @@
| swap1.cpp:108:23:108:31 | move_from | swap1.cpp:113:41:113:49 | move_from | |
| swap1.cpp:109:5:109:13 | move_from [post update] | swap1.cpp:111:10:111:18 | move_from | |
| swap1.cpp:109:5:109:13 | move_from [post update] | swap1.cpp:113:41:113:49 | move_from | |
| swap1.cpp:109:5:109:30 | ... = ... | swap1.cpp:109:15:109:19 | data1 [post update] | |
| swap1.cpp:109:5:109:30 | ... = ... | swap1.cpp:111:20:111:24 | data1 | |
| swap1.cpp:109:5:109:30 | ... = ... | swap1.cpp:115:18:115:22 | data1 | |
| swap1.cpp:109:23:109:28 | call to source | swap1.cpp:109:5:109:30 | ... = ... | |
@ -887,6 +1071,7 @@
| swap1.cpp:122:5:122:5 | x [post update] | swap1.cpp:124:10:124:10 | x | |
| swap1.cpp:122:5:122:5 | x [post update] | swap1.cpp:127:19:127:19 | x | |
| swap1.cpp:122:5:122:5 | x [post update] | swap1.cpp:130:10:130:10 | x | |
| swap1.cpp:122:5:122:22 | ... = ... | swap1.cpp:122:7:122:11 | data1 [post update] | |
| swap1.cpp:122:5:122:22 | ... = ... | swap1.cpp:124:12:124:16 | data1 | |
| swap1.cpp:122:5:122:22 | ... = ... | swap1.cpp:130:12:130:16 | data1 | |
| swap1.cpp:122:15:122:20 | call to source | swap1.cpp:122:5:122:22 | ... = ... | |
@ -901,6 +1086,7 @@
| swap1.cpp:137:5:137:5 | x [post update] | swap1.cpp:139:10:139:10 | x | |
| swap1.cpp:137:5:137:5 | x [post update] | swap1.cpp:142:29:142:29 | x | |
| swap1.cpp:137:5:137:5 | x [post update] | swap1.cpp:145:10:145:10 | x | |
| swap1.cpp:137:5:137:22 | ... = ... | swap1.cpp:137:7:137:11 | data1 [post update] | |
| swap1.cpp:137:5:137:22 | ... = ... | swap1.cpp:139:12:139:16 | data1 | |
| swap1.cpp:137:5:137:22 | ... = ... | swap1.cpp:145:12:145:16 | data1 | |
| swap1.cpp:137:15:137:20 | call to source | swap1.cpp:137:5:137:22 | ... = ... | |
@ -990,6 +1176,7 @@
| swap2.cpp:71:5:71:5 | x [post update] | swap2.cpp:73:10:73:10 | x | |
| swap2.cpp:71:5:71:5 | x [post update] | swap2.cpp:76:9:76:9 | x | |
| swap2.cpp:71:5:71:5 | x [post update] | swap2.cpp:79:10:79:10 | x | |
| swap2.cpp:71:5:71:22 | ... = ... | swap2.cpp:71:7:71:11 | data1 [post update] | |
| swap2.cpp:71:5:71:22 | ... = ... | swap2.cpp:73:12:73:16 | data1 | |
| swap2.cpp:71:5:71:22 | ... = ... | swap2.cpp:79:12:79:16 | data1 | |
| swap2.cpp:71:15:71:20 | call to source | swap2.cpp:71:5:71:22 | ... = ... | |
@ -1005,6 +1192,7 @@
| swap2.cpp:82:5:82:6 | z1 [post update] | swap2.cpp:83:10:83:11 | z1 | |
| swap2.cpp:82:5:82:6 | z1 [post update] | swap2.cpp:85:10:85:11 | z1 | |
| swap2.cpp:82:5:82:6 | z1 [post update] | swap2.cpp:88:10:88:11 | z1 | |
| swap2.cpp:82:5:82:23 | ... = ... | swap2.cpp:82:8:82:12 | data1 [post update] | |
| swap2.cpp:82:5:82:23 | ... = ... | swap2.cpp:83:13:83:17 | data1 | |
| swap2.cpp:82:5:82:23 | ... = ... | swap2.cpp:88:13:88:17 | data1 | |
| swap2.cpp:82:16:82:21 | call to source | swap2.cpp:82:5:82:23 | ... = ... | |
@ -1020,6 +1208,7 @@
| swap2.cpp:95:5:95:5 | x [post update] | swap2.cpp:97:10:97:10 | x | |
| swap2.cpp:95:5:95:5 | x [post update] | swap2.cpp:100:19:100:19 | x | |
| swap2.cpp:95:5:95:5 | x [post update] | swap2.cpp:103:10:103:10 | x | |
| swap2.cpp:95:5:95:22 | ... = ... | swap2.cpp:95:7:95:11 | data1 [post update] | |
| swap2.cpp:95:5:95:22 | ... = ... | swap2.cpp:97:12:97:16 | data1 | |
| swap2.cpp:95:5:95:22 | ... = ... | swap2.cpp:103:12:103:16 | data1 | |
| swap2.cpp:95:15:95:20 | call to source | swap2.cpp:95:5:95:22 | ... = ... | |
@ -1036,6 +1225,7 @@
| swap2.cpp:108:23:108:31 | move_from | swap2.cpp:113:41:113:49 | move_from | |
| swap2.cpp:109:5:109:13 | move_from [post update] | swap2.cpp:111:10:111:18 | move_from | |
| swap2.cpp:109:5:109:13 | move_from [post update] | swap2.cpp:113:41:113:49 | move_from | |
| swap2.cpp:109:5:109:30 | ... = ... | swap2.cpp:109:15:109:19 | data1 [post update] | |
| swap2.cpp:109:5:109:30 | ... = ... | swap2.cpp:111:20:111:24 | data1 | |
| swap2.cpp:109:5:109:30 | ... = ... | swap2.cpp:115:18:115:22 | data1 | |
| swap2.cpp:109:23:109:28 | call to source | swap2.cpp:109:5:109:30 | ... = ... | |
@ -1053,6 +1243,7 @@
| swap2.cpp:122:5:122:5 | x [post update] | swap2.cpp:124:10:124:10 | x | |
| swap2.cpp:122:5:122:5 | x [post update] | swap2.cpp:127:19:127:19 | x | |
| swap2.cpp:122:5:122:5 | x [post update] | swap2.cpp:130:10:130:10 | x | |
| swap2.cpp:122:5:122:22 | ... = ... | swap2.cpp:122:7:122:11 | data1 [post update] | |
| swap2.cpp:122:5:122:22 | ... = ... | swap2.cpp:124:12:124:16 | data1 | |
| swap2.cpp:122:5:122:22 | ... = ... | swap2.cpp:130:12:130:16 | data1 | |
| swap2.cpp:122:15:122:20 | call to source | swap2.cpp:122:5:122:22 | ... = ... | |
@ -1067,6 +1258,7 @@
| swap2.cpp:137:5:137:5 | x [post update] | swap2.cpp:139:10:139:10 | x | |
| swap2.cpp:137:5:137:5 | x [post update] | swap2.cpp:142:29:142:29 | x | |
| swap2.cpp:137:5:137:5 | x [post update] | swap2.cpp:145:10:145:10 | x | |
| swap2.cpp:137:5:137:22 | ... = ... | swap2.cpp:137:7:137:11 | data1 [post update] | |
| swap2.cpp:137:5:137:22 | ... = ... | swap2.cpp:139:12:139:16 | data1 | |
| swap2.cpp:137:5:137:22 | ... = ... | swap2.cpp:145:12:145:16 | data1 | |
| swap2.cpp:137:15:137:20 | call to source | swap2.cpp:137:5:137:22 | ... = ... | |
@ -1125,9 +1317,12 @@
| taint.cpp:71:22:71:27 | call to source | taint.cpp:71:20:71:30 | constructor init of field b | TAINT |
| taint.cpp:72:3:72:3 | this | taint.cpp:73:3:73:3 | this | |
| taint.cpp:72:3:72:3 | this [post update] | taint.cpp:73:3:73:3 | this | |
| taint.cpp:72:3:72:14 | ... = ... | taint.cpp:72:3:72:3 | c [post update] | |
| taint.cpp:72:7:72:12 | call to source | taint.cpp:72:3:72:14 | ... = ... | |
| taint.cpp:73:3:73:7 | ... = ... | taint.cpp:73:3:73:3 | d [post update] | |
| taint.cpp:73:7:73:7 | 0 | taint.cpp:73:3:73:7 | ... = ... | |
| taint.cpp:76:7:76:14 | this | taint.cpp:77:3:77:3 | this | |
| taint.cpp:77:3:77:14 | ... = ... | taint.cpp:77:3:77:3 | d [post update] | |
| taint.cpp:77:7:77:12 | call to source | taint.cpp:77:3:77:14 | ... = ... | |
| taint.cpp:84:10:84:12 | call to MyClass | taint.cpp:86:2:86:4 | mc1 | |
| taint.cpp:84:10:84:12 | call to MyClass | taint.cpp:88:7:88:9 | mc1 | |
@ -1287,6 +1482,7 @@
| taint.cpp:235:15:235:15 | this | taint.cpp:236:3:236:6 | this | |
| taint.cpp:236:3:236:6 | this | taint.cpp:237:3:237:6 | this | |
| taint.cpp:237:3:237:6 | this | taint.cpp:238:3:238:14 | this | |
| taint.cpp:238:3:238:14 | ... = ... | taint.cpp:238:3:238:14 | v [post update] | |
| taint.cpp:238:7:238:12 | call to source | taint.cpp:238:3:238:14 | ... = ... | |
| taint.cpp:243:10:246:2 | [...](...){...} | taint.cpp:247:2:247:2 | c | |
| taint.cpp:243:10:246:2 | {...} | taint.cpp:243:10:246:2 | [...](...){...} | |
@ -1454,6 +1650,7 @@
| taint.cpp:428:2:428:2 | b [post update] | taint.cpp:429:7:429:7 | b | |
| taint.cpp:428:2:428:2 | b [post update] | taint.cpp:430:7:430:7 | b | |
| taint.cpp:428:2:428:2 | b [post update] | taint.cpp:431:7:431:7 | b | |
| taint.cpp:428:2:428:20 | ... = ... | taint.cpp:428:4:428:9 | member [post update] | |
| taint.cpp:428:2:428:20 | ... = ... | taint.cpp:430:9:430:14 | member | |
| taint.cpp:428:13:428:18 | call to source | taint.cpp:428:2:428:20 | ... = ... | |
| taint.cpp:433:6:433:20 | call to MyClass2 | taint.cpp:433:6:433:20 | new | |
@ -1646,6 +1843,9 @@
| vector.cpp:40:2:40:3 | ref arg v1 | vector.cpp:48:7:48:8 | v1 | |
| vector.cpp:40:2:40:3 | ref arg v1 | vector.cpp:49:7:49:8 | v1 | |
| vector.cpp:40:2:40:3 | ref arg v1 | vector.cpp:101:1:101:1 | v1 | |
| vector.cpp:40:2:40:3 | v1 | vector.cpp:40:4:40:4 | call to operator[] | TAINT |
| vector.cpp:40:2:40:10 | ... = ... | vector.cpp:40:4:40:4 | call to operator[] [post update] | |
| vector.cpp:40:4:40:4 | call to operator[] [post update] | vector.cpp:40:2:40:3 | ref arg v1 | TAINT |
| vector.cpp:40:10:40:10 | 0 | vector.cpp:40:2:40:10 | ... = ... | |
| vector.cpp:41:2:41:3 | ref arg v1 | vector.cpp:42:2:42:3 | v1 | |
| vector.cpp:41:2:41:3 | ref arg v1 | vector.cpp:43:2:43:3 | v1 | |
@ -1656,6 +1856,9 @@
| vector.cpp:41:2:41:3 | ref arg v1 | vector.cpp:48:7:48:8 | v1 | |
| vector.cpp:41:2:41:3 | ref arg v1 | vector.cpp:49:7:49:8 | v1 | |
| vector.cpp:41:2:41:3 | ref arg v1 | vector.cpp:101:1:101:1 | v1 | |
| vector.cpp:41:2:41:3 | v1 | vector.cpp:41:4:41:4 | call to operator[] | TAINT |
| vector.cpp:41:2:41:10 | ... = ... | vector.cpp:41:4:41:4 | call to operator[] [post update] | |
| vector.cpp:41:4:41:4 | call to operator[] [post update] | vector.cpp:41:2:41:3 | ref arg v1 | TAINT |
| vector.cpp:41:10:41:10 | 0 | vector.cpp:41:2:41:10 | ... = ... | |
| vector.cpp:42:2:42:3 | ref arg v1 | vector.cpp:43:2:43:3 | v1 | |
| vector.cpp:42:2:42:3 | ref arg v1 | vector.cpp:44:7:44:8 | v1 | |
@ -1665,6 +1868,9 @@
| vector.cpp:42:2:42:3 | ref arg v1 | vector.cpp:48:7:48:8 | v1 | |
| vector.cpp:42:2:42:3 | ref arg v1 | vector.cpp:49:7:49:8 | v1 | |
| vector.cpp:42:2:42:3 | ref arg v1 | vector.cpp:101:1:101:1 | v1 | |
| vector.cpp:42:2:42:3 | v1 | vector.cpp:42:4:42:4 | call to operator[] | TAINT |
| vector.cpp:42:2:42:10 | ... = ... | vector.cpp:42:4:42:4 | call to operator[] [post update] | |
| vector.cpp:42:4:42:4 | call to operator[] [post update] | vector.cpp:42:2:42:3 | ref arg v1 | TAINT |
| vector.cpp:42:10:42:10 | 0 | vector.cpp:42:2:42:10 | ... = ... | |
| vector.cpp:43:2:43:3 | ref arg v1 | vector.cpp:44:7:44:8 | v1 | |
| vector.cpp:43:2:43:3 | ref arg v1 | vector.cpp:45:7:45:8 | v1 | |
@ -1685,13 +1891,16 @@
| vector.cpp:45:7:45:8 | ref arg v1 | vector.cpp:48:7:48:8 | v1 | |
| vector.cpp:45:7:45:8 | ref arg v1 | vector.cpp:49:7:49:8 | v1 | |
| vector.cpp:45:7:45:8 | ref arg v1 | vector.cpp:101:1:101:1 | v1 | |
| vector.cpp:45:7:45:8 | v1 | vector.cpp:45:9:45:9 | call to operator[] | TAINT |
| vector.cpp:46:7:46:8 | ref arg v1 | vector.cpp:47:7:47:8 | v1 | |
| vector.cpp:46:7:46:8 | ref arg v1 | vector.cpp:48:7:48:8 | v1 | |
| vector.cpp:46:7:46:8 | ref arg v1 | vector.cpp:49:7:49:8 | v1 | |
| vector.cpp:46:7:46:8 | ref arg v1 | vector.cpp:101:1:101:1 | v1 | |
| vector.cpp:46:7:46:8 | v1 | vector.cpp:46:9:46:9 | call to operator[] | TAINT |
| vector.cpp:47:7:47:8 | ref arg v1 | vector.cpp:48:7:48:8 | v1 | |
| vector.cpp:47:7:47:8 | ref arg v1 | vector.cpp:49:7:49:8 | v1 | |
| vector.cpp:47:7:47:8 | ref arg v1 | vector.cpp:101:1:101:1 | v1 | |
| vector.cpp:47:7:47:8 | v1 | vector.cpp:47:9:47:9 | call to operator[] | TAINT |
| vector.cpp:48:7:48:8 | ref arg v1 | vector.cpp:49:7:49:8 | v1 | |
| vector.cpp:48:7:48:8 | ref arg v1 | vector.cpp:101:1:101:1 | v1 | |
| vector.cpp:48:7:48:8 | v1 | vector.cpp:48:10:48:14 | call to front | TAINT |
@ -1703,6 +1912,9 @@
| vector.cpp:51:2:51:3 | ref arg v2 | vector.cpp:55:7:55:8 | v2 | |
| vector.cpp:51:2:51:3 | ref arg v2 | vector.cpp:57:7:57:8 | v2 | |
| vector.cpp:51:2:51:3 | ref arg v2 | vector.cpp:101:1:101:1 | v2 | |
| vector.cpp:51:2:51:3 | v2 | vector.cpp:51:4:51:4 | call to operator[] | TAINT |
| vector.cpp:51:2:51:17 | ... = ... | vector.cpp:51:4:51:4 | call to operator[] [post update] | |
| vector.cpp:51:4:51:4 | call to operator[] [post update] | vector.cpp:51:2:51:3 | ref arg v2 | TAINT |
| vector.cpp:51:10:51:15 | call to source | vector.cpp:51:2:51:17 | ... = ... | |
| vector.cpp:52:7:52:8 | ref arg v2 | vector.cpp:53:7:53:8 | v2 | |
| vector.cpp:52:7:52:8 | ref arg v2 | vector.cpp:54:7:54:8 | v2 | |
@ -1713,11 +1925,14 @@
| vector.cpp:53:7:53:8 | ref arg v2 | vector.cpp:55:7:55:8 | v2 | |
| vector.cpp:53:7:53:8 | ref arg v2 | vector.cpp:57:7:57:8 | v2 | |
| vector.cpp:53:7:53:8 | ref arg v2 | vector.cpp:101:1:101:1 | v2 | |
| vector.cpp:53:7:53:8 | v2 | vector.cpp:53:9:53:9 | call to operator[] | TAINT |
| vector.cpp:54:7:54:8 | ref arg v2 | vector.cpp:55:7:55:8 | v2 | |
| vector.cpp:54:7:54:8 | ref arg v2 | vector.cpp:57:7:57:8 | v2 | |
| vector.cpp:54:7:54:8 | ref arg v2 | vector.cpp:101:1:101:1 | v2 | |
| vector.cpp:54:7:54:8 | v2 | vector.cpp:54:9:54:9 | call to operator[] | TAINT |
| vector.cpp:55:7:55:8 | ref arg v2 | vector.cpp:57:7:57:8 | v2 | |
| vector.cpp:55:7:55:8 | ref arg v2 | vector.cpp:101:1:101:1 | v2 | |
| vector.cpp:55:7:55:8 | v2 | vector.cpp:55:9:55:9 | call to operator[] | TAINT |
| vector.cpp:57:2:57:3 | ref arg v3 | vector.cpp:58:7:58:8 | v3 | |
| vector.cpp:57:2:57:3 | ref arg v3 | vector.cpp:59:7:59:8 | v3 | |
| vector.cpp:57:2:57:3 | ref arg v3 | vector.cpp:60:7:60:8 | v3 | |
@ -1732,14 +1947,20 @@
| vector.cpp:59:7:59:8 | ref arg v3 | vector.cpp:60:7:60:8 | v3 | |
| vector.cpp:59:7:59:8 | ref arg v3 | vector.cpp:61:7:61:8 | v3 | |
| vector.cpp:59:7:59:8 | ref arg v3 | vector.cpp:101:1:101:1 | v3 | |
| vector.cpp:59:7:59:8 | v3 | vector.cpp:59:9:59:9 | call to operator[] | TAINT |
| vector.cpp:60:7:60:8 | ref arg v3 | vector.cpp:61:7:61:8 | v3 | |
| vector.cpp:60:7:60:8 | ref arg v3 | vector.cpp:101:1:101:1 | v3 | |
| vector.cpp:60:7:60:8 | v3 | vector.cpp:60:9:60:9 | call to operator[] | TAINT |
| vector.cpp:61:7:61:8 | ref arg v3 | vector.cpp:101:1:101:1 | v3 | |
| vector.cpp:61:7:61:8 | v3 | vector.cpp:61:9:61:9 | call to operator[] | TAINT |
| vector.cpp:63:2:63:3 | ref arg v4 | vector.cpp:64:7:64:8 | v4 | |
| vector.cpp:63:2:63:3 | ref arg v4 | vector.cpp:65:7:65:8 | v4 | |
| vector.cpp:63:2:63:3 | ref arg v4 | vector.cpp:66:7:66:8 | v4 | |
| vector.cpp:63:2:63:3 | ref arg v4 | vector.cpp:67:7:67:8 | v4 | |
| vector.cpp:63:2:63:3 | ref arg v4 | vector.cpp:101:1:101:1 | v4 | |
| vector.cpp:63:2:63:3 | v4 | vector.cpp:63:4:63:4 | call to operator[] | TAINT |
| vector.cpp:63:2:63:17 | ... = ... | vector.cpp:63:4:63:4 | call to operator[] [post update] | |
| vector.cpp:63:4:63:4 | call to operator[] [post update] | vector.cpp:63:2:63:3 | ref arg v4 | TAINT |
| vector.cpp:63:10:63:15 | call to source | vector.cpp:63:2:63:17 | ... = ... | |
| vector.cpp:64:7:64:8 | ref arg v4 | vector.cpp:65:7:65:8 | v4 | |
| vector.cpp:64:7:64:8 | ref arg v4 | vector.cpp:66:7:66:8 | v4 | |
@ -1748,9 +1969,12 @@
| vector.cpp:65:7:65:8 | ref arg v4 | vector.cpp:66:7:66:8 | v4 | |
| vector.cpp:65:7:65:8 | ref arg v4 | vector.cpp:67:7:67:8 | v4 | |
| vector.cpp:65:7:65:8 | ref arg v4 | vector.cpp:101:1:101:1 | v4 | |
| vector.cpp:65:7:65:8 | v4 | vector.cpp:65:9:65:9 | call to operator[] | TAINT |
| vector.cpp:66:7:66:8 | ref arg v4 | vector.cpp:67:7:67:8 | v4 | |
| vector.cpp:66:7:66:8 | ref arg v4 | vector.cpp:101:1:101:1 | v4 | |
| vector.cpp:66:7:66:8 | v4 | vector.cpp:66:9:66:9 | call to operator[] | TAINT |
| vector.cpp:67:7:67:8 | ref arg v4 | vector.cpp:101:1:101:1 | v4 | |
| vector.cpp:67:7:67:8 | v4 | vector.cpp:67:9:67:9 | call to operator[] | TAINT |
| vector.cpp:69:2:69:3 | ref arg v5 | vector.cpp:70:7:70:8 | v5 | |
| vector.cpp:69:2:69:3 | ref arg v5 | vector.cpp:71:7:71:8 | v5 | |
| vector.cpp:69:2:69:3 | ref arg v5 | vector.cpp:72:7:72:8 | v5 | |
@ -1767,13 +1991,17 @@
| vector.cpp:74:2:74:3 | ref arg v6 | vector.cpp:75:7:75:8 | v6 | |
| vector.cpp:74:2:74:3 | ref arg v6 | vector.cpp:76:7:76:8 | v6 | |
| vector.cpp:74:2:74:3 | ref arg v6 | vector.cpp:101:1:101:1 | v6 | |
| vector.cpp:74:2:74:3 | v6 | vector.cpp:74:5:74:8 | call to data | TAINT |
| vector.cpp:74:2:74:13 | access to array [post update] | vector.cpp:74:5:74:8 | call to data [inner post update] | |
| vector.cpp:74:2:74:24 | ... = ... | vector.cpp:74:2:74:13 | access to array [post update] | |
| vector.cpp:74:5:74:8 | call to data | vector.cpp:74:2:74:13 | access to array | TAINT |
| vector.cpp:74:5:74:8 | call to data [inner post update] | vector.cpp:74:2:74:3 | ref arg v6 | TAINT |
| vector.cpp:74:12:74:12 | 2 | vector.cpp:74:2:74:13 | access to array | TAINT |
| vector.cpp:74:17:74:22 | call to source | vector.cpp:74:2:74:24 | ... = ... | |
| vector.cpp:75:7:75:8 | ref arg v6 | vector.cpp:76:7:76:8 | v6 | |
| vector.cpp:75:7:75:8 | ref arg v6 | vector.cpp:101:1:101:1 | v6 | |
| vector.cpp:76:7:76:8 | ref arg v6 | vector.cpp:101:1:101:1 | v6 | |
| vector.cpp:76:7:76:8 | v6 | vector.cpp:76:10:76:13 | call to data | TAINT |
| vector.cpp:76:10:76:13 | call to data | vector.cpp:76:7:76:18 | access to array | TAINT |
| vector.cpp:76:17:76:17 | 2 | vector.cpp:76:7:76:18 | access to array | TAINT |
| vector.cpp:79:33:79:34 | v7 | vector.cpp:80:41:80:43 | v7c | |
@ -1809,6 +2037,9 @@
| vector.cpp:96:2:96:3 | ref arg v9 | vector.cpp:99:7:99:8 | v9 | |
| vector.cpp:96:2:96:3 | ref arg v9 | vector.cpp:100:7:100:8 | v9 | |
| vector.cpp:96:2:96:3 | ref arg v9 | vector.cpp:101:1:101:1 | v9 | |
| vector.cpp:96:2:96:3 | v9 | vector.cpp:96:5:96:6 | call to at | TAINT |
| vector.cpp:96:2:96:20 | ... = ... | vector.cpp:96:5:96:6 | call to at [post update] | |
| vector.cpp:96:5:96:6 | call to at [post update] | vector.cpp:96:2:96:3 | ref arg v9 | TAINT |
| vector.cpp:96:13:96:18 | call to source | vector.cpp:96:2:96:20 | ... = ... | |
| vector.cpp:97:7:97:8 | ref arg v9 | vector.cpp:98:7:98:8 | v9 | |
| vector.cpp:97:7:97:8 | ref arg v9 | vector.cpp:99:7:99:8 | v9 | |
@ -1817,9 +2048,12 @@
| vector.cpp:98:7:98:8 | ref arg v9 | vector.cpp:99:7:99:8 | v9 | |
| vector.cpp:98:7:98:8 | ref arg v9 | vector.cpp:100:7:100:8 | v9 | |
| vector.cpp:98:7:98:8 | ref arg v9 | vector.cpp:101:1:101:1 | v9 | |
| vector.cpp:98:7:98:8 | v9 | vector.cpp:98:10:98:11 | call to at | TAINT |
| vector.cpp:99:7:99:8 | ref arg v9 | vector.cpp:100:7:100:8 | v9 | |
| vector.cpp:99:7:99:8 | ref arg v9 | vector.cpp:101:1:101:1 | v9 | |
| vector.cpp:99:7:99:8 | v9 | vector.cpp:99:10:99:11 | call to at | TAINT |
| vector.cpp:100:7:100:8 | ref arg v9 | vector.cpp:101:1:101:1 | v9 | |
| vector.cpp:100:7:100:8 | v9 | vector.cpp:100:10:100:11 | call to at | TAINT |
| vector.cpp:104:22:104:24 | call to vector | vector.cpp:106:2:106:3 | v1 | |
| vector.cpp:104:22:104:24 | call to vector | vector.cpp:109:7:109:8 | v1 | |
| vector.cpp:104:22:104:24 | call to vector | vector.cpp:114:2:114:3 | v1 | |
@ -1939,3 +2173,327 @@
| vector.cpp:140:7:140:8 | ref arg v2 | vector.cpp:143:1:143:1 | v2 | |
| vector.cpp:141:7:141:8 | ref arg v3 | vector.cpp:143:1:143:1 | v3 | |
| vector.cpp:142:7:142:8 | ref arg v4 | vector.cpp:143:1:143:1 | v4 | |
| vector.cpp:150:8:150:8 | call to vector | vector.cpp:150:8:150:8 | constructor init of field vs | TAINT |
| vector.cpp:150:8:150:8 | call to ~vector | vector.cpp:150:8:150:8 | destructor field destruction of vs | TAINT |
| vector.cpp:150:8:150:8 | this | vector.cpp:150:8:150:8 | constructor init of field vs [pre-this] | |
| vector.cpp:158:19:158:22 | {...} | vector.cpp:160:8:160:9 | aa | |
| vector.cpp:158:19:158:22 | {...} | vector.cpp:161:3:161:4 | aa | |
| vector.cpp:158:21:158:21 | 0 | vector.cpp:158:21:158:21 | {...} | TAINT |
| vector.cpp:158:21:158:21 | {...} | vector.cpp:158:19:158:22 | {...} | TAINT |
| vector.cpp:160:8:160:9 | aa | vector.cpp:160:8:160:12 | access to array | TAINT |
| vector.cpp:160:8:160:12 | access to array | vector.cpp:160:8:160:15 | access to array | TAINT |
| vector.cpp:160:11:160:11 | 0 | vector.cpp:160:8:160:12 | access to array | TAINT |
| vector.cpp:160:14:160:14 | 0 | vector.cpp:160:8:160:15 | access to array | TAINT |
| vector.cpp:161:3:161:4 | aa | vector.cpp:161:3:161:7 | access to array | TAINT |
| vector.cpp:161:3:161:7 | access to array | vector.cpp:161:3:161:10 | access to array | TAINT |
| vector.cpp:161:6:161:6 | 0 | vector.cpp:161:3:161:7 | access to array | TAINT |
| vector.cpp:161:9:161:9 | 0 | vector.cpp:161:3:161:10 | access to array | TAINT |
| vector.cpp:161:14:161:19 | call to source | vector.cpp:161:3:161:21 | ... = ... | |
| vector.cpp:162:8:162:9 | aa | vector.cpp:162:8:162:12 | access to array | TAINT |
| vector.cpp:162:8:162:12 | access to array | vector.cpp:162:8:162:15 | access to array | TAINT |
| vector.cpp:162:11:162:11 | 0 | vector.cpp:162:8:162:12 | access to array | TAINT |
| vector.cpp:162:14:162:14 | 0 | vector.cpp:162:8:162:15 | access to array | TAINT |
| vector.cpp:166:37:166:39 | call to vector | vector.cpp:168:3:168:4 | bb | |
| vector.cpp:166:37:166:39 | call to vector | vector.cpp:169:8:169:9 | bb | |
| vector.cpp:166:37:166:39 | call to vector | vector.cpp:170:3:170:4 | bb | |
| vector.cpp:166:37:166:39 | call to vector | vector.cpp:171:8:171:9 | bb | |
| vector.cpp:166:37:166:39 | call to vector | vector.cpp:172:2:172:2 | bb | |
| vector.cpp:168:3:168:4 | bb | vector.cpp:168:5:168:5 | call to operator[] | TAINT |
| vector.cpp:168:3:168:4 | ref arg bb | vector.cpp:169:8:169:9 | bb | |
| vector.cpp:168:3:168:4 | ref arg bb | vector.cpp:170:3:170:4 | bb | |
| vector.cpp:168:3:168:4 | ref arg bb | vector.cpp:171:8:171:9 | bb | |
| vector.cpp:168:3:168:4 | ref arg bb | vector.cpp:172:2:172:2 | bb | |
| vector.cpp:168:5:168:5 | ref arg call to operator[] | vector.cpp:168:3:168:4 | ref arg bb | TAINT |
| vector.cpp:168:19:168:19 | 0 | vector.cpp:168:5:168:5 | ref arg call to operator[] | TAINT |
| vector.cpp:169:8:169:9 | bb | vector.cpp:169:10:169:10 | call to operator[] | TAINT |
| vector.cpp:169:8:169:9 | ref arg bb | vector.cpp:170:3:170:4 | bb | |
| vector.cpp:169:8:169:9 | ref arg bb | vector.cpp:171:8:171:9 | bb | |
| vector.cpp:169:8:169:9 | ref arg bb | vector.cpp:172:2:172:2 | bb | |
| vector.cpp:169:10:169:10 | call to operator[] | vector.cpp:169:13:169:13 | call to operator[] | TAINT |
| vector.cpp:169:10:169:10 | ref arg call to operator[] | vector.cpp:169:8:169:9 | ref arg bb | TAINT |
| vector.cpp:170:3:170:4 | bb | vector.cpp:170:5:170:5 | call to operator[] | TAINT |
| vector.cpp:170:3:170:4 | ref arg bb | vector.cpp:171:8:171:9 | bb | |
| vector.cpp:170:3:170:4 | ref arg bb | vector.cpp:172:2:172:2 | bb | |
| vector.cpp:170:3:170:21 | ... = ... | vector.cpp:170:8:170:8 | call to operator[] [post update] | |
| vector.cpp:170:5:170:5 | call to operator[] | vector.cpp:170:8:170:8 | call to operator[] | TAINT |
| vector.cpp:170:5:170:5 | ref arg call to operator[] | vector.cpp:170:3:170:4 | ref arg bb | TAINT |
| vector.cpp:170:8:170:8 | call to operator[] [post update] | vector.cpp:170:5:170:5 | ref arg call to operator[] | TAINT |
| vector.cpp:170:14:170:19 | call to source | vector.cpp:170:3:170:21 | ... = ... | |
| vector.cpp:171:8:171:9 | bb | vector.cpp:171:10:171:10 | call to operator[] | TAINT |
| vector.cpp:171:8:171:9 | ref arg bb | vector.cpp:172:2:172:2 | bb | |
| vector.cpp:171:10:171:10 | call to operator[] | vector.cpp:171:13:171:13 | call to operator[] | TAINT |
| vector.cpp:171:10:171:10 | ref arg call to operator[] | vector.cpp:171:8:171:9 | ref arg bb | TAINT |
| vector.cpp:175:20:175:21 | call to vector | vector.cpp:175:20:175:21 | {...} | TAINT |
| vector.cpp:175:20:175:21 | {...} | vector.cpp:177:3:177:4 | cc | |
| vector.cpp:175:20:175:21 | {...} | vector.cpp:178:8:178:9 | cc | |
| vector.cpp:175:20:175:21 | {...} | vector.cpp:179:3:179:4 | cc | |
| vector.cpp:175:20:175:21 | {...} | vector.cpp:180:8:180:9 | cc | |
| vector.cpp:175:20:175:21 | {...} | vector.cpp:181:2:181:2 | cc | |
| vector.cpp:177:3:177:4 | cc | vector.cpp:177:3:177:7 | access to array | TAINT |
| vector.cpp:177:3:177:7 | ref arg access to array | vector.cpp:177:3:177:4 | cc [inner post update] | |
| vector.cpp:177:3:177:7 | ref arg access to array | vector.cpp:178:8:178:9 | cc | |
| vector.cpp:177:3:177:7 | ref arg access to array | vector.cpp:179:3:179:4 | cc | |
| vector.cpp:177:3:177:7 | ref arg access to array | vector.cpp:180:8:180:9 | cc | |
| vector.cpp:177:3:177:7 | ref arg access to array | vector.cpp:181:2:181:2 | cc | |
| vector.cpp:177:6:177:6 | 0 | vector.cpp:177:3:177:7 | access to array | TAINT |
| vector.cpp:177:19:177:19 | 0 | vector.cpp:177:3:177:7 | ref arg access to array | TAINT |
| vector.cpp:178:8:178:9 | cc | vector.cpp:178:8:178:12 | access to array | TAINT |
| vector.cpp:178:8:178:12 | access to array | vector.cpp:178:13:178:13 | call to operator[] | TAINT |
| vector.cpp:178:8:178:12 | ref arg access to array | vector.cpp:178:8:178:9 | cc [inner post update] | |
| vector.cpp:178:8:178:12 | ref arg access to array | vector.cpp:179:3:179:4 | cc | |
| vector.cpp:178:8:178:12 | ref arg access to array | vector.cpp:180:8:180:9 | cc | |
| vector.cpp:178:8:178:12 | ref arg access to array | vector.cpp:181:2:181:2 | cc | |
| vector.cpp:178:11:178:11 | 0 | vector.cpp:178:8:178:12 | access to array | TAINT |
| vector.cpp:179:3:179:4 | cc | vector.cpp:179:3:179:7 | access to array | TAINT |
| vector.cpp:179:3:179:7 | access to array | vector.cpp:179:8:179:8 | call to operator[] | TAINT |
| vector.cpp:179:3:179:7 | ref arg access to array | vector.cpp:179:3:179:4 | cc [inner post update] | |
| vector.cpp:179:3:179:7 | ref arg access to array | vector.cpp:180:8:180:9 | cc | |
| vector.cpp:179:3:179:7 | ref arg access to array | vector.cpp:181:2:181:2 | cc | |
| vector.cpp:179:3:179:21 | ... = ... | vector.cpp:179:8:179:8 | call to operator[] [post update] | |
| vector.cpp:179:6:179:6 | 0 | vector.cpp:179:3:179:7 | access to array | TAINT |
| vector.cpp:179:8:179:8 | call to operator[] [post update] | vector.cpp:179:3:179:7 | ref arg access to array | TAINT |
| vector.cpp:179:14:179:19 | call to source | vector.cpp:179:3:179:21 | ... = ... | |
| vector.cpp:180:8:180:9 | cc | vector.cpp:180:8:180:12 | access to array | TAINT |
| vector.cpp:180:8:180:12 | access to array | vector.cpp:180:13:180:13 | call to operator[] | TAINT |
| vector.cpp:180:8:180:12 | ref arg access to array | vector.cpp:180:8:180:9 | cc [inner post update] | |
| vector.cpp:180:8:180:12 | ref arg access to array | vector.cpp:181:2:181:2 | cc | |
| vector.cpp:180:11:180:11 | 0 | vector.cpp:180:8:180:12 | access to array | TAINT |
| vector.cpp:184:23:184:24 | call to vector | vector.cpp:187:3:187:4 | dd | |
| vector.cpp:184:23:184:24 | call to vector | vector.cpp:188:8:188:9 | dd | |
| vector.cpp:184:23:184:24 | call to vector | vector.cpp:189:8:189:9 | dd | |
| vector.cpp:184:23:184:24 | call to vector | vector.cpp:190:3:190:4 | dd | |
| vector.cpp:184:23:184:24 | call to vector | vector.cpp:191:8:191:9 | dd | |
| vector.cpp:184:23:184:24 | call to vector | vector.cpp:192:8:192:9 | dd | |
| vector.cpp:184:23:184:24 | call to vector | vector.cpp:193:2:193:2 | dd | |
| vector.cpp:185:14:185:20 | {...} | vector.cpp:187:16:187:17 | mp | |
| vector.cpp:187:3:187:4 | ref arg dd | vector.cpp:188:8:188:9 | dd | |
| vector.cpp:187:3:187:4 | ref arg dd | vector.cpp:189:8:189:9 | dd | |
| vector.cpp:187:3:187:4 | ref arg dd | vector.cpp:190:3:190:4 | dd | |
| vector.cpp:187:3:187:4 | ref arg dd | vector.cpp:191:8:191:9 | dd | |
| vector.cpp:187:3:187:4 | ref arg dd | vector.cpp:192:8:192:9 | dd | |
| vector.cpp:187:3:187:4 | ref arg dd | vector.cpp:193:2:193:2 | dd | |
| vector.cpp:187:16:187:17 | mp | vector.cpp:187:3:187:4 | ref arg dd | TAINT |
| vector.cpp:188:8:188:9 | dd | vector.cpp:188:10:188:10 | call to operator[] | TAINT |
| vector.cpp:188:8:188:9 | ref arg dd | vector.cpp:189:8:189:9 | dd | |
| vector.cpp:188:8:188:9 | ref arg dd | vector.cpp:190:3:190:4 | dd | |
| vector.cpp:188:8:188:9 | ref arg dd | vector.cpp:191:8:191:9 | dd | |
| vector.cpp:188:8:188:9 | ref arg dd | vector.cpp:192:8:192:9 | dd | |
| vector.cpp:188:8:188:9 | ref arg dd | vector.cpp:193:2:193:2 | dd | |
| vector.cpp:189:8:189:9 | dd | vector.cpp:189:10:189:10 | call to operator[] | TAINT |
| vector.cpp:189:8:189:9 | ref arg dd | vector.cpp:190:3:190:4 | dd | |
| vector.cpp:189:8:189:9 | ref arg dd | vector.cpp:191:8:191:9 | dd | |
| vector.cpp:189:8:189:9 | ref arg dd | vector.cpp:192:8:192:9 | dd | |
| vector.cpp:189:8:189:9 | ref arg dd | vector.cpp:193:2:193:2 | dd | |
| vector.cpp:190:3:190:4 | dd | vector.cpp:190:5:190:5 | call to operator[] | TAINT |
| vector.cpp:190:3:190:4 | ref arg dd | vector.cpp:191:8:191:9 | dd | |
| vector.cpp:190:3:190:4 | ref arg dd | vector.cpp:192:8:192:9 | dd | |
| vector.cpp:190:3:190:4 | ref arg dd | vector.cpp:193:2:193:2 | dd | |
| vector.cpp:190:3:190:20 | ... = ... | vector.cpp:190:9:190:9 | a [post update] | |
| vector.cpp:190:5:190:5 | call to operator[] [post update] | vector.cpp:190:3:190:4 | ref arg dd | TAINT |
| vector.cpp:190:13:190:18 | call to source | vector.cpp:190:3:190:20 | ... = ... | |
| vector.cpp:191:8:191:9 | dd | vector.cpp:191:10:191:10 | call to operator[] | TAINT |
| vector.cpp:191:8:191:9 | ref arg dd | vector.cpp:192:8:192:9 | dd | |
| vector.cpp:191:8:191:9 | ref arg dd | vector.cpp:193:2:193:2 | dd | |
| vector.cpp:192:8:192:9 | dd | vector.cpp:192:10:192:10 | call to operator[] | TAINT |
| vector.cpp:192:8:192:9 | ref arg dd | vector.cpp:193:2:193:2 | dd | |
| vector.cpp:196:21:196:22 | call to MyVectorContainer | vector.cpp:198:3:198:4 | ee | |
| vector.cpp:196:21:196:22 | call to MyVectorContainer | vector.cpp:199:8:199:9 | ee | |
| vector.cpp:196:21:196:22 | call to MyVectorContainer | vector.cpp:200:3:200:4 | ee | |
| vector.cpp:196:21:196:22 | call to MyVectorContainer | vector.cpp:201:8:201:9 | ee | |
| vector.cpp:196:21:196:22 | call to MyVectorContainer | vector.cpp:202:2:202:2 | ee | |
| vector.cpp:198:3:198:4 | ee [post update] | vector.cpp:199:8:199:9 | ee | |
| vector.cpp:198:3:198:4 | ee [post update] | vector.cpp:200:3:200:4 | ee | |
| vector.cpp:198:3:198:4 | ee [post update] | vector.cpp:201:8:201:9 | ee | |
| vector.cpp:198:3:198:4 | ee [post update] | vector.cpp:202:2:202:2 | ee | |
| vector.cpp:198:19:198:19 | 0 | vector.cpp:198:6:198:7 | ref arg vs | TAINT |
| vector.cpp:199:8:199:9 | ee [post update] | vector.cpp:200:3:200:4 | ee | |
| vector.cpp:199:8:199:9 | ee [post update] | vector.cpp:201:8:201:9 | ee | |
| vector.cpp:199:8:199:9 | ee [post update] | vector.cpp:202:2:202:2 | ee | |
| vector.cpp:199:11:199:12 | vs | vector.cpp:199:13:199:13 | call to operator[] | TAINT |
| vector.cpp:200:3:200:4 | ee [post update] | vector.cpp:201:8:201:9 | ee | |
| vector.cpp:200:3:200:4 | ee [post update] | vector.cpp:202:2:202:2 | ee | |
| vector.cpp:200:3:200:21 | ... = ... | vector.cpp:200:8:200:8 | call to operator[] [post update] | |
| vector.cpp:200:6:200:7 | vs | vector.cpp:200:8:200:8 | call to operator[] | TAINT |
| vector.cpp:200:8:200:8 | call to operator[] [post update] | vector.cpp:200:6:200:7 | ref arg vs | TAINT |
| vector.cpp:200:14:200:19 | call to source | vector.cpp:200:3:200:21 | ... = ... | |
| vector.cpp:201:8:201:9 | ee [post update] | vector.cpp:202:2:202:2 | ee | |
| vector.cpp:201:11:201:12 | vs | vector.cpp:201:13:201:13 | call to operator[] | TAINT |
| vector.cpp:205:34:205:35 | call to vector | vector.cpp:209:3:209:4 | ff | |
| vector.cpp:205:34:205:35 | call to vector | vector.cpp:210:8:210:9 | ff | |
| vector.cpp:205:34:205:35 | call to vector | vector.cpp:211:3:211:4 | ff | |
| vector.cpp:205:34:205:35 | call to vector | vector.cpp:212:8:212:9 | ff | |
| vector.cpp:205:34:205:35 | call to vector | vector.cpp:213:2:213:2 | ff | |
| vector.cpp:206:21:206:23 | call to MyVectorContainer | vector.cpp:208:3:208:5 | mvc | |
| vector.cpp:206:21:206:23 | call to MyVectorContainer | vector.cpp:209:16:209:18 | mvc | |
| vector.cpp:206:21:206:23 | call to MyVectorContainer | vector.cpp:213:2:213:2 | mvc | |
| vector.cpp:208:3:208:5 | mvc [post update] | vector.cpp:209:16:209:18 | mvc | |
| vector.cpp:208:3:208:5 | mvc [post update] | vector.cpp:213:2:213:2 | mvc | |
| vector.cpp:208:20:208:20 | 0 | vector.cpp:208:7:208:8 | ref arg vs | TAINT |
| vector.cpp:209:3:209:4 | ref arg ff | vector.cpp:210:8:210:9 | ff | |
| vector.cpp:209:3:209:4 | ref arg ff | vector.cpp:211:3:211:4 | ff | |
| vector.cpp:209:3:209:4 | ref arg ff | vector.cpp:212:8:212:9 | ff | |
| vector.cpp:209:3:209:4 | ref arg ff | vector.cpp:213:2:213:2 | ff | |
| vector.cpp:209:16:209:18 | mvc | vector.cpp:209:3:209:4 | ref arg ff | TAINT |
| vector.cpp:210:8:210:9 | ff | vector.cpp:210:10:210:10 | call to operator[] | TAINT |
| vector.cpp:210:8:210:9 | ref arg ff | vector.cpp:211:3:211:4 | ff | |
| vector.cpp:210:8:210:9 | ref arg ff | vector.cpp:212:8:212:9 | ff | |
| vector.cpp:210:8:210:9 | ref arg ff | vector.cpp:213:2:213:2 | ff | |
| vector.cpp:210:10:210:10 | call to operator[] [post update] | vector.cpp:210:8:210:9 | ref arg ff | TAINT |
| vector.cpp:210:14:210:15 | vs | vector.cpp:210:16:210:16 | call to operator[] | TAINT |
| vector.cpp:211:3:211:4 | ff | vector.cpp:211:5:211:5 | call to operator[] | TAINT |
| vector.cpp:211:3:211:4 | ref arg ff | vector.cpp:212:8:212:9 | ff | |
| vector.cpp:211:3:211:4 | ref arg ff | vector.cpp:213:2:213:2 | ff | |
| vector.cpp:211:3:211:24 | ... = ... | vector.cpp:211:11:211:11 | call to operator[] [post update] | |
| vector.cpp:211:5:211:5 | call to operator[] [post update] | vector.cpp:211:3:211:4 | ref arg ff | TAINT |
| vector.cpp:211:9:211:10 | vs | vector.cpp:211:11:211:11 | call to operator[] | TAINT |
| vector.cpp:211:11:211:11 | call to operator[] [post update] | vector.cpp:211:9:211:10 | ref arg vs | TAINT |
| vector.cpp:211:17:211:22 | call to source | vector.cpp:211:3:211:24 | ... = ... | |
| vector.cpp:212:8:212:9 | ff | vector.cpp:212:10:212:10 | call to operator[] | TAINT |
| vector.cpp:212:8:212:9 | ref arg ff | vector.cpp:213:2:213:2 | ff | |
| vector.cpp:212:10:212:10 | call to operator[] [post update] | vector.cpp:212:8:212:9 | ref arg ff | TAINT |
| vector.cpp:212:14:212:15 | vs | vector.cpp:212:16:212:16 | call to operator[] | TAINT |
| vector.cpp:235:19:235:20 | call to vector | vector.cpp:237:2:237:3 | v1 | |
| vector.cpp:235:19:235:20 | call to vector | vector.cpp:241:7:241:8 | v1 | |
| vector.cpp:235:19:235:20 | call to vector | vector.cpp:249:13:249:14 | v1 | |
| vector.cpp:235:19:235:20 | call to vector | vector.cpp:249:25:249:26 | v1 | |
| vector.cpp:235:19:235:20 | call to vector | vector.cpp:277:1:277:1 | v1 | |
| vector.cpp:235:23:235:24 | call to vector | vector.cpp:238:2:238:3 | v2 | |
| vector.cpp:235:23:235:24 | call to vector | vector.cpp:242:7:242:8 | v2 | |
| vector.cpp:235:23:235:24 | call to vector | vector.cpp:277:1:277:1 | v2 | |
| vector.cpp:235:27:235:28 | call to vector | vector.cpp:239:2:239:3 | v3 | |
| vector.cpp:235:27:235:28 | call to vector | vector.cpp:243:7:243:8 | v3 | |
| vector.cpp:235:27:235:28 | call to vector | vector.cpp:250:13:250:14 | v3 | |
| vector.cpp:235:27:235:28 | call to vector | vector.cpp:250:25:250:26 | v3 | |
| vector.cpp:235:27:235:28 | call to vector | vector.cpp:251:8:251:9 | v3 | |
| vector.cpp:235:27:235:28 | call to vector | vector.cpp:277:1:277:1 | v3 | |
| vector.cpp:237:2:237:3 | ref arg v1 | vector.cpp:241:7:241:8 | v1 | |
| vector.cpp:237:2:237:3 | ref arg v1 | vector.cpp:249:13:249:14 | v1 | |
| vector.cpp:237:2:237:3 | ref arg v1 | vector.cpp:249:25:249:26 | v1 | |
| vector.cpp:237:2:237:3 | ref arg v1 | vector.cpp:277:1:277:1 | v1 | |
| vector.cpp:237:17:237:17 | 0 | vector.cpp:237:2:237:3 | ref arg v1 | TAINT |
| vector.cpp:238:2:238:3 | ref arg v2 | vector.cpp:242:7:242:8 | v2 | |
| vector.cpp:238:2:238:3 | ref arg v2 | vector.cpp:277:1:277:1 | v2 | |
| vector.cpp:238:17:238:30 | call to source | vector.cpp:238:2:238:3 | ref arg v2 | TAINT |
| vector.cpp:239:2:239:3 | ref arg v3 | vector.cpp:243:7:243:8 | v3 | |
| vector.cpp:239:2:239:3 | ref arg v3 | vector.cpp:250:13:250:14 | v3 | |
| vector.cpp:239:2:239:3 | ref arg v3 | vector.cpp:250:25:250:26 | v3 | |
| vector.cpp:239:2:239:3 | ref arg v3 | vector.cpp:251:8:251:9 | v3 | |
| vector.cpp:239:2:239:3 | ref arg v3 | vector.cpp:277:1:277:1 | v3 | |
| vector.cpp:239:15:239:20 | call to source | vector.cpp:239:2:239:3 | ref arg v3 | TAINT |
| vector.cpp:241:7:241:8 | ref arg v1 | vector.cpp:249:13:249:14 | v1 | |
| vector.cpp:241:7:241:8 | ref arg v1 | vector.cpp:249:25:249:26 | v1 | |
| vector.cpp:241:7:241:8 | ref arg v1 | vector.cpp:277:1:277:1 | v1 | |
| vector.cpp:242:7:242:8 | ref arg v2 | vector.cpp:277:1:277:1 | v2 | |
| vector.cpp:243:7:243:8 | ref arg v3 | vector.cpp:250:13:250:14 | v3 | |
| vector.cpp:243:7:243:8 | ref arg v3 | vector.cpp:250:25:250:26 | v3 | |
| vector.cpp:243:7:243:8 | ref arg v3 | vector.cpp:251:8:251:9 | v3 | |
| vector.cpp:243:7:243:8 | ref arg v3 | vector.cpp:277:1:277:1 | v3 | |
| vector.cpp:246:20:246:21 | call to vector | vector.cpp:249:3:249:4 | v4 | |
| vector.cpp:246:20:246:21 | call to vector | vector.cpp:257:8:257:9 | v4 | |
| vector.cpp:246:20:246:21 | call to vector | vector.cpp:262:2:262:2 | v4 | |
| vector.cpp:246:24:246:25 | call to vector | vector.cpp:250:3:250:4 | v5 | |
| vector.cpp:246:24:246:25 | call to vector | vector.cpp:258:8:258:9 | v5 | |
| vector.cpp:246:24:246:25 | call to vector | vector.cpp:262:2:262:2 | v5 | |
| vector.cpp:246:28:246:29 | call to vector | vector.cpp:255:3:255:4 | v6 | |
| vector.cpp:246:28:246:29 | call to vector | vector.cpp:261:8:261:9 | v6 | |
| vector.cpp:246:28:246:29 | call to vector | vector.cpp:262:2:262:2 | v6 | |
| vector.cpp:249:3:249:4 | ref arg v4 | vector.cpp:257:8:257:9 | v4 | |
| vector.cpp:249:3:249:4 | ref arg v4 | vector.cpp:262:2:262:2 | v4 | |
| vector.cpp:249:13:249:14 | ref arg v1 | vector.cpp:249:25:249:26 | v1 | |
| vector.cpp:249:13:249:14 | ref arg v1 | vector.cpp:277:1:277:1 | v1 | |
| vector.cpp:249:25:249:26 | ref arg v1 | vector.cpp:277:1:277:1 | v1 | |
| vector.cpp:250:3:250:4 | ref arg v5 | vector.cpp:258:8:258:9 | v5 | |
| vector.cpp:250:3:250:4 | ref arg v5 | vector.cpp:262:2:262:2 | v5 | |
| vector.cpp:250:13:250:14 | ref arg v3 | vector.cpp:250:25:250:26 | v3 | |
| vector.cpp:250:13:250:14 | ref arg v3 | vector.cpp:251:8:251:9 | v3 | |
| vector.cpp:250:13:250:14 | ref arg v3 | vector.cpp:277:1:277:1 | v3 | |
| vector.cpp:250:25:250:26 | ref arg v3 | vector.cpp:251:8:251:9 | v3 | |
| vector.cpp:250:25:250:26 | ref arg v3 | vector.cpp:277:1:277:1 | v3 | |
| vector.cpp:251:8:251:9 | ref arg v3 | vector.cpp:277:1:277:1 | v3 | |
| vector.cpp:251:11:251:15 | call to begin | vector.cpp:251:3:251:17 | ... = ... | |
| vector.cpp:251:11:251:15 | call to begin | vector.cpp:252:3:252:4 | i1 | |
| vector.cpp:251:11:251:15 | call to begin | vector.cpp:253:8:253:9 | i1 | |
| vector.cpp:251:11:251:15 | call to begin | vector.cpp:255:13:255:14 | i1 | |
| vector.cpp:251:11:251:15 | call to begin | vector.cpp:259:8:259:9 | i1 | |
| vector.cpp:252:3:252:4 | ref arg i1 | vector.cpp:253:8:253:9 | i1 | |
| vector.cpp:252:3:252:4 | ref arg i1 | vector.cpp:255:13:255:14 | i1 | |
| vector.cpp:252:3:252:4 | ref arg i1 | vector.cpp:259:8:259:9 | i1 | |
| vector.cpp:253:8:253:9 | i1 | vector.cpp:253:3:253:9 | ... = ... | |
| vector.cpp:253:8:253:9 | i1 | vector.cpp:254:3:254:4 | i2 | |
| vector.cpp:253:8:253:9 | i1 | vector.cpp:255:17:255:18 | i2 | |
| vector.cpp:253:8:253:9 | i1 | vector.cpp:260:8:260:9 | i2 | |
| vector.cpp:254:3:254:4 | ref arg i2 | vector.cpp:255:17:255:18 | i2 | |
| vector.cpp:254:3:254:4 | ref arg i2 | vector.cpp:260:8:260:9 | i2 | |
| vector.cpp:255:3:255:4 | ref arg v6 | vector.cpp:261:8:261:9 | v6 | |
| vector.cpp:255:3:255:4 | ref arg v6 | vector.cpp:262:2:262:2 | v6 | |
| vector.cpp:257:8:257:9 | ref arg v4 | vector.cpp:262:2:262:2 | v4 | |
| vector.cpp:258:8:258:9 | ref arg v5 | vector.cpp:262:2:262:2 | v5 | |
| vector.cpp:261:8:261:9 | ref arg v6 | vector.cpp:262:2:262:2 | v6 | |
| vector.cpp:265:22:265:23 | call to vector | vector.cpp:269:3:269:4 | v7 | |
| vector.cpp:265:22:265:23 | call to vector | vector.cpp:273:8:273:9 | v7 | |
| vector.cpp:265:22:265:23 | call to vector | vector.cpp:276:2:276:2 | v7 | |
| vector.cpp:266:24:266:25 | call to vector | vector.cpp:270:3:270:4 | v8 | |
| vector.cpp:266:24:266:25 | call to vector | vector.cpp:274:8:274:9 | v8 | |
| vector.cpp:266:24:266:25 | call to vector | vector.cpp:276:2:276:2 | v8 | |
| vector.cpp:267:28:267:29 | call to vector | vector.cpp:271:3:271:4 | v9 | |
| vector.cpp:267:28:267:29 | call to vector | vector.cpp:275:8:275:9 | v9 | |
| vector.cpp:267:28:267:29 | call to vector | vector.cpp:276:2:276:2 | v9 | |
| vector.cpp:269:3:269:4 | ref arg v7 | vector.cpp:273:8:273:9 | v7 | |
| vector.cpp:269:3:269:4 | ref arg v7 | vector.cpp:276:2:276:2 | v7 | |
| vector.cpp:269:18:269:31 | call to source | vector.cpp:269:3:269:4 | ref arg v7 | TAINT |
| vector.cpp:270:3:270:4 | ref arg v8 | vector.cpp:274:8:274:9 | v8 | |
| vector.cpp:270:3:270:4 | ref arg v8 | vector.cpp:276:2:276:2 | v8 | |
| vector.cpp:270:18:270:35 | call to source | vector.cpp:270:3:270:4 | ref arg v8 | TAINT |
| vector.cpp:271:3:271:4 | ref arg v9 | vector.cpp:275:8:275:9 | v9 | |
| vector.cpp:271:3:271:4 | ref arg v9 | vector.cpp:276:2:276:2 | v9 | |
| vector.cpp:271:18:271:34 | call to source | vector.cpp:271:3:271:4 | ref arg v9 | TAINT |
| vector.cpp:273:8:273:9 | ref arg v7 | vector.cpp:276:2:276:2 | v7 | |
| vector.cpp:274:8:274:9 | ref arg v8 | vector.cpp:276:2:276:2 | v8 | |
| vector.cpp:275:8:275:9 | ref arg v9 | vector.cpp:276:2:276:2 | v9 | |
| vector.cpp:282:19:282:20 | call to vector | vector.cpp:284:2:284:3 | v1 | |
| vector.cpp:282:19:282:20 | call to vector | vector.cpp:285:7:285:8 | v1 | |
| vector.cpp:282:19:282:20 | call to vector | vector.cpp:286:7:286:8 | v1 | |
| vector.cpp:282:19:282:20 | call to vector | vector.cpp:287:7:287:8 | v1 | |
| vector.cpp:282:19:282:20 | call to vector | vector.cpp:293:1:293:1 | v1 | |
| vector.cpp:282:23:282:24 | call to vector | vector.cpp:289:4:289:5 | v2 | |
| vector.cpp:282:23:282:24 | call to vector | vector.cpp:290:7:290:8 | v2 | |
| vector.cpp:282:23:282:24 | call to vector | vector.cpp:291:7:291:8 | v2 | |
| vector.cpp:282:23:282:24 | call to vector | vector.cpp:292:7:292:8 | v2 | |
| vector.cpp:282:23:282:24 | call to vector | vector.cpp:293:1:293:1 | v2 | |
| vector.cpp:284:2:284:3 | ref arg v1 | vector.cpp:285:7:285:8 | v1 | |
| vector.cpp:284:2:284:3 | ref arg v1 | vector.cpp:286:7:286:8 | v1 | |
| vector.cpp:284:2:284:3 | ref arg v1 | vector.cpp:287:7:287:8 | v1 | |
| vector.cpp:284:2:284:3 | ref arg v1 | vector.cpp:293:1:293:1 | v1 | |
| vector.cpp:284:15:284:20 | call to source | vector.cpp:284:2:284:3 | ref arg v1 | TAINT |
| vector.cpp:285:7:285:8 | ref arg v1 | vector.cpp:286:7:286:8 | v1 | |
| vector.cpp:285:7:285:8 | ref arg v1 | vector.cpp:287:7:287:8 | v1 | |
| vector.cpp:285:7:285:8 | ref arg v1 | vector.cpp:293:1:293:1 | v1 | |
| vector.cpp:286:7:286:8 | ref arg v1 | vector.cpp:287:7:287:8 | v1 | |
| vector.cpp:286:7:286:8 | ref arg v1 | vector.cpp:293:1:293:1 | v1 | |
| vector.cpp:286:7:286:8 | v1 | vector.cpp:286:10:286:13 | call to data | TAINT |
| vector.cpp:286:10:286:13 | ref arg call to data | vector.cpp:286:7:286:8 | ref arg v1 | TAINT |
| vector.cpp:287:7:287:8 | ref arg v1 | vector.cpp:293:1:293:1 | v1 | |
| vector.cpp:287:7:287:8 | v1 | vector.cpp:287:10:287:13 | call to data | TAINT |
| vector.cpp:287:10:287:13 | call to data | vector.cpp:287:7:287:18 | access to array | TAINT |
| vector.cpp:287:17:287:17 | 2 | vector.cpp:287:7:287:18 | access to array | TAINT |
| vector.cpp:289:2:289:13 | * ... [post update] | vector.cpp:289:7:289:10 | call to data [inner post update] | |
| vector.cpp:289:2:289:32 | ... = ... | vector.cpp:289:2:289:13 | * ... [post update] | |
| vector.cpp:289:4:289:5 | ref arg v2 | vector.cpp:290:7:290:8 | v2 | |
| vector.cpp:289:4:289:5 | ref arg v2 | vector.cpp:291:7:291:8 | v2 | |
| vector.cpp:289:4:289:5 | ref arg v2 | vector.cpp:292:7:292:8 | v2 | |
| vector.cpp:289:4:289:5 | ref arg v2 | vector.cpp:293:1:293:1 | v2 | |
| vector.cpp:289:4:289:5 | v2 | vector.cpp:289:7:289:10 | call to data | TAINT |
| vector.cpp:289:7:289:10 | call to data | vector.cpp:289:2:289:13 | * ... | TAINT |
| vector.cpp:289:7:289:10 | call to data [inner post update] | vector.cpp:289:4:289:5 | ref arg v2 | TAINT |
| vector.cpp:289:17:289:30 | call to source | vector.cpp:289:2:289:32 | ... = ... | |
| vector.cpp:290:7:290:8 | ref arg v2 | vector.cpp:291:7:291:8 | v2 | |
| vector.cpp:290:7:290:8 | ref arg v2 | vector.cpp:292:7:292:8 | v2 | |
| vector.cpp:290:7:290:8 | ref arg v2 | vector.cpp:293:1:293:1 | v2 | |
| vector.cpp:291:7:291:8 | ref arg v2 | vector.cpp:292:7:292:8 | v2 | |
| vector.cpp:291:7:291:8 | ref arg v2 | vector.cpp:293:1:293:1 | v2 | |
| vector.cpp:291:7:291:8 | v2 | vector.cpp:291:10:291:13 | call to data | TAINT |
| vector.cpp:291:10:291:13 | ref arg call to data | vector.cpp:291:7:291:8 | ref arg v2 | TAINT |
| vector.cpp:292:7:292:8 | ref arg v2 | vector.cpp:293:1:293:1 | v2 | |
| vector.cpp:292:7:292:8 | v2 | vector.cpp:292:10:292:13 | call to data | TAINT |
| vector.cpp:292:10:292:13 | call to data | vector.cpp:292:7:292:18 | access to array | TAINT |
| vector.cpp:292:17:292:17 | 2 | vector.cpp:292:7:292:18 | access to array | TAINT |

Просмотреть файл

@ -11,12 +11,14 @@ namespace std
struct ptrdiff_t;
template <class iterator_category,
template <class Category,
class value_type,
class difference_type = ptrdiff_t,
class pointer_type = value_type*,
class reference_type = value_type&>
struct iterator {
typedef Category iterator_category;
iterator &operator++();
iterator operator++(int);
bool operator==(iterator other) const;
@ -38,6 +40,9 @@ namespace std
template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
class basic_string {
public:
using value_type = charT;
using reference = value_type&;
using const_reference = const value_type&;
typedef typename Allocator::size_type size_type;
static const size_type npos = -1;
@ -58,6 +63,10 @@ namespace std
const_iterator cbegin() const;
const_iterator cend() const;
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
const_reference at(size_type n) const;
reference at(size_type n);
template<class T> basic_string& operator+=(const T& t);
basic_string& operator+=(const charT* s);
basic_string& append(const basic_string& str);
@ -135,6 +144,10 @@ namespace std {
vector& operator=(const vector& x);
vector& operator=(vector&& x) noexcept/*(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value)*/;
template<class InputIterator, class IteratorCategory = typename InputIterator::iterator_category> void assign(InputIterator first, InputIterator last);
// use of `iterator_category` makes sure InputIterator is (probably) an iterator, and not an `int` or
// similar that should match a different overload (SFINAE).
void assign(size_type n, const T& u);
iterator begin() noexcept;
const_iterator begin() const noexcept;

Просмотреть файл

@ -321,3 +321,31 @@ void test_string_substr()
sink(a.substr(0, a.length()));
sink(b.substr(0, b.length())); // tainted
}
void test_string_at()
{
std::string a("123");
std::string b("123");
std::string c("123");
sink(a);
sink(b);
sink(c);
a[0] = ns_char::source();
b.at(0) = ns_char::source();
c[0] = a[0];
sink(a); // tainted
sink(b); // tainted
sink(c); // tainted
}
void test_string_data_more()
{
std::string str("123");
str.data()[1] = ns_char::source();
sink(str); // tainted
sink(str.data()); // tainted
}

Просмотреть файл

@ -1,3 +1,8 @@
| arrayassignment.cpp:33:7:33:9 | r_x | arrayassignment.cpp:29:8:29:13 | call to source |
| arrayassignment.cpp:57:10:57:12 | call to get | arrayassignment.cpp:54:9:54:14 | call to source |
| arrayassignment.cpp:67:10:67:12 | call to get | arrayassignment.cpp:64:13:64:18 | call to source |
| arrayassignment.cpp:101:7:101:18 | access to array | arrayassignment.cpp:99:17:99:22 | call to source |
| arrayassignment.cpp:135:7:135:10 | ref1 | arrayassignment.cpp:134:9:134:14 | call to source |
| copyableclass.cpp:40:8:40:9 | s1 | copyableclass.cpp:34:22:34:27 | call to source |
| copyableclass.cpp:41:8:41:9 | s2 | copyableclass.cpp:35:24:35:29 | call to source |
| copyableclass.cpp:42:8:42:9 | s3 | copyableclass.cpp:34:22:34:27 | call to source |
@ -91,6 +96,11 @@
| string.cpp:302:7:302:8 | s3 | string.cpp:290:17:290:22 | call to source |
| string.cpp:311:9:311:12 | call to data | string.cpp:308:16:308:21 | call to source |
| string.cpp:322:9:322:14 | call to substr | string.cpp:319:16:319:21 | call to source |
| string.cpp:339:7:339:7 | a | string.cpp:335:9:335:23 | call to source |
| string.cpp:340:7:340:7 | b | string.cpp:336:12:336:26 | call to source |
| string.cpp:341:7:341:7 | c | string.cpp:335:9:335:23 | call to source |
| string.cpp:349:7:349:9 | str | string.cpp:348:18:348:32 | call to source |
| string.cpp:350:11:350:14 | call to data | string.cpp:348:18:348:32 | 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 |
@ -200,9 +210,27 @@
| vector.cpp:20:8:20:8 | x | vector.cpp:16:43:16:49 | source1 |
| vector.cpp:28:8:28:8 | x | vector.cpp:16:43:16:49 | source1 |
| vector.cpp:33:8:33:8 | x | vector.cpp:16:43:16:49 | source1 |
| vector.cpp:52:7:52:8 | v2 | vector.cpp:51:10:51:15 | call to source |
| vector.cpp:53:9:53:9 | call to operator[] | vector.cpp:51:10:51:15 | call to source |
| vector.cpp:54:9:54:9 | call to operator[] | vector.cpp:51:10:51:15 | call to source |
| vector.cpp:55:9:55:9 | call to operator[] | vector.cpp:51:10:51:15 | call to source |
| vector.cpp:58:7:58:8 | v3 | vector.cpp:51:10:51:15 | call to source |
| vector.cpp:59:9:59:9 | call to operator[] | vector.cpp:51:10:51:15 | call to source |
| vector.cpp:60:9:60:9 | call to operator[] | vector.cpp:51:10:51:15 | call to source |
| vector.cpp:61:9:61:9 | call to operator[] | vector.cpp:51:10:51:15 | call to source |
| vector.cpp:64:7:64:8 | v4 | vector.cpp:63:10:63:15 | call to source |
| vector.cpp:65:9:65:9 | call to operator[] | vector.cpp:63:10:63:15 | call to source |
| vector.cpp:66:9:66:9 | call to operator[] | vector.cpp:63:10:63:15 | call to source |
| vector.cpp:67:9:67:9 | call to operator[] | vector.cpp:63:10:63:15 | call to source |
| vector.cpp:70:7:70:8 | v5 | vector.cpp:69:15:69:20 | call to source |
| vector.cpp:71:10:71:14 | call to front | vector.cpp:69:15:69:20 | call to source |
| vector.cpp:72:10:72:13 | call to back | vector.cpp:69:15:69:20 | call to source |
| vector.cpp:75:7:75:8 | v6 | vector.cpp:74:17:74:22 | call to source |
| vector.cpp:76:7:76:18 | access to array | vector.cpp:74:17:74:22 | call to source |
| vector.cpp:97:7:97:8 | v9 | vector.cpp:96:13:96:18 | call to source |
| vector.cpp:98:10:98:11 | call to at | vector.cpp:96:13:96:18 | call to source |
| vector.cpp:99:10:99:11 | call to at | vector.cpp:96:13:96:18 | call to source |
| vector.cpp:100:10:100:11 | call to at | vector.cpp:96:13:96:18 | call to source |
| vector.cpp:109:7:109:8 | v1 | vector.cpp:106:15:106:20 | call to source |
| vector.cpp:112:7:112:8 | v4 | vector.cpp:107:15:107:20 | call to source |
| vector.cpp:117:7:117:8 | v1 | vector.cpp:106:15:106:20 | call to source |
@ -215,3 +243,17 @@
| vector.cpp:139:7:139:8 | v1 | vector.cpp:126:15:126:20 | call to source |
| vector.cpp:140:7:140:8 | v2 | vector.cpp:127:15:127:20 | call to source |
| vector.cpp:141:7:141:8 | v3 | vector.cpp:128:15:128:20 | call to source |
| vector.cpp:171:13:171:13 | call to operator[] | vector.cpp:170:14:170:19 | call to source |
| vector.cpp:180:13:180:13 | call to operator[] | vector.cpp:179:14:179:19 | call to source |
| vector.cpp:201:13:201:13 | call to operator[] | vector.cpp:200:14:200:19 | call to source |
| vector.cpp:242:7:242:8 | v2 | vector.cpp:238:17:238:30 | call to source |
| vector.cpp:243:7:243:8 | v3 | vector.cpp:239:15:239:20 | call to source |
| vector.cpp:273:8:273:9 | v7 | vector.cpp:269:18:269:31 | call to source |
| vector.cpp:274:8:274:9 | v8 | vector.cpp:270:18:270:35 | call to source |
| vector.cpp:275:8:275:9 | v9 | vector.cpp:271:18:271:34 | call to source |
| vector.cpp:285:7:285:8 | v1 | vector.cpp:284:15:284:20 | call to source |
| vector.cpp:286:10:286:13 | call to data | vector.cpp:284:15:284:20 | call to source |
| vector.cpp:287:7:287:18 | access to array | vector.cpp:284:15:284:20 | call to source |
| vector.cpp:290:7:290:8 | v2 | vector.cpp:289:17:289:30 | call to source |
| vector.cpp:291:10:291:13 | call to data | vector.cpp:289:17:289:30 | call to source |
| vector.cpp:292:7:292:18 | access to array | vector.cpp:289:17:289:30 | call to source |

Просмотреть файл

@ -1,3 +1,21 @@
| arrayassignment.cpp:16:7:16:7 | arrayassignment.cpp:14:9:14:14 | IR only |
| arrayassignment.cpp:17:7:17:10 | arrayassignment.cpp:14:9:14:14 | IR only |
| arrayassignment.cpp:18:7:18:11 | arrayassignment.cpp:14:9:14:14 | IR only |
| arrayassignment.cpp:19:7:19:9 | arrayassignment.cpp:14:9:14:14 | IR only |
| arrayassignment.cpp:31:7:31:7 | arrayassignment.cpp:29:8:29:13 | IR only |
| arrayassignment.cpp:32:7:32:10 | arrayassignment.cpp:29:8:29:13 | IR only |
| arrayassignment.cpp:34:7:34:10 | arrayassignment.cpp:29:8:29:13 | IR only |
| arrayassignment.cpp:56:7:56:8 | arrayassignment.cpp:54:9:54:14 | IR only |
| arrayassignment.cpp:57:10:57:12 | arrayassignment.cpp:54:9:54:14 | AST only |
| arrayassignment.cpp:57:10:57:15 | arrayassignment.cpp:54:9:54:14 | IR only |
| arrayassignment.cpp:66:7:66:8 | arrayassignment.cpp:64:13:64:18 | IR only |
| arrayassignment.cpp:67:10:67:12 | arrayassignment.cpp:64:13:64:18 | AST only |
| arrayassignment.cpp:67:10:67:15 | arrayassignment.cpp:64:13:64:18 | IR only |
| arrayassignment.cpp:136:7:136:13 | arrayassignment.cpp:134:9:134:14 | IR only |
| arrayassignment.cpp:140:7:140:11 | arrayassignment.cpp:139:10:139:15 | IR only |
| arrayassignment.cpp:141:7:141:13 | arrayassignment.cpp:139:10:139:15 | IR only |
| arrayassignment.cpp:145:7:145:13 | arrayassignment.cpp:144:12:144:17 | IR only |
| arrayassignment.cpp:146:7:146:13 | arrayassignment.cpp:144:12:144:17 | IR only |
| copyableclass.cpp:40:8:40:9 | copyableclass.cpp:34:22:34:27 | AST only |
| copyableclass.cpp:41:8:41:9 | copyableclass.cpp:35:24:35:29 | AST only |
| copyableclass.cpp:42:8:42:9 | copyableclass.cpp:34:22:34:27 | AST only |
@ -88,6 +106,11 @@
| string.cpp:302:7:302:8 | string.cpp:290:17:290:22 | AST only |
| string.cpp:311:9:311:12 | string.cpp:308:16:308:21 | AST only |
| string.cpp:322:9:322:14 | string.cpp:319:16:319:21 | AST only |
| string.cpp:339:7:339:7 | string.cpp:335:9:335:23 | AST only |
| string.cpp:340:7:340:7 | string.cpp:336:12:336:26 | AST only |
| string.cpp:341:7:341:7 | string.cpp:335:9:335:23 | AST only |
| string.cpp:349:7:349:9 | string.cpp:348:18:348:32 | AST only |
| string.cpp:350:11:350:14 | string.cpp:348:18:348:32 | 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 |
@ -135,9 +158,27 @@
| vector.cpp:20:8:20:8 | vector.cpp:16:43:16:49 | AST only |
| vector.cpp:28:8:28:8 | vector.cpp:16:43:16:49 | AST only |
| vector.cpp:33:8:33:8 | vector.cpp:16:43:16:49 | AST only |
| vector.cpp:52:7:52:8 | vector.cpp:51:10:51:15 | AST only |
| vector.cpp:53:9:53:9 | vector.cpp:51:10:51:15 | AST only |
| vector.cpp:54:9:54:9 | vector.cpp:51:10:51:15 | AST only |
| vector.cpp:55:9:55:9 | vector.cpp:51:10:51:15 | AST only |
| vector.cpp:58:7:58:8 | vector.cpp:51:10:51:15 | AST only |
| vector.cpp:59:9:59:9 | vector.cpp:51:10:51:15 | AST only |
| vector.cpp:60:9:60:9 | vector.cpp:51:10:51:15 | AST only |
| vector.cpp:61:9:61:9 | vector.cpp:51:10:51:15 | AST only |
| vector.cpp:64:7:64:8 | vector.cpp:63:10:63:15 | AST only |
| vector.cpp:65:9:65:9 | vector.cpp:63:10:63:15 | AST only |
| vector.cpp:66:9:66:9 | vector.cpp:63:10:63:15 | AST only |
| vector.cpp:67:9:67:9 | vector.cpp:63:10:63:15 | AST only |
| vector.cpp:70:7:70:8 | vector.cpp:69:15:69:20 | AST only |
| vector.cpp:71:10:71:14 | vector.cpp:69:15:69:20 | AST only |
| vector.cpp:72:10:72:13 | vector.cpp:69:15:69:20 | AST only |
| vector.cpp:75:7:75:8 | vector.cpp:74:17:74:22 | AST only |
| vector.cpp:76:7:76:18 | vector.cpp:74:17:74:22 | AST only |
| vector.cpp:97:7:97:8 | vector.cpp:96:13:96:18 | AST only |
| vector.cpp:98:10:98:11 | vector.cpp:96:13:96:18 | AST only |
| vector.cpp:99:10:99:11 | vector.cpp:96:13:96:18 | AST only |
| vector.cpp:100:10:100:11 | vector.cpp:96:13:96:18 | AST only |
| vector.cpp:109:7:109:8 | vector.cpp:106:15:106:20 | AST only |
| vector.cpp:112:7:112:8 | vector.cpp:107:15:107:20 | AST only |
| vector.cpp:117:7:117:8 | vector.cpp:106:15:106:20 | AST only |
@ -150,3 +191,18 @@
| vector.cpp:139:7:139:8 | vector.cpp:126:15:126:20 | AST only |
| vector.cpp:140:7:140:8 | vector.cpp:127:15:127:20 | AST only |
| vector.cpp:141:7:141:8 | vector.cpp:128:15:128:20 | AST only |
| vector.cpp:162:8:162:15 | vector.cpp:161:14:161:19 | IR only |
| vector.cpp:171:13:171:13 | vector.cpp:170:14:170:19 | AST only |
| vector.cpp:180:13:180:13 | vector.cpp:179:14:179:19 | AST only |
| vector.cpp:201:13:201:13 | vector.cpp:200:14:200:19 | AST only |
| vector.cpp:242:7:242:8 | vector.cpp:238:17:238:30 | AST only |
| vector.cpp:243:7:243:8 | vector.cpp:239:15:239:20 | AST only |
| vector.cpp:273:8:273:9 | vector.cpp:269:18:269:31 | AST only |
| vector.cpp:274:8:274:9 | vector.cpp:270:18:270:35 | AST only |
| vector.cpp:275:8:275:9 | vector.cpp:271:18:271:34 | AST only |
| vector.cpp:285:7:285:8 | vector.cpp:284:15:284:20 | AST only |
| vector.cpp:286:10:286:13 | vector.cpp:284:15:284:20 | AST only |
| vector.cpp:287:7:287:18 | vector.cpp:284:15:284:20 | AST only |
| vector.cpp:290:7:290:8 | vector.cpp:289:17:289:30 | AST only |
| vector.cpp:291:10:291:13 | vector.cpp:289:17:289:30 | AST only |
| vector.cpp:292:7:292:18 | vector.cpp:289:17:289:30 | AST only |

Просмотреть файл

@ -1,3 +1,22 @@
| arrayassignment.cpp:16:7:16:7 | x | arrayassignment.cpp:14:9:14:14 | call to source |
| arrayassignment.cpp:17:7:17:10 | * ... | arrayassignment.cpp:14:9:14:14 | call to source |
| arrayassignment.cpp:18:7:18:11 | * ... | arrayassignment.cpp:14:9:14:14 | call to source |
| arrayassignment.cpp:19:7:19:9 | (reference dereference) | arrayassignment.cpp:14:9:14:14 | call to source |
| arrayassignment.cpp:31:7:31:7 | x | arrayassignment.cpp:29:8:29:13 | call to source |
| arrayassignment.cpp:32:7:32:10 | * ... | arrayassignment.cpp:29:8:29:13 | call to source |
| arrayassignment.cpp:33:7:33:9 | (reference dereference) | arrayassignment.cpp:29:8:29:13 | call to source |
| arrayassignment.cpp:34:7:34:10 | (reference dereference) | arrayassignment.cpp:29:8:29:13 | call to source |
| arrayassignment.cpp:56:7:56:8 | mi | arrayassignment.cpp:54:9:54:14 | call to source |
| arrayassignment.cpp:57:10:57:15 | (reference dereference) | arrayassignment.cpp:54:9:54:14 | call to source |
| arrayassignment.cpp:66:7:66:8 | mi | arrayassignment.cpp:64:13:64:18 | call to source |
| arrayassignment.cpp:67:10:67:15 | (reference dereference) | arrayassignment.cpp:64:13:64:18 | call to source |
| arrayassignment.cpp:101:7:101:18 | access to array | arrayassignment.cpp:99:17:99:22 | call to source |
| arrayassignment.cpp:135:7:135:10 | (reference dereference) | arrayassignment.cpp:134:9:134:14 | call to source |
| arrayassignment.cpp:136:7:136:13 | access to array | arrayassignment.cpp:134:9:134:14 | call to source |
| arrayassignment.cpp:140:7:140:11 | * ... | arrayassignment.cpp:139:10:139:15 | call to source |
| arrayassignment.cpp:141:7:141:13 | access to array | arrayassignment.cpp:139:10:139:15 | call to source |
| arrayassignment.cpp:145:7:145:13 | access to array | arrayassignment.cpp:144:12:144:17 | call to source |
| arrayassignment.cpp:146:7:146:13 | access to array | arrayassignment.cpp:144:12:144:17 | call to source |
| 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 |
@ -79,3 +98,4 @@
| taint.cpp:465:7:465:7 | x | taint.cpp:462:6:462:11 | call to source |
| taint.cpp:470:7:470:7 | x | 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:162:8:162:15 | access to array | vector.cpp:161:14:161:19 | call to source |

Просмотреть файл

@ -5,9 +5,9 @@ using namespace std;
int source();
namespace ns_char
namespace ns_int
{
char source();
int source();
}
void sink(int);
@ -49,22 +49,22 @@ void test_element_taint(int x) {
sink(v1.back());
v2[0] = source();
sink(v2); // tainted [NOT DETECTED]
sink(v2[0]); // tainted [NOT DETECTED]
sink(v2[1]);
sink(v2); // tainted
sink(v2[0]); // tainted
sink(v2[1]); // [FALSE POSITIVE]
sink(v2[x]); // potentially tainted
v3 = v2;
sink(v3); // tainted [NOT DETECTED]
sink(v3[0]); // tainted [NOT DETECTED]
sink(v3[1]);
sink(v3); // tainted
sink(v3[0]); // tainted
sink(v3[1]); // [FALSE POSITIVE]
sink(v3[x]); // potentially tainted
v4[x] = source();
sink(v4); // tainted [NOT DETECTED]
sink(v4); // tainted
sink(v4[0]); // potentially tainted
sink(v4[1]); // potentially tainted
sink(v4[x]); // tainted [NOT DETECTED]
sink(v4[x]); // tainted
v5.push_back(source());
sink(v5); // tainted
@ -72,8 +72,8 @@ void test_element_taint(int x) {
sink(v5.back()); // tainted
v6.data()[2] = source();
sink(v6); // tainted [NOT DETECTED]
sink(v6.data()[2]); // tainted [NOT DETECTED]
sink(v6); // tainted
sink(v6.data()[2]); // tainted
{
const std::vector<int> &v7c = v7; // (workaround because our iterators don't convert to const_iterator)
@ -87,17 +87,17 @@ void test_element_taint(int x) {
{
const std::vector<int> &v8c = v8;
std::vector<int>::const_iterator it = v8c.begin();
v8.insert(it, 10, ns_char::source());
v8.insert(it, 10, ns_int::source());
}
sink(v8); // tainted [NOT DETECTED]
sink(v8.front()); // tainted [NOT DETECTED]
sink(v8.back());
v9.at(x) = source();
sink(v9); // tainted [NOT DETECTED]
sink(v9); // tainted
sink(v9.at(0)); // potentially tainted
sink(v9.at(1)); // potentially tainted
sink(v9.at(x)); // tainted [NOT DETECTED]
sink(v9.at(x)); // tainted
}
void test_vector_swap() {
@ -141,3 +141,153 @@ void test_vector_clear() {
sink(v3); // [FALSE POSITIVE]
sink(v4);
}
struct MyPair
{
int a, b;
};
struct MyVectorContainer
{
std::vector<int> vs;
};
void test_nested_vectors()
{
{
int aa[10][20] = {0};
sink(aa[0][0]);
aa[0][0] = source();
sink(aa[0][0]); // tainted [IR ONLY]
}
{
std::vector<std::vector<int> > bb(30);
bb[0].push_back(0);
sink(bb[0][0]);
bb[0][0] = source();
sink(bb[0][0]); // tainted
}
{
std::vector<int> cc[40];
cc[0].push_back(0);
sink(cc[0][0]);
cc[0][0] = source();
sink(cc[0][0]); // tainted
}
{
std::vector<MyPair> dd;
MyPair mp = {0, 0};
dd.push_back(mp);
sink(dd[0].a);
sink(dd[0].b);
dd[0].a = source();
sink(dd[0].a); // tainted [NOT DETECTED]
sink(dd[0].b);
}
{
MyVectorContainer ee;
ee.vs.push_back(0);
sink(ee.vs[0]);
ee.vs[0] = source();
sink(ee.vs[0]); // tainted
}
{
std::vector<MyVectorContainer> ff;
MyVectorContainer mvc;
mvc.vs.push_back(0);
ff.push_back(mvc);
sink(ff[0].vs[0]);
ff[0].vs[0] = source();
sink(ff[0].vs[0]); // tainted [NOT DETECTED]
}
}
void sink(std::vector<int>::iterator &);
typedef int myInt;
typedef float myFloat;
namespace ns_myFloat
{
myFloat source();
}
namespace ns_ci_ptr
{
const int *source();
}
void sink(std::vector<myFloat> &);
void sink(std::vector<const int *> &);
void test_vector_assign() {
std::vector<int> v1, v2, v3;
v1.assign(100, 0);
v2.assign(100, ns_int::source());
v3.push_back(source());
sink(v1);
sink(v2); // tainted
sink(v3); // tainted
{
std::vector<int> v4, v5, v6;
std::vector<int>::iterator i1, i2;
v4.assign(v1.begin(), v1.end());
v5.assign(v3.begin(), v3.end());
i1 = v3.begin();
i1++;
i2 = i1;
i2++;
v6.assign(i1, i2);
sink(v4);
sink(v5); // tainted [NOT DETECTED]
sink(i1); // tainted [NOT DETECTED]
sink(i2); // tainted [NOT DETECTED]
sink(v6); // tainted [NOT DETECTED]
}
{
std::vector<myInt> v7;
std::vector<myFloat> v8;
std::vector<const int *> v9;
v7.assign(100, ns_int::source());
v8.assign(100, ns_myFloat::source());
v9.assign(100, ns_ci_ptr::source());
sink(v7); // tainted
sink(v8); // tainted
sink(v9); // tainted
}
}
void sink(int *);
void test_data_more() {
std::vector<int> v1, v2;
v1.push_back(source());
sink(v1); // tainted
sink(v1.data()); // tainted
sink(v1.data()[2]); // tainted
*(v2.data()) = ns_int::source();
sink(v2); // tainted
sink(v2.data()); // tainted
sink(v2.data()[2]); // tainted
}

Просмотреть файл

@ -0,0 +1,10 @@
// semmle-extractor-options: --edg --clang --edg --c++20
namespace cpp20 {
class TestConstexpr {
constexpr int member_constexpr() { return 0; } // not const in C++ >= 14
constexpr int member_const_constexpr() const { return 0; }
};
} // namespace cpp20

Просмотреть файл

@ -1,5 +1,22 @@
| Class | specifiers2pp.cpp:8:7:8:13 | MyClass | MyClass | abstract |
| Class | specifiers2pp.cpp:24:7:24:14 | MyClass2 | MyClass2 | abstract |
| Function | cpp20.cpp:5:7:5:7 | operator= | operator= | extern |
| Function | cpp20.cpp:5:7:5:7 | operator= | operator= | extern |
| Function | cpp20.cpp:5:7:5:7 | operator= | operator= | inline |
| Function | cpp20.cpp:5:7:5:7 | operator= | operator= | inline |
| Function | cpp20.cpp:5:7:5:7 | operator= | operator= | is_constexpr |
| Function | cpp20.cpp:5:7:5:7 | operator= | operator= | is_constexpr |
| Function | cpp20.cpp:5:7:5:7 | operator= | operator= | public |
| Function | cpp20.cpp:5:7:5:7 | operator= | operator= | public |
| Function | cpp20.cpp:6:19:6:34 | member_constexpr | member_constexpr | declared_constexpr |
| Function | cpp20.cpp:6:19:6:34 | member_constexpr | member_constexpr | inline |
| Function | cpp20.cpp:6:19:6:34 | member_constexpr | member_constexpr | is_constexpr |
| Function | cpp20.cpp:6:19:6:34 | member_constexpr | member_constexpr | private |
| Function | cpp20.cpp:7:19:7:40 | member_const_constexpr | member_const_constexpr | const |
| Function | cpp20.cpp:7:19:7:40 | member_const_constexpr | member_const_constexpr | declared_constexpr |
| Function | cpp20.cpp:7:19:7:40 | member_const_constexpr | member_const_constexpr | inline |
| Function | cpp20.cpp:7:19:7:40 | member_const_constexpr | member_const_constexpr | is_constexpr |
| Function | cpp20.cpp:7:19:7:40 | member_const_constexpr | member_const_constexpr | private |
| Function | specifiers2.c:11:6:11:6 | f | f | extern |
| Function | specifiers2.c:12:13:12:13 | f | f | extern |
| Function | specifiers2.c:13:13:13:13 | f | f | extern |
@ -79,6 +96,24 @@
| Function | specifiers2pp.cpp:41:16:41:23 | someFun2 | someFun2 | extern |
| Function | specifiers2pp.cpp:43:9:43:16 | someFun3 | someFun3 | extern |
| Function | specifiers2pp.cpp:44:16:44:23 | someFun4 | someFun4 | static |
| Function | specifiers2pp.cpp:62:7:62:7 | operator= | operator= | extern |
| Function | specifiers2pp.cpp:62:7:62:7 | operator= | operator= | extern |
| Function | specifiers2pp.cpp:62:7:62:7 | operator= | operator= | inline |
| Function | specifiers2pp.cpp:62:7:62:7 | operator= | operator= | inline |
| Function | specifiers2pp.cpp:62:7:62:7 | operator= | operator= | is_constexpr |
| Function | specifiers2pp.cpp:62:7:62:7 | operator= | operator= | is_constexpr |
| Function | specifiers2pp.cpp:62:7:62:7 | operator= | operator= | public |
| Function | specifiers2pp.cpp:62:7:62:7 | operator= | operator= | public |
| Function | specifiers2pp.cpp:63:19:63:34 | member_constexpr | member_constexpr | const |
| Function | specifiers2pp.cpp:63:19:63:34 | member_constexpr | member_constexpr | declared_constexpr |
| Function | specifiers2pp.cpp:63:19:63:34 | member_constexpr | member_constexpr | inline |
| Function | specifiers2pp.cpp:63:19:63:34 | member_constexpr | member_constexpr | is_constexpr |
| Function | specifiers2pp.cpp:63:19:63:34 | member_constexpr | member_constexpr | private |
| Function | specifiers2pp.cpp:64:19:64:40 | member_const_constexpr | member_const_constexpr | const |
| Function | specifiers2pp.cpp:64:19:64:40 | member_const_constexpr | member_const_constexpr | declared_constexpr |
| Function | specifiers2pp.cpp:64:19:64:40 | member_const_constexpr | member_const_constexpr | inline |
| Function | specifiers2pp.cpp:64:19:64:40 | member_const_constexpr | member_const_constexpr | is_constexpr |
| Function | specifiers2pp.cpp:64:19:64:40 | member_const_constexpr | member_const_constexpr | private |
| FunctionDeclarationEntry | specifiers2.c:11:6:11:6 | declaration of f | f | c_linkage |
| FunctionDeclarationEntry | specifiers2.c:11:6:11:6 | declaration of f | f | void_param_list |
| FunctionDeclarationEntry | specifiers2.c:12:13:12:13 | declaration of f | f | c_linkage |

Просмотреть файл

@ -58,3 +58,8 @@ template<typename T> using Const = const T;
using Const_int = Const<int>;
typedef volatile Const_int volatile_Const_int;
class TestConstexpr {
constexpr int member_constexpr() { return 0; } // const in C++11
constexpr int member_const_constexpr() const { return 0; }
};

Просмотреть файл

@ -0,0 +1,6 @@
| a.c:4:5:4:6 | definition of is | array of {int} | 1 |
| a.h:2:12:2:13 | declaration of is | array of 4 {int} | 1 |
| file://:0:0:0:0 | definition of fp_offset | unsigned int | 1 |
| file://:0:0:0:0 | definition of gp_offset | unsigned int | 1 |
| file://:0:0:0:0 | definition of overflow_arg_area | pointer to {void} | 1 |
| file://:0:0:0:0 | definition of reg_save_area | pointer to {void} | 1 |

Просмотреть файл

@ -0,0 +1,5 @@
import cpp
from VariableDeclarationEntry vd, Type t
where t = vd.getType()
select vd, t.explain(), count(Type u | u = vd.getType())

Просмотреть файл

@ -1,5 +1,4 @@
| a.c:4:5:4:6 | is | array of 4 {int} | 2 |
| a.c:4:5:4:6 | is | array of {int} | 2 |
| a.c:4:5:4:6 | is | array of {int} | 1 |
| file://:0:0:0:0 | fp_offset | unsigned int | 1 |
| file://:0:0:0:0 | gp_offset | unsigned int | 1 |
| file://:0:0:0:0 | overflow_arg_area | pointer to {void} | 1 |

213
csharp/.editorconfig Normal file
Просмотреть файл

@ -0,0 +1,213 @@
# Taken as is from https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference?view=vs-2019
# Customizations are added at the bottom of the file.
# Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true
# C# files
[*.cs]
#### Core EditorConfig Options ####
# Indentation and spacing
indent_size = 4
indent_style = space
tab_width = 4
# New line preferences
end_of_line = crlf
insert_final_newline = false
#### .NET Coding Conventions ####
# Organize usings
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = false
# this. and Me. preferences
dotnet_style_qualification_for_event = false:silent
dotnet_style_qualification_for_field = false:silent
dotnet_style_qualification_for_method = false:silent
dotnet_style_qualification_for_property = false:silent
# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
dotnet_style_predefined_type_for_member_access = true:silent
# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
# Modifier preferences
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
# Expression-level preferences
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_object_initializer = true:suggestion
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
# Field preferences
dotnet_style_readonly_field = true:suggestion
# Parameter preferences
dotnet_code_quality_unused_parameters = all:suggestion
#### C# Coding Conventions ####
# var preferences
csharp_style_var_elsewhere = false:silent
csharp_style_var_for_built_in_types = false:silent
csharp_style_var_when_type_is_apparent = false:silent
# Expression-bodied members
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:silent
# Pattern matching preferences
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_prefer_switch_expression = true:suggestion
# Null-checking preferences
csharp_style_conditional_delegate_call = true:suggestion
# Modifier preferences
csharp_prefer_static_local_function = true:suggestion
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
# Code-block preferences
csharp_prefer_braces = true:silent
csharp_prefer_simple_using_statement = true:suggestion
# Expression-level preferences
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_pattern_local_over_anonymous_function = true:suggestion
csharp_style_prefer_index_operator = true:suggestion
csharp_style_prefer_range_operator = true:suggestion
csharp_style_throw_expression = true:suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
# 'using' directive preferences
csharp_using_directive_placement = outside_namespace:silent
#### C# Formatting Rules ####
# New line preferences
csharp_new_line_before_catch = true
csharp_new_line_before_else = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = all
csharp_new_line_between_query_expression_clauses = true
# Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
# Space preferences
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
# Wrapping preferences
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
#### Naming styles ####
# Naming rules
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
# Symbol specifications
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
# Naming styles
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case
#
# Customizations
#
# IDE0055: Fix formatting
dotnet_diagnostic.IDE0055.severity = warning
[extractor/Semmle.Extraction/Tuples.cs,
extractor/Semmle.Extraction.CSharp/Tuples.cs,
extractor/Semmle.Extraction.CIL/Tuples.cs]
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = none

8
csharp/.vscode/settings.json поставляемый
Просмотреть файл

@ -3,5 +3,11 @@
"dotnet-test-explorer.testProjectPath": "**/*Tests.@(csproj|vbproj|fsproj)",
"dotnet-test-explorer.testArguments": "/property:GenerateTargetFrameworkAttribute=false",
"csharp.supressBuildAssetsNotification": true,
"csharp.suppressDotnetRestoreNotification": true
"csharp.suppressDotnetRestoreNotification": true,
"[csharp]": {
"editor.defaultFormatter": "ms-dotnettools.csharp"
},
"omnisharp.enableMsBuildLoadProjectsOnDemand": true,
"omnisharp.enableEditorConfigSupport": true,
"omnisharp.enableRoslynAnalyzers": true,
}

Просмотреть файл

@ -450,15 +450,22 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
Actions.GetEnvironmentVariable["ProgramFiles(x86)"] = @"C:\Program Files (x86)";
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = true;
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = 0;
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = "C:\\VS1\nC:\\VS2";
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = "10.0\n11.0";
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = "C:\\VS1\nC:\\VS2\nC:\\VS3";
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = 0;
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = "10.0\n11.0\n16.0";
var candidates = BuildTools.GetCandidateVcVarsFiles(Actions).ToArray();
Assert.Equal("C:\\VS1\\VC\\vcvarsall.bat", candidates[0].Path);
Assert.Equal(10, candidates[0].ToolsVersion);
Assert.Equal("C:\\VS2\\VC\\vcvarsall.bat", candidates[1].Path);
Assert.Equal(11, candidates[1].ToolsVersion);
Assert.Equal(@"C:\VS3\VC\Auxiliary\Build\vcvars32.bat", candidates[2].Path);
Assert.Equal(16, candidates[2].ToolsVersion);
Assert.Equal(@"C:\VS3\VC\Auxiliary\Build\vcvars64.bat", candidates[3].Path);
Assert.Equal(16, candidates[3].ToolsVersion);
Assert.Equal(@"C:\VS3\Common7\Tools\VsDevCmd.bat", candidates[4].Path);
Assert.Equal(16, candidates[4].ToolsVersion);
Assert.Equal(5, candidates.Length);
}
[Fact]

Просмотреть файл

@ -11,13 +11,11 @@ namespace Semmle.Autobuild.Shared
{
public readonly int ToolsVersion;
public readonly string Path;
public readonly string[] Platform;
public VcVarsBatFile(string path, int version, params string[] platform)
public VcVarsBatFile(string path, int version)
{
Path = path;
ToolsVersion = version;
Platform = platform;
}
};
@ -51,12 +49,15 @@ namespace Semmle.Autobuild.Shared
{
if (majorVersion < 15)
{
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\vcvarsall.bat"), majorVersion, "x86");
// Visual Studio 2015 and below
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\vcvarsall.bat"), majorVersion);
}
else
{
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\Auxiliary\Build\vcvars32.bat"), majorVersion, "x86");
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\Auxiliary\Build\vcvars64.bat"), majorVersion, "x64");
// Visual Studio 2017 and above
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\Auxiliary\Build\vcvars32.bat"), majorVersion);
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\Auxiliary\Build\vcvars64.bat"), majorVersion);
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"Common7\Tools\VsDevCmd.bat"), majorVersion);
}
}
// else: Skip installation without a version
@ -66,10 +67,10 @@ namespace Semmle.Autobuild.Shared
}
// vswhere not installed or didn't run correctly - return legacy Visual Studio versions
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 14.0\VC\vcvarsall.bat"), 14, "x86");
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 12.0\VC\vcvarsall.bat"), 12, "x86");
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 11.0\VC\vcvarsall.bat"), 11, "x86");
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 10.0\VC\vcvarsall.bat"), 10, "x86");
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 14.0\VC\vcvarsall.bat"), 14);
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 12.0\VC\vcvarsall.bat"), 12);
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 11.0\VC\vcvarsall.bat"), 11);
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 10.0\VC\vcvarsall.bat"), 10);
}
/// <summary>

Просмотреть файл

@ -33,7 +33,7 @@ namespace Semmle.Autobuild.Shared
if (vsTools == null && builder.Actions.IsWindows())
{
builder.Log(Severity.Warning, "Could not find a suitable version of vcvarsall.bat");
builder.Log(Severity.Warning, "Could not find a suitable version of VsDevCmd.bat/vcvarsall.bat");
}
var nuget =

Просмотреть файл

@ -50,6 +50,13 @@ namespace Semmle.Extraction.CIL.Driver
return an;
}
/// <summary>
/// Initializes a new instance of the <see cref="AssemblyInfo"/> class.
/// </summary>
/// <param name="path">Path of the assembly.</param>
/// <exception cref="Semmle.Extraction.CIL.Driver.InvalidAssemblyException">
/// Thrown when the input file is not a valid assembly.
/// </exception>
public AssemblyInfo(string path)
{
filename = path;
@ -60,13 +67,11 @@ namespace Semmle.Extraction.CIL.Driver
{
try
{
isAssembly = peReader.HasMetadata;
if (!isAssembly) return;
if (!peReader.HasMetadata) throw new InvalidAssemblyException();
var mdReader = peReader.GetMetadataReader();
isAssembly = mdReader.IsAssembly;
if (!mdReader.IsAssembly) return;
if (!mdReader.IsAssembly) throw new InvalidAssemblyException();
// Get our own assembly name
name = CreateAssemblyName(mdReader, mdReader.GetAssemblyDefinition());
@ -81,7 +86,7 @@ namespace Semmle.Extraction.CIL.Driver
// This failed on one of the Roslyn tests that includes
// a deliberately malformed assembly.
// In this case, we just skip the extraction of this assembly.
isAssembly = false;
throw new InvalidAssemblyException();
}
}
}
@ -89,7 +94,6 @@ namespace Semmle.Extraction.CIL.Driver
public readonly AssemblyName name;
public readonly string filename;
public bool extract;
public readonly bool isAssembly;
public readonly AssemblyName[] references;
}
@ -102,11 +106,12 @@ namespace Semmle.Extraction.CIL.Driver
{
class AssemblyNameComparer : IEqualityComparer<AssemblyName>
{
bool IEqualityComparer<AssemblyName>.Equals(AssemblyName x, AssemblyName y) =>
x.Name == y.Name && x.Version == y.Version;
bool IEqualityComparer<AssemblyName>.Equals(AssemblyName? x, AssemblyName? y) =>
object.ReferenceEquals(x, y) ||
x?.Name == y?.Name && x?.Version == y?.Version;
int IEqualityComparer<AssemblyName>.GetHashCode(AssemblyName obj) =>
obj.Name.GetHashCode() + 7 * obj.Version.GetHashCode();
(obj.Name, obj.Version).GetHashCode();
}
readonly Dictionary<AssemblyName, AssemblyInfo> assembliesRead = new Dictionary<AssemblyName, AssemblyInfo>(new AssemblyNameComparer());
@ -116,13 +121,15 @@ namespace Semmle.Extraction.CIL.Driver
if (!filesAnalyzed.Contains(assemblyPath))
{
filesAnalyzed.Add(assemblyPath);
var info = new AssemblyInfo(assemblyPath);
if (info.isAssembly)
try
{
var info = new AssemblyInfo(assemblyPath);
info.extract = extractAll;
if (!assembliesRead.ContainsKey(info.name))
assembliesRead.Add(info.name, info);
}
catch (InvalidAssemblyException)
{ }
}
}
@ -137,8 +144,7 @@ namespace Semmle.Extraction.CIL.Driver
while (assembliesToReference.Any())
{
var item = assembliesToReference.Pop();
AssemblyInfo info;
if (assembliesRead.TryGetValue(item, out info))
if (assembliesRead.TryGetValue(item, out AssemblyInfo? info))
{
if (!info.extract)
{
@ -165,6 +171,21 @@ namespace Semmle.Extraction.CIL.Driver
{
readonly AssemblyList assemblyList = new AssemblyList();
public ExtractorOptions(string[] args)
{
Verbosity = Verbosity.Info;
Threads = System.Environment.ProcessorCount;
PDB = true;
TrapCompression = TrapWriter.CompressionMode.Gzip;
ParseArgs(args);
AddFrameworkDirectories(false);
assemblyList.ResolveReferences();
AssembliesToExtract = assemblyList.AssembliesToExtract.ToArray();
}
public void AddDirectory(string directory, bool extractAll)
{
foreach (var file in
@ -192,7 +213,12 @@ namespace Semmle.Extraction.CIL.Driver
if (File.Exists(path))
{
assemblyList.AddFile(path, true);
AddDirectory(Path.GetDirectoryName(path), false);
string? directory = Path.GetDirectoryName(path);
if (directory is null)
{
throw new InternalError($"Directory of path '{path}' is null");
}
AddDirectory(directory, false);
}
else if (Directory.Exists(path))
{
@ -200,13 +226,7 @@ namespace Semmle.Extraction.CIL.Driver
}
}
void ResolveReferences()
{
assemblyList.ResolveReferences();
AssembliesToExtract = assemblyList.AssembliesToExtract.ToArray();
}
public IEnumerable<AssemblyInfo> AssembliesToExtract { get; private set; }
public IEnumerable<AssemblyInfo> AssembliesToExtract { get; }
/// <summary>
/// Gets the assemblies that were referenced but were not available to be
@ -215,55 +235,43 @@ namespace Semmle.Extraction.CIL.Driver
/// </summary>
public IEnumerable<AssemblyName> MissingReferences => assemblyList.missingReferences;
public static ExtractorOptions ParseCommandLine(string[] args)
private void ParseArgs(string[] args)
{
var options = new ExtractorOptions();
options.Verbosity = Verbosity.Info;
options.Threads = System.Environment.ProcessorCount;
options.PDB = true;
options.TrapCompression = TrapWriter.CompressionMode.Gzip;
foreach (var arg in args)
{
if (arg == "--verbose")
{
options.Verbosity = Verbosity.All;
Verbosity = Verbosity.All;
}
else if (arg == "--silent")
{
options.Verbosity = Verbosity.Off;
Verbosity = Verbosity.Off;
}
else if (arg.StartsWith("--verbosity:"))
{
options.Verbosity = (Verbosity)int.Parse(arg.Substring(12));
Verbosity = (Verbosity)int.Parse(arg.Substring(12));
}
else if (arg == "--dotnet")
{
options.AddFrameworkDirectories(true);
AddFrameworkDirectories(true);
}
else if (arg == "--nocache")
{
options.NoCache = true;
NoCache = true;
}
else if (arg.StartsWith("--threads:"))
{
options.Threads = int.Parse(arg.Substring(10));
Threads = int.Parse(arg.Substring(10));
}
else if (arg == "--no-pdb")
{
options.PDB = false;
PDB = false;
}
else
{
options.AddFileOrDirectory(arg);
AddFileOrDirectory(arg);
}
}
options.AddFrameworkDirectories(false);
options.ResolveReferences();
return options;
}
}
}

Просмотреть файл

@ -0,0 +1,7 @@
using System;
namespace Semmle.Extraction.CIL.Driver
{
class InvalidAssemblyException : Exception
{ }
}

Просмотреть файл

@ -40,7 +40,7 @@ namespace Semmle.Extraction.CIL.Driver
return;
}
var options = ExtractorOptions.ParseCommandLine(args);
var options = new ExtractorOptions(args);
var layout = new Layout();
var logger = new ConsoleLogger(options.Verbosity);

Просмотреть файл

@ -7,6 +7,7 @@
<RootNamespace>Semmle.Extraction.CIL.Driver</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -501,7 +501,7 @@ namespace Semmle.Extraction.CIL.Entities
unboundMethod.WriteId(trapFile);
trapFile.Write('<');
int index = 0;
foreach(var param in typeParams)
foreach (var param in typeParams)
{
trapFile.WriteSeparator(",", ref index);
trapFile.WriteSubId(param);

Просмотреть файл

@ -38,7 +38,7 @@ namespace Semmle.Extraction.CIL.Entities
trapFile.Write('.');
trapFile.Write(cx.GetString(pd.Name));
trapFile.Write("(");
int index=0;
int index = 0;
var signature = pd.DecodeSignature(new SignatureDecoder(), gc);
foreach (var param in signature.ParameterTypes)
{

Просмотреть файл

@ -771,7 +771,7 @@ namespace Semmle.Extraction.CIL.Entities
public override bool Equals(object obj)
{
if(obj is ConstructedType t && Equals(unboundGenericType, t.unboundGenericType) && Equals(containingType, t.containingType))
if (obj is ConstructedType t && Equals(unboundGenericType, t.unboundGenericType) && Equals(containingType, t.containingType))
{
if (thisTypeArguments is null) return t.thisTypeArguments is null;
if (!(t.thisTypeArguments is null)) return thisTypeArguments.SequenceEqual(t.thisTypeArguments);
@ -1208,7 +1208,7 @@ namespace Semmle.Extraction.CIL.Entities
{
elementType.WriteId(trapFile, gc);
trapFile.Write('[');
for (int i=1; i<shape.Rank; ++i)
for (int i = 1; i < shape.Rank; ++i)
trapFile.Write(',');
trapFile.Write(']');
}
@ -1254,7 +1254,7 @@ namespace Semmle.Extraction.CIL.Entities
genericType.WriteId(trapFile, gc);
trapFile.Write('<');
int index = 0;
foreach(var arg in typeArguments)
foreach (var arg in typeArguments)
{
trapFile.WriteSeparator(",", ref index);
arg.WriteId(trapFile, gc);
@ -1451,8 +1451,7 @@ namespace Semmle.Extraction.CIL.Entities
genericContext.GetGenericTypeParameter(index);
Type ISignatureTypeProvider<Type, GenericContext>.GetModifiedType(Type modifier, Type unmodifiedType, bool isRequired) =>
// !! Not implemented properly
unmodifiedType;
unmodifiedType; // !! Not implemented properly
Type ISignatureTypeProvider<Type, GenericContext>.GetPinnedType(Type elementType) =>
cx.Populate(new PointerType(cx, elementType));

Просмотреть файл

@ -26,28 +26,28 @@ namespace Semmle.Extraction.CSharp.Entities
// Arguments
int index = 0;
foreach(var arg in args)
foreach (var arg in args)
{
trapFile.compilation_args(this, index++, arg);
}
// Files
index = 0;
foreach(var file in cx.Compilation.SyntaxTrees.Select(tree => Extraction.Entities.File.Create(cx, tree.FilePath)))
foreach (var file in cx.Compilation.SyntaxTrees.Select(tree => Extraction.Entities.File.Create(cx, tree.FilePath)))
{
trapFile.compilation_compiling_files(this, index++, file);
}
// References
index = 0;
foreach(var file in cx.Compilation.References.OfType<PortableExecutableReference>().Select(r => Extraction.Entities.File.Create(cx, r.FilePath)))
foreach (var file in cx.Compilation.References.OfType<PortableExecutableReference>().Select(r => Extraction.Entities.File.Create(cx, r.FilePath)))
{
trapFile.compilation_referencing_files(this, index++, file);
}
// Diagnostics
index = 0;
foreach(var diag in cx.Compilation.GetDiagnostics().Select(d => new Diagnostic(cx, d)))
foreach (var diag in cx.Compilation.GetDiagnostics().Select(d => new Diagnostic(cx, d)))
{
trapFile.diagnostic_for(diag, this, 0, index++);
}
@ -57,7 +57,7 @@ namespace Semmle.Extraction.CSharp.Entities
{
var trapFile = cx.TrapWriter.Writer;
int index = 0;
foreach(float metric in p.Metrics)
foreach (float metric in p.Metrics)
{
trapFile.compilation_time(this, -1, index++, metric);
}

Просмотреть файл

@ -53,7 +53,7 @@ namespace Semmle.Extraction.CSharp.Entities
trapFile.type_nullability(this, n);
}
if(Info.FlowState != NullableFlowState.None)
if (Info.FlowState != NullableFlowState.None)
{
trapFile.expr_flowstate(this, (int)Info.FlowState);
}
@ -292,7 +292,7 @@ namespace Semmle.Extraction.CSharp.Entities
protected Expression(ExpressionNodeInfo info)
: base(info)
{
Syntax = (SyntaxNode)info.Node;
Syntax = (SyntaxNode)info.Node;
}
/// <summary>
@ -307,7 +307,7 @@ namespace Semmle.Extraction.CSharp.Entities
protected new Expression TryPopulate()
{
cx.Try(Syntax, null, ()=>PopulateExpression(cx.TrapWriter.Writer));
cx.Try(Syntax, null, () => PopulateExpression(cx.TrapWriter.Writer));
return this;
}
}

Просмотреть файл

@ -22,7 +22,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
}
public ImplicitCast(ExpressionNodeInfo info, IMethodSymbol method)
: base(new ExpressionInfo(info.Context, Entities.Type.Create(info.Context, info.ConvertedType), info.Location, ExprKind.OPERATOR_INVOCATION, info.Parent, info.Child, true, info.ExprValue) )
: base(new ExpressionInfo(info.Context, Entities.Type.Create(info.Context, info.ConvertedType), info.Location, ExprKind.OPERATOR_INVOCATION, info.Parent, info.Child, true, info.ExprValue))
{
Expr = Factory.Create(info.SetParent(this, 0));

Просмотреть файл

@ -50,7 +50,8 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
public static Lambda Create(ExpressionNodeInfo info, SimpleLambdaExpressionSyntax node) => new Lambda(info, node);
Lambda(ExpressionNodeInfo info, AnonymousMethodExpressionSyntax node) :
this(info.SetKind(ExprKind.ANONYMOUS_METHOD), node.Body, node.ParameterList == null ? Enumerable.Empty<ParameterSyntax>() : node.ParameterList.Parameters) { }
this(info.SetKind(ExprKind.ANONYMOUS_METHOD), node.Body, node.ParameterList == null ? Enumerable.Empty<ParameterSyntax>() : node.ParameterList.Parameters)
{ }
public static Lambda Create(ExpressionNodeInfo info, AnonymousMethodExpressionSyntax node) => new Lambda(info, node);
}

Просмотреть файл

@ -9,7 +9,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
{
class Literal : Expression<LiteralExpressionSyntax>
{
Literal(ExpressionNodeInfo info) : base(info.SetKind(GetKind(info)) ) { }
Literal(ExpressionNodeInfo info) : base(info.SetKind(GetKind(info))) { }
public static Expression Create(ExpressionNodeInfo info) => new Literal(info).TryPopulate();
@ -17,7 +17,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
static ExprKind GetKind(ExpressionNodeInfo info)
{
switch(info.Node.Kind())
switch (info.Node.Kind())
{
case SyntaxKind.DefaultLiteralExpression:
return ExprKind.DEFAULT;

Просмотреть файл

@ -27,10 +27,12 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
}
}
public static Expression Create(ExpressionNodeInfo info, ConditionalAccessExpressionSyntax node) =>
public static Expression Create(ExpressionNodeInfo info, ConditionalAccessExpressionSyntax node)
{
// The qualifier is located by walking the syntax tree.
// `node.WhenNotNull` will contain a MemberBindingExpressionSyntax, calling the method below.
CreateFromNode(new ExpressionNodeInfo(info.Context, node.WhenNotNull, info.Parent, info.Child, info.TypeInfo));
return CreateFromNode(new ExpressionNodeInfo(info.Context, node.WhenNotNull, info.Parent, info.Child, info.TypeInfo));
}
public static Expression Create(ExpressionNodeInfo info, MemberBindingExpressionSyntax node)
{

Просмотреть файл

@ -23,7 +23,7 @@ namespace Semmle.Extraction.CSharp.Entities
protected override void Populate(TextWriter trapFile)
{
var @namespace = (INamespaceSymbol) cx.GetModel(Node).GetSymbolInfo(Node.Name).Symbol;
var @namespace = (INamespaceSymbol)cx.GetModel(Node).GetSymbolInfo(Node.Name).Symbol;
var ns = Namespace.Create(cx, @namespace);
trapFile.namespace_declarations(this, ns);
trapFile.namespace_declaration_location(this, cx.Create(Node.Name.GetLocation()));

Просмотреть файл

@ -64,7 +64,7 @@ namespace Semmle.Extraction.CSharp.Entities
Emit(trapFile, Loc ?? Syntax.GetLocation(), Parent, Type);
Create(cx, nts.ElementType, this, nt.symbol.IsReferenceType ? nt : nt.TypeArguments[0]);
}
else if(Type is ArrayType array)
else if (Type is ArrayType array)
{
Create(cx, nts.ElementType, Parent, array);
}

Просмотреть файл

@ -35,14 +35,14 @@ namespace Semmle.Extraction.CSharp.Entities
if (symbol.HasConstructorConstraint)
trapFile.general_type_parameter_constraints(constraints, 3);
if(symbol.HasUnmanagedTypeConstraint)
if (symbol.HasUnmanagedTypeConstraint)
trapFile.general_type_parameter_constraints(constraints, 4);
ITypeSymbol baseType = symbol.HasValueTypeConstraint ?
Context.Compilation.GetTypeByMetadataName(valueTypeName) :
Context.Compilation.ObjectType;
if(symbol.ReferenceTypeConstraintNullableAnnotation == NullableAnnotation.Annotated)
if (symbol.ReferenceTypeConstraintNullableAnnotation == NullableAnnotation.Annotated)
trapFile.general_type_parameter_constraints(constraints, 5);
foreach (var abase in symbol.GetAnnotatedTypeConstraints())

Просмотреть файл

@ -140,6 +140,12 @@ namespace Semmle.Extraction.CSharp
return ExitCode.Failed;
}
// csc.exe (CSharpCompiler.cs) also provides CompilationOptions
// .WithMetadataReferenceResolver(),
// .WithXmlReferenceResolver() and
// .WithSourceReferenceResolver().
// These would be needed if we hadn't explicitly provided the source/references
// already.
var compilation = CSharpCompilation.Create(
compilerArguments.CompilationName,
syntaxTrees,
@ -147,11 +153,6 @@ namespace Semmle.Extraction.CSharp
compilerArguments.CompilationOptions.
WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default).
WithStrongNameProvider(new DesktopStrongNameProvider(compilerArguments.KeyFileSearchPaths))
// csc.exe (CSharpCompiler.cs) also provides WithMetadataReferenceResolver,
// WithXmlReferenceResolver and
// WithSourceReferenceResolver.
// These would be needed if we hadn't explicitly provided the source/references
// already.
);
analyser.EndInitialize(compilerArguments, commandLineArguments, compilation);

Просмотреть файл

@ -15,6 +15,8 @@ namespace Semmle.Extraction.Tests
var layout = new Semmle.Extraction.Layout(null, null, null);
var project = layout.LookupProjectOrNull("foo.cs");
Assert.NotNull(project);
// All files are mapped when there's no layout file.
Assert.True(layout.FileInLayout("foo.cs"));
@ -28,7 +30,7 @@ namespace Semmle.Extraction.Tests
Assert.NotEqual(Directory.GetCurrentDirectory(), tmpDir);
return;
}
var f1 = project.GetTrapPath(Logger, "foo.cs", TrapWriter.CompressionMode.Gzip);
var f1 = project!.GetTrapPath(Logger, "foo.cs", TrapWriter.CompressionMode.Gzip);
var g1 = TrapWriter.NestPaths(Logger, tmpDir, "foo.cs.trap.gz", TrapWriter.InnerPathComputation.ABSOLUTE);
Assert.Equal(f1, g1);
@ -72,7 +74,9 @@ namespace Semmle.Extraction.Tests
// Test the trap file
var project = layout.LookupProjectOrNull("bar.cs");
var trapwriterFilename = project.GetTrapPath(Logger, "bar.cs", TrapWriter.CompressionMode.Gzip);
Assert.NotNull(project);
var trapwriterFilename = project!.GetTrapPath(Logger, "bar.cs", TrapWriter.CompressionMode.Gzip);
Assert.Equal(TrapWriter.NestPaths(Logger, Path.GetFullPath("snapshot\\trap"), "bar.cs.trap.gz", TrapWriter.InnerPathComputation.ABSOLUTE),
trapwriterFilename);
@ -90,7 +94,9 @@ namespace Semmle.Extraction.Tests
// When you specify both a trap file and a layout, use the trap file.
var layout = new Semmle.Extraction.Layout(Path.GetFullPath("snapshot\\trap"), null, "something.txt");
Assert.True(layout.FileInLayout("bar.cs"));
var f1 = layout.LookupProjectOrNull("foo.cs").GetTrapPath(Logger, "foo.cs", TrapWriter.CompressionMode.Gzip);
var subProject = layout.LookupProjectOrNull("foo.cs");
Assert.NotNull(subProject);
var f1 = subProject!.GetTrapPath(Logger, "foo.cs", TrapWriter.CompressionMode.Gzip);
var g1 = TrapWriter.NestPaths(Logger, Path.GetFullPath("snapshot\\trap"), "foo.cs.trap.gz", TrapWriter.InnerPathComputation.ABSOLUTE);
Assert.Equal(f1, g1);
}
@ -118,13 +124,17 @@ namespace Semmle.Extraction.Tests
// Use Section 2
Assert.True(layout.FileInLayout("bar.cs"));
var f1 = layout.LookupProjectOrNull("bar.cs").GetTrapPath(Logger, "bar.cs", TrapWriter.CompressionMode.Gzip);
var subProject = layout.LookupProjectOrNull("bar.cs");
Assert.NotNull(subProject);
var f1 = subProject!.GetTrapPath(Logger, "bar.cs", TrapWriter.CompressionMode.Gzip);
var g1 = TrapWriter.NestPaths(Logger, Path.GetFullPath("snapshot\\trap2"), "bar.cs.trap.gz", TrapWriter.InnerPathComputation.ABSOLUTE);
Assert.Equal(f1, g1);
// Use Section 1
Assert.True(layout.FileInLayout("foo.cs"));
var f2 = layout.LookupProjectOrNull("foo.cs").GetTrapPath(Logger, "foo.cs", TrapWriter.CompressionMode.Gzip);
subProject = layout.LookupProjectOrNull("foo.cs");
Assert.NotNull(subProject);
var f2 = subProject!.GetTrapPath(Logger, "foo.cs", TrapWriter.CompressionMode.Gzip);
var g2 = TrapWriter.NestPaths(Logger, Path.GetFullPath("snapshot\\trap1"), "foo.cs.trap.gz", TrapWriter.InnerPathComputation.ABSOLUTE);
Assert.Equal(f2, g2);

Просмотреть файл

@ -9,8 +9,8 @@ namespace Semmle.Extraction.Tests
{
public class OptionsTests
{
CSharp.Options options;
CSharp.Standalone.Options standaloneOptions;
CSharp.Options? options;
CSharp.Standalone.Options? standaloneOptions;
public OptionsTests()
{

Просмотреть файл

@ -5,6 +5,7 @@
<TargetFramework>netcoreapp3.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -49,7 +49,7 @@ namespace Semmle.Extraction
/// <param name="factory">The entity factory.</param>
/// <param name="init">The initializer for the entity.</param>
/// <returns>The new/existing entity.</returns>
public Entity CreateEntity<Type, Entity>(ICachedEntityFactory<Type, Entity> factory, Type init) where Entity : ICachedEntity where Type:struct
public Entity CreateEntity<Type, Entity>(ICachedEntityFactory<Type, Entity> factory, Type init) where Entity : ICachedEntity where Type : struct
{
return CreateNonNullEntity(factory, init);
}
@ -73,7 +73,7 @@ namespace Semmle.Extraction
/// <returns>The new/existing entity.</returns>
public Entity CreateEntityFromSymbol<Type, Entity>(ICachedEntityFactory<Type, Entity> factory, Type init)
where Entity : ICachedEntity
where Type: ISymbol
where Type : ISymbol
{
return init == null ? CreateEntity2(factory, init) : CreateNonNullEntity(factory, init);
}
@ -500,7 +500,7 @@ namespace Semmle.Extraction
{
ExtractionError(message, optionalSymbol.ToDisplayString(), Entities.Location.Create(this, optionalSymbol.Locations.FirstOrDefault()));
}
else if(!(optionalEntity is null))
else if (!(optionalEntity is null))
{
ExtractionError(message, optionalEntity.Label.ToString(), Entities.Location.Create(this, optionalEntity.ReportingLocation));
}

Просмотреть файл

@ -14,7 +14,7 @@ namespace Semmle.Extraction.Entities
protected override void Populate(TextWriter trapFile)
{
trapFile.extractor_messages(this, msg.Severity, "C# extractor", msg.Text, msg.EntityText, msg.Location ?? GeneratedLocation.Create(cx), msg.StackTrace);
trapFile.extractor_messages(this, msg.Severity, "C# extractor", msg.Text, msg.EntityText, msg.Location ?? GeneratedLocation.Create(cx), msg.StackTrace);
}
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel;

Просмотреть файл

@ -4,7 +4,8 @@ using Microsoft.CodeAnalysis;
namespace Semmle.Extraction.Entities
{
public abstract class SourceLocation : Location {
public abstract class SourceLocation : Location
{
protected SourceLocation(Context cx, Microsoft.CodeAnalysis.Location? init) : base(cx, init)
{
}

Просмотреть файл

@ -153,7 +153,7 @@ namespace Semmle.Extraction
{
entity.WriteQuotedId(trapFile);
}
catch(Exception ex) // lgtm[cs/catch-of-all-exceptions]
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
{
trapFile.WriteLine("\"");
extractor.Message(new Message("Unhandled exception generating id", entity.ToString() ?? "", null, ex.StackTrace));

Просмотреть файл

@ -61,7 +61,7 @@ namespace Semmle.Extraction
/// </summary>
/// <param name="srcFile">The source file.</param>
/// <returns>A newly created TrapWriter.</returns>
public TrapWriter CreateTrapWriter(ILogger logger, string srcFile, bool discardDuplicates, TrapWriter.CompressionMode trapCompression) =>
public TrapWriter CreateTrapWriter(ILogger logger, string srcFile, bool discardDuplicates, TrapWriter.CompressionMode trapCompression) =>
new TrapWriter(logger, srcFile, TRAP_FOLDER, SOURCE_ARCHIVE, discardDuplicates, trapCompression);
}

Просмотреть файл

@ -9,7 +9,7 @@ namespace Semmle.Util
/// dictionary. If a list does not already exist, a new list is
/// created.
/// </summary>
public static void AddAnother<T1, T2>(this Dictionary<T1, List<T2>> dict, T1 key, T2 element) where T1:notnull
public static void AddAnother<T1, T2>(this Dictionary<T1, List<T2>> dict, T1 key, T2 element) where T1 : notnull
{
if (!dict.TryGetValue(key, out var list))
{

Просмотреть файл

@ -37,7 +37,7 @@ namespace Semmle.Util
/// </remarks>
///
/// <typeparam name="T">The value type.</typeparam>
public class FuzzyDictionary<T> where T:class
public class FuzzyDictionary<T> where T : class
{
// All data items indexed by the "base string" (stripped of numbers)
readonly Dictionary<string, List<KeyValuePair<string, T>>> index = new Dictionary<string, List<KeyValuePair<string, T>>>();
@ -61,7 +61,7 @@ namespace Semmle.Util
/// <param name="v1">Vector 1</param>
/// <param name="v2">Vector 2</param>
/// <returns>The Hamming Distance.</returns>
static int HammingDistance<U>(IEnumerable<U> v1, IEnumerable<U> v2) where U: notnull
static int HammingDistance<U>(IEnumerable<U> v1, IEnumerable<U> v2) where U : notnull
{
return v1.Zip(v2, (x, y) => x.Equals(y) ? 0 : 1).Sum();
}

Просмотреть файл

@ -93,7 +93,7 @@ namespace Semmle.Util
/// <typeparam name="T">The type of the item.</typeparam>
/// <param name="items">The list of items to hash.</param>
/// <returns>The hash code.</returns>
public static int SequenceHash<T>(this IEnumerable<T> items) where T: notnull
public static int SequenceHash<T>(this IEnumerable<T> items) where T : notnull
{
int h = 0;
foreach (var i in items)

Просмотреть файл

@ -7,7 +7,6 @@
+ semmlecode-javascript-queries/Declarations/UniqueParameterNames.ql: /Correctness/Declarations
+ semmlecode-javascript-queries/Declarations/UniquePropertyNames.ql: /Correctness/Declarations
+ semmlecode-javascript-queries/Declarations/IneffectiveParameterType.ql: /Correctness/Declarations
+ semmlecode-javascript-queries/DOM/AmbiguousIdAttribute.ql: /Correctness/DOM
+ semmlecode-javascript-queries/DOM/ConflictingAttributes.ql: /Correctness/DOM
+ semmlecode-javascript-queries/DOM/MalformedIdAttribute.ql: /Correctness/DOM
+ semmlecode-javascript-queries/Expressions/ComparisonWithNaN.ql: /Correctness/Expressions

Просмотреть файл

@ -35,6 +35,7 @@ import com.semmle.js.ast.jsx.JSXMemberExpression;
import com.semmle.js.ast.jsx.JSXNamespacedName;
import com.semmle.js.ast.jsx.JSXOpeningElement;
import com.semmle.js.ast.jsx.JSXSpreadAttribute;
import com.semmle.js.ast.jsx.JSXThisExpr;
import com.semmle.util.data.Either;
import java.util.ArrayList;
import java.util.List;
@ -225,22 +226,26 @@ public class JSXParser extends Parser {
}
/** Parse next token as JSX identifier */
private JSXIdentifier jsx_parseIdentifier() {
private IJSXName jsx_parseIdentifier(boolean expectThisExpr) {
SourceLocation loc = new SourceLocation(this.startLoc);
String name = null;
if (this.type == jsxName) name = String.valueOf(this.value);
else if (this.type.keyword != null) name = this.type.keyword;
else this.unexpected();
this.next();
return this.finishNode(new JSXIdentifier(loc, name));
if (expectThisExpr && name.equals("this")) {
return this.finishNode(new JSXThisExpr(loc));
} else {
return this.finishNode(new JSXIdentifier(loc, name));
}
}
/** Parse namespaced identifier. */
private IJSXName jsx_parseNamespacedName() {
SourceLocation loc = new SourceLocation(this.startLoc);
JSXIdentifier namespace = this.jsx_parseIdentifier();
if (!((JSXOptions) options).allowNamespaces || !this.eat(colon)) return namespace;
return this.finishNode(new JSXNamespacedName(loc, namespace, this.jsx_parseIdentifier()));
IJSXName namespace = this.jsx_parseIdentifier(true);
if (namespace instanceof JSXThisExpr || (!((JSXOptions) options).allowNamespaces || !this.eat(colon))) return namespace;
return this.finishNode(new JSXNamespacedName(loc, (JSXIdentifier)namespace, (JSXIdentifier)this.jsx_parseIdentifier(false)));
}
/**
@ -258,7 +263,7 @@ public class JSXParser extends Parser {
}
while (this.eat(dot)) {
SourceLocation loc = new SourceLocation(startPos);
node = this.finishNode(new JSXMemberExpression(loc, node, this.jsx_parseIdentifier()));
node = this.finishNode(new JSXMemberExpression(loc, node, (JSXIdentifier)this.jsx_parseIdentifier(false)));
}
return node;
}

Просмотреть файл

@ -15,6 +15,7 @@ import com.semmle.js.ast.jsx.JSXMemberExpression;
import com.semmle.js.ast.jsx.JSXNamespacedName;
import com.semmle.js.ast.jsx.JSXOpeningElement;
import com.semmle.js.ast.jsx.JSXSpreadAttribute;
import com.semmle.js.ast.jsx.JSXThisExpr;
import com.semmle.ts.ast.ExportWholeDeclaration;
import com.semmle.ts.ast.ExternalModuleReference;
import com.semmle.ts.ast.ImportWholeDeclaration;
@ -635,6 +636,11 @@ public class AST2JSON extends DefaultVisitor<Void, JsonElement> {
return result;
}
@Override
public JsonElement visit(JSXThisExpr nd, Void c) {
return this.mkNode(nd, "JSXThisExpr");
}
@Override
public JsonElement visit(JSXMemberExpression nd, Void c) {
JsonObject result = this.mkNode(nd);

Просмотреть файл

@ -14,6 +14,7 @@ import com.semmle.js.ast.jsx.JSXMemberExpression;
import com.semmle.js.ast.jsx.JSXNamespacedName;
import com.semmle.js.ast.jsx.JSXOpeningElement;
import com.semmle.js.ast.jsx.JSXSpreadAttribute;
import com.semmle.js.ast.jsx.JSXThisExpr;
import com.semmle.ts.ast.ArrayTypeExpr;
import com.semmle.ts.ast.ConditionalTypeExpr;
import com.semmle.ts.ast.DecoratorList;
@ -498,6 +499,11 @@ public class DefaultVisitor<C, R> implements Visitor<C, R> {
return visit((IJSXName) nd, c);
}
@Override
public R visit(JSXThisExpr nd, C c) {
return visit((IJSXName) nd, c);
}
@Override
public R visit(JSXMemberExpression nd, C c) {
return visit((IJSXName) nd, c);

Просмотреть файл

@ -10,6 +10,7 @@ import com.semmle.js.ast.jsx.JSXMemberExpression;
import com.semmle.js.ast.jsx.JSXNamespacedName;
import com.semmle.js.ast.jsx.JSXOpeningElement;
import com.semmle.js.ast.jsx.JSXSpreadAttribute;
import com.semmle.js.ast.jsx.JSXThisExpr;
import com.semmle.ts.ast.ArrayTypeExpr;
import com.semmle.ts.ast.ConditionalTypeExpr;
import com.semmle.ts.ast.DecoratorList;
@ -567,6 +568,11 @@ public class NodeCopier implements Visitor<Void, INode> {
return new JSXIdentifier(visit(nd.getLoc()), nd.getName());
}
@Override
public INode visit(JSXThisExpr nd, Void c) {
return new JSXThisExpr(visit(nd.getLoc()));
}
@Override
public INode visit(JSXMemberExpression nd, Void c) {
return new JSXMemberExpression(visit(nd.getLoc()), copy(nd.getObject()), copy(nd.getName()));

Просмотреть файл

@ -10,6 +10,7 @@ import com.semmle.js.ast.jsx.JSXMemberExpression;
import com.semmle.js.ast.jsx.JSXNamespacedName;
import com.semmle.js.ast.jsx.JSXOpeningElement;
import com.semmle.js.ast.jsx.JSXSpreadAttribute;
import com.semmle.js.ast.jsx.JSXThisExpr;
import com.semmle.ts.ast.ArrayTypeExpr;
import com.semmle.ts.ast.ConditionalTypeExpr;
import com.semmle.ts.ast.DecoratorList;
@ -200,6 +201,8 @@ public interface Visitor<C, R> {
public R visit(JSXIdentifier nd, C c);
public R visit(JSXThisExpr nd, C c);
public R visit(JSXMemberExpression nd, C c);
public R visit(JSXNamespacedName nd, C c);

Просмотреть файл

@ -0,0 +1,21 @@
package com.semmle.js.ast.jsx;
import com.semmle.js.ast.ThisExpression;
import com.semmle.js.ast.SourceLocation;
import com.semmle.js.ast.Visitor;
public class JSXThisExpr extends ThisExpression implements IJSXName {
public JSXThisExpr(SourceLocation loc) {
super(loc);
}
@Override
public <C, R> R accept(Visitor<C, R> v, C c) {
return v.visit(this, c);
}
@Override
public String getQualifiedName() {
return "this";
}
}

Просмотреть файл

@ -82,6 +82,7 @@ import com.semmle.js.ast.SwitchStatement;
import com.semmle.js.ast.TaggedTemplateExpression;
import com.semmle.js.ast.TemplateElement;
import com.semmle.js.ast.TemplateLiteral;
import com.semmle.js.ast.ThisExpression;
import com.semmle.js.ast.ThrowStatement;
import com.semmle.js.ast.TryStatement;
import com.semmle.js.ast.UnaryExpression;
@ -105,6 +106,7 @@ import com.semmle.js.ast.jsx.JSXMemberExpression;
import com.semmle.js.ast.jsx.JSXNamespacedName;
import com.semmle.js.ast.jsx.JSXOpeningElement;
import com.semmle.js.ast.jsx.JSXSpreadAttribute;
import com.semmle.js.ast.jsx.JSXThisExpr;
import com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase;
import com.semmle.js.extractor.ExtractorConfig.Platform;
import com.semmle.js.extractor.ExtractorConfig.SourceType;
@ -1645,6 +1647,11 @@ public class ASTExtractor {
return visit((Identifier) nd, c);
}
@Override
public Label visit(JSXThisExpr nd, Context c) {
return visit((ThisExpression) nd, c);
}
@Override
public Label visit(JSXMemberExpression nd, Context c) {
Label key = super.visit(nd, c);

Просмотреть файл

@ -18,6 +18,7 @@ import com.semmle.js.ast.Literal;
import com.semmle.js.ast.LogicalExpression;
import com.semmle.js.ast.MemberExpression;
import com.semmle.js.ast.MetaProperty;
import com.semmle.js.ast.ThisExpression;
import com.semmle.js.ast.UnaryExpression;
import com.semmle.js.ast.UpdateExpression;
import com.semmle.js.ast.XMLAnyName;
@ -28,6 +29,7 @@ import com.semmle.js.ast.XMLQualifiedIdentifier;
import com.semmle.js.ast.jsx.JSXIdentifier;
import com.semmle.js.ast.jsx.JSXMemberExpression;
import com.semmle.js.ast.jsx.JSXSpreadAttribute;
import com.semmle.js.ast.jsx.JSXThisExpr;
import com.semmle.js.extractor.ASTExtractor.IdContext;
import com.semmle.ts.ast.DecoratorList;
import com.semmle.ts.ast.ExpressionWithTypeArguments;
@ -194,6 +196,11 @@ public class ExprKinds {
return visit((Identifier) nd, c);
}
@Override
public Integer visit(JSXThisExpr nd, Void c) {
return visit((ThisExpression) nd, c);
}
@Override
public Integer visit(LogicalExpression nd, Void q) {
return binOpKinds.get(nd.getOperator());

Просмотреть файл

@ -1,7 +1,10 @@
package com.semmle.js.extractor;
import java.io.File;
import java.nio.file.Path;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.Optional;
import com.semmle.js.parser.TypeScriptParser;
@ -23,6 +26,8 @@ public class ExtractorState {
private final ConcurrentHashMap<Path, FileSnippet> snippets = new ConcurrentHashMap<>();
private static final ConcurrentMap<File, Optional<String>> packageTypeCache = new ConcurrentHashMap<>();
public TypeScriptParser getTypeScriptParser() {
return typeScriptParser;
}
@ -36,6 +41,15 @@ public class ExtractorState {
return snippets;
}
/**
* Returns a cache for the "type" field in `package.json` files.
*
* <p>The map is thread-safe and may be mutated by the caller.
*/
public ConcurrentMap<File, Optional<String>> getPackageTypeCache() {
return this.packageTypeCache;
}
/**
* Makes this semantically equivalent to a fresh state, but may internally retain shared resources
* that are expensive to reacquire.
@ -43,5 +57,6 @@ public class ExtractorState {
public void reset() {
typeScriptParser.reset();
snippets.clear();
packageTypeCache.clear();
}
}

Просмотреть файл

@ -119,7 +119,7 @@ public class FileExtractor {
JS(".js", ".jsx", ".mjs", ".cjs", ".es6", ".es") {
@Override
public IExtractor mkExtractor(ExtractorConfig config, ExtractorState state) {
return new ScriptExtractor(config);
return new ScriptExtractor(config, state);
}
@Override

Просмотреть файл

@ -43,7 +43,7 @@ public class Main {
* A version identifier that should be updated every time the extractor changes in such a way that
* it may produce different tuples for the same file under the same {@link ExtractorConfig}.
*/
public static final String EXTRACTOR_VERSION = "2020-08-20-2";
public static final String EXTRACTOR_VERSION = "2020-08-24";
public static final Pattern NEWLINE = Pattern.compile("\n");

Просмотреть файл

@ -1,5 +1,16 @@
package com.semmle.js.extractor;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.ConcurrentMap;
import java.util.Optional;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.semmle.js.extractor.ExtractorConfig.Platform;
import com.semmle.js.extractor.ExtractorConfig.SourceType;
import com.semmle.js.parser.ParseError;
@ -9,19 +20,24 @@ import com.semmle.util.trap.TrapWriter.Label;
/** Extract a stand-alone JavaScript script. */
public class ScriptExtractor implements IExtractor {
private ExtractorConfig config;
private ConcurrentMap<File, Optional<String>> packageTypeCache;
public ScriptExtractor(ExtractorConfig config) {
public ScriptExtractor(ExtractorConfig config, ExtractorState state) {
this.config = config;
this.packageTypeCache = state.getPackageTypeCache();
}
/** True if files with the given extension should always be treated as modules. */
private boolean isAlwaysModule(String extension) {
return extension.equals(".mjs") || extension.equals(".es6") || extension.equals(".es");
/** True if files with the given extension and type (from package.json) should always be treated as ES2015 modules. */
private boolean isAlwaysModule(String extension, String packageType) {
if (extension.equals(".mjs") || extension.equals(".es6") || extension.equals(".es")) {
return true;
}
return "module".equals(packageType) && extension.equals(".js");
}
/** True if files with the given extension should always be treated as CommonJS modules. */
private boolean isAlwaysCommonJSModule(String extension) {
return extension.equals(".cjs");
/** True if files with the given extension and type (from package.json) should always be treated as CommonJS modules. */
private boolean isAlwaysCommonJSModule(String extension, String packageType) {
return extension.equals(".cjs") || (extension.equals(".js") && "commonjs".equals(packageType));
}
@Override
@ -49,13 +65,16 @@ public class ScriptExtractor implements IExtractor {
locationManager.setStart(2, 1);
}
// Some file extensions are interpreted as modules by default.
String packageType = getPackageType(locationManager.getSourceFile().getParentFile());
String extension = locationManager.getSourceFileExtension();
// Some files are interpreted as modules by default.
if (config.getSourceType() == SourceType.AUTO) {
if (isAlwaysModule(locationManager.getSourceFileExtension())) {
if (isAlwaysModule(extension, packageType)) {
config = config.withSourceType(SourceType.MODULE);
}
if (isAlwaysCommonJSModule(locationManager.getSourceFileExtension())) {
config = config.withSourceType(SourceType.COMMONJS_MODULE);
if (isAlwaysCommonJSModule(extension, packageType)) {
config = config.withSourceType(SourceType.COMMONJS_MODULE).withPlatform(Platform.NODE);
}
}
@ -78,4 +97,40 @@ public class ScriptExtractor implements IExtractor {
return loc;
}
/**
* A minimal model of `package.json` files that can be used to read the "type" field.
*/
private static class PackageJSON {
String type;
}
/**
* Returns the "type" field from the nearest `package.json` file (searching up the file hierarchy).
*/
private String getPackageType(File folder) {
if (folder == null || !folder.isDirectory()) {
return null;
}
if (packageTypeCache.containsKey(folder)) {
return packageTypeCache.get(folder).orElse(null);
}
File file = new File(folder, "package.json");
if (file.isDirectory()) {
return null;
}
if (!file.exists()) {
String result = getPackageType(folder.getParentFile());
packageTypeCache.put(folder, Optional.ofNullable(result));
return result;
}
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
String result = new Gson().fromJson(reader, PackageJSON.class).type;
packageTypeCache.put(folder, Optional.ofNullable(result));
return result;
} catch (IOException | JsonSyntaxException e) {
return null;
}
}
}

Просмотреть файл

@ -111,6 +111,7 @@ import com.semmle.js.ast.jsx.JSXIdentifier;
import com.semmle.js.ast.jsx.JSXMemberExpression;
import com.semmle.js.ast.jsx.JSXOpeningElement;
import com.semmle.js.ast.jsx.JSXSpreadAttribute;
import com.semmle.js.ast.jsx.JSXThisExpr;
import com.semmle.js.parser.JSParser.Result;
import com.semmle.ts.ast.ArrayTypeExpr;
import com.semmle.ts.ast.ConditionalTypeExpr;
@ -2377,7 +2378,7 @@ public class TypeScriptASTConverter {
convertJSXName(me.getObject()),
(JSXIdentifier) convertJSXName(me.getProperty()));
}
if (e instanceof ThisExpression) return new JSXIdentifier(e.getLoc(), "this");
if (e instanceof ThisExpression) return new JSXThisExpr(e.getLoc());
return (IJSXName) e;
}

Просмотреть файл

@ -60,82 +60,89 @@ toplevels(#20001,0)
#20020=@"loc,{#10000},1,1,2,0"
locations_default(#20020,#10000,1,1,2,0)
hasLocation(#20001,#20020)
#20021=@"module;{#10000},1,1"
scopes(#20021,3)
scopenodes(#20001,#20021)
scopenesting(#20021,#20000)
#20022=@"var;{require};{#20021}"
variables(#20022,"require",#20021)
#20023=@"var;{module};{#20021}"
variables(#20023,"module",#20021)
#20024=@"var;{exports};{#20021}"
variables(#20024,"exports",#20021)
#20025=@"var;{__filename};{#20021}"
variables(#20025,"__filename",#20021)
#20026=@"var;{__dirname};{#20021}"
variables(#20026,"__dirname",#20021)
#20027=@"var;{arguments};{#20021}"
variables(#20027,"arguments",#20021)
#20021=@"var;{global};{#20000}"
variables(#20021,"global",#20000)
#20022=@"var;{process};{#20000}"
variables(#20022,"process",#20000)
#20023=@"var;{console};{#20000}"
variables(#20023,"console",#20000)
#20024=@"var;{Buffer};{#20000}"
variables(#20024,"Buffer",#20000)
#20025=@"module;{#10000},1,1"
scopes(#20025,3)
scopenodes(#20001,#20025)
scopenesting(#20025,#20000)
#20026=@"var;{require};{#20025}"
variables(#20026,"require",#20025)
#20027=@"var;{module};{#20025}"
variables(#20027,"module",#20025)
#20028=@"var;{exports};{#20025}"
variables(#20028,"exports",#20025)
#20029=@"var;{__filename};{#20025}"
variables(#20029,"__filename",#20025)
#20030=@"var;{__dirname};{#20025}"
variables(#20030,"__dirname",#20025)
#20031=@"var;{arguments};{#20025}"
variables(#20031,"arguments",#20025)
isModule(#20001)
#20028=*
stmts(#20028,2,#20001,0,"console ... onJS"");")
hasLocation(#20028,#20003)
stmtContainers(#20028,#20001)
#20029=*
exprs(#20029,13,#20028,0,"console ... monJS"")")
#20030=@"loc,{#10000},1,1,1,29"
locations_default(#20030,#10000,1,1,1,29)
hasLocation(#20029,#20030)
enclosingStmt(#20029,#20028)
exprContainers(#20029,#20001)
#20031=*
exprs(#20031,14,#20029,-1,"console.log")
#20032=@"loc,{#10000},1,1,1,11"
locations_default(#20032,#10000,1,1,1,11)
hasLocation(#20031,#20032)
enclosingStmt(#20031,#20028)
exprContainers(#20031,#20001)
#20032=*
stmts(#20032,2,#20001,0,"console ... onJS"");")
hasLocation(#20032,#20003)
stmtContainers(#20032,#20001)
#20033=*
exprs(#20033,79,#20031,0,"console")
hasLocation(#20033,#20005)
enclosingStmt(#20033,#20028)
exprs(#20033,13,#20032,0,"console ... monJS"")")
#20034=@"loc,{#10000},1,1,1,29"
locations_default(#20034,#10000,1,1,1,29)
hasLocation(#20033,#20034)
enclosingStmt(#20033,#20032)
exprContainers(#20033,#20001)
literals("console","console",#20033)
#20034=@"var;{console};{#20000}"
variables(#20034,"console",#20000)
bind(#20033,#20034)
#20035=*
exprs(#20035,0,#20031,1,"log")
hasLocation(#20035,#20009)
enclosingStmt(#20035,#20028)
exprs(#20035,14,#20033,-1,"console.log")
#20036=@"loc,{#10000},1,1,1,11"
locations_default(#20036,#10000,1,1,1,11)
hasLocation(#20035,#20036)
enclosingStmt(#20035,#20032)
exprContainers(#20035,#20001)
literals("log","log",#20035)
#20036=*
exprs(#20036,4,#20029,0,"""Hello CommonJS""")
hasLocation(#20036,#20013)
enclosingStmt(#20036,#20028)
exprContainers(#20036,#20001)
literals("Hello CommonJS","""Hello CommonJS""",#20036)
#20037=*
regexpterm(#20037,14,#20036,0,"Hello CommonJS")
#20038=@"loc,{#10000},1,14,1,27"
locations_default(#20038,#10000,1,14,1,27)
hasLocation(#20037,#20038)
regexpConstValue(#20037,"Hello CommonJS")
exprs(#20037,79,#20035,0,"console")
hasLocation(#20037,#20005)
enclosingStmt(#20037,#20032)
exprContainers(#20037,#20001)
literals("console","console",#20037)
bind(#20037,#20023)
#20038=*
exprs(#20038,0,#20035,1,"log")
hasLocation(#20038,#20009)
enclosingStmt(#20038,#20032)
exprContainers(#20038,#20001)
literals("log","log",#20038)
#20039=*
entry_cfg_node(#20039,#20001)
#20040=@"loc,{#10000},1,1,1,0"
locations_default(#20040,#10000,1,1,1,0)
hasLocation(#20039,#20040)
#20041=*
exit_cfg_node(#20041,#20001)
hasLocation(#20041,#20019)
successor(#20028,#20033)
successor(#20036,#20029)
successor(#20035,#20031)
successor(#20033,#20035)
successor(#20031,#20036)
successor(#20029,#20041)
successor(#20039,#20028)
exprs(#20039,4,#20033,0,"""Hello CommonJS""")
hasLocation(#20039,#20013)
enclosingStmt(#20039,#20032)
exprContainers(#20039,#20001)
literals("Hello CommonJS","""Hello CommonJS""",#20039)
#20040=*
regexpterm(#20040,14,#20039,0,"Hello CommonJS")
#20041=@"loc,{#10000},1,14,1,27"
locations_default(#20041,#10000,1,14,1,27)
hasLocation(#20040,#20041)
regexpConstValue(#20040,"Hello CommonJS")
#20042=*
entry_cfg_node(#20042,#20001)
#20043=@"loc,{#10000},1,1,1,0"
locations_default(#20043,#10000,1,1,1,0)
hasLocation(#20042,#20043)
#20044=*
exit_cfg_node(#20044,#20001)
hasLocation(#20044,#20019)
successor(#20032,#20037)
successor(#20039,#20033)
successor(#20038,#20035)
successor(#20037,#20038)
successor(#20035,#20039)
successor(#20033,#20044)
successor(#20042,#20032)
isNodejs(#20001)
numlines(#10000,1,1,0)
filetype(#10000,"javascript")

Просмотреть файл

@ -0,0 +1,3 @@
// I'm invalid JSON
{
"type": "foo"

Просмотреть файл

Просмотреть файл

@ -0,0 +1,15 @@
#10000=@"/package.json;sourcefile"
files(#10000,"/package.json","package","json",0)
#10001=@"/;folder"
folders(#10001,"/","")
containerparent(#10001,#10000)
#10002=@"loc,{#10000},0,0,0,0"
locations_default(#10002,#10000,0,0,0,0)
hasLocation(#10000,#10002)
#20000=*
json_errors(#20000,"Error: Unexpected token")
#20001=@"loc,{#10000},3,1,3,1"
locations_default(#20001,#10000,3,1,3,1)
hasLocation(#20000,#20001)
numlines(#10000,3,0,0)
filetype(#10000,"json")

Просмотреть файл

@ -0,0 +1,28 @@
#10000=@"/tst.js;sourcefile"
files(#10000,"/tst.js","tst","js",0)
#10001=@"/;folder"
folders(#10001,"/","")
containerparent(#10001,#10000)
#10002=@"loc,{#10000},0,0,0,0"
locations_default(#10002,#10000,0,0,0,0)
hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=@"script;{#10000},1,1"
numlines(#20001,0,0,0)
#20002=*
tokeninfo(#20002,0,#20001,0,"")
#20003=@"loc,{#10000},1,1,1,0"
locations_default(#20003,#10000,1,1,1,0)
hasLocation(#20002,#20003)
toplevels(#20001,0)
hasLocation(#20001,#20003)
#20004=*
entry_cfg_node(#20004,#20001)
hasLocation(#20004,#20003)
#20005=*
exit_cfg_node(#20005,#20001)
hasLocation(#20005,#20003)
successor(#20004,#20005)
numlines(#10000,0,0,0)
filetype(#10000,"javascript")

Просмотреть файл

@ -0,0 +1,3 @@
{
"type": 123
}

Просмотреть файл

Просмотреть файл

@ -0,0 +1,22 @@
#10000=@"/package.json;sourcefile"
files(#10000,"/package.json","package","json",0)
#10001=@"/;folder"
folders(#10001,"/","")
containerparent(#10001,#10000)
#10002=@"loc,{#10000},0,0,0,0"
locations_default(#10002,#10000,0,0,0,0)
hasLocation(#10000,#10002)
#20000=*
json(#20000,5,#10000,0,"{\n ""type"": 123\n}")
#20001=@"loc,{#10000},1,1,3,1"
locations_default(#20001,#10000,1,1,3,1)
json_locations(#20000,#20001)
#20002=*
json(#20002,2,#20000,0,"123")
#20003=@"loc,{#10000},2,11,2,13"
locations_default(#20003,#10000,2,11,2,13)
json_locations(#20002,#20003)
json_literals("123","123",#20002)
json_properties(#20000,"type",#20002)
numlines(#10000,3,0,0)
filetype(#10000,"json")

Просмотреть файл

@ -0,0 +1,28 @@
#10000=@"/tst2.js;sourcefile"
files(#10000,"/tst2.js","tst2","js",0)
#10001=@"/;folder"
folders(#10001,"/","")
containerparent(#10001,#10000)
#10002=@"loc,{#10000},0,0,0,0"
locations_default(#10002,#10000,0,0,0,0)
hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=@"script;{#10000},1,1"
numlines(#20001,0,0,0)
#20002=*
tokeninfo(#20002,0,#20001,0,"")
#20003=@"loc,{#10000},1,1,1,0"
locations_default(#20003,#10000,1,1,1,0)
hasLocation(#20002,#20003)
toplevels(#20001,0)
hasLocation(#20001,#20003)
#20004=*
entry_cfg_node(#20004,#20001)
hasLocation(#20004,#20003)
#20005=*
exit_cfg_node(#20005,#20001)
hasLocation(#20005,#20003)
successor(#20004,#20005)
numlines(#10000,0,0,0)
filetype(#10000,"javascript")

Просмотреть файл

@ -301,94 +301,90 @@ hasLocation(#20099,#20100)
enclosingStmt(#20099,#20077)
exprContainers(#20099,#20001)
#20101=*
exprs(#20101,79,#20099,0,"this")
exprs(#20101,6,#20099,0,"this")
hasLocation(#20101,#20039)
enclosingStmt(#20101,#20077)
exprContainers(#20101,#20001)
literals("this","this",#20101)
#20102=@"var;{this};{#20000}"
variables(#20102,"this",#20000)
bind(#20101,#20102)
#20102=*
exprs(#20102,0,#20099,1,"props")
hasLocation(#20102,#20043)
enclosingStmt(#20102,#20077)
exprContainers(#20102,#20001)
literals("props","props",#20102)
#20103=*
exprs(#20103,0,#20099,1,"props")
hasLocation(#20103,#20043)
exprs(#20103,0,#20097,1,"icon")
hasLocation(#20103,#20047)
enclosingStmt(#20103,#20077)
exprContainers(#20103,#20001)
literals("props","props",#20103)
literals("icon","icon",#20103)
#20104=*
exprs(#20104,0,#20097,1,"icon")
hasLocation(#20104,#20047)
exprs(#20104,4,#20079,-4,"")
#20105=@"loc,{#10000},3,3,3,2"
locations_default(#20105,#10000,3,3,3,2)
hasLocation(#20104,#20105)
enclosingStmt(#20104,#20077)
exprContainers(#20104,#20001)
literals("icon","icon",#20104)
#20105=*
exprs(#20105,4,#20079,-4,"")
#20106=@"loc,{#10000},3,3,3,2"
locations_default(#20106,#10000,3,3,3,2)
hasLocation(#20105,#20106)
enclosingStmt(#20105,#20077)
exprContainers(#20105,#20001)
literals("
","",#20105)
#20107=*
regexpterm(#20107,14,#20105,0,"
","",#20104)
#20106=*
regexpterm(#20106,14,#20104,0,"
")
#20108=@"loc,{#10000},3,4,3,6"
locations_default(#20108,#10000,3,4,3,6)
hasLocation(#20107,#20108)
regexpConstValue(#20107,"
#20107=@"loc,{#10000},3,4,3,6"
locations_default(#20107,#10000,3,4,3,6)
hasLocation(#20106,#20107)
regexpConstValue(#20106,"
")
#20109=*
exprs(#20109,89,#20079,-5,"<name-with-dashes/>")
#20110=@"loc,{#10000},3,3,3,21"
locations_default(#20110,#10000,3,3,3,21)
hasLocation(#20109,#20110)
enclosingStmt(#20109,#20077)
exprContainers(#20109,#20001)
#20111=*
exprs(#20111,0,#20109,-1,"name-with-dashes")
#20112=@"loc,{#10000},3,4,3,19"
locations_default(#20112,#10000,3,4,3,19)
hasLocation(#20111,#20112)
enclosingStmt(#20111,#20077)
exprContainers(#20111,#20001)
literals("name-with-dashes","name-with-dashes",#20111)
#20113=*
exprs(#20113,4,#20079,-6,"")
#20114=@"loc,{#10000},4,1,4,0"
locations_default(#20114,#10000,4,1,4,0)
hasLocation(#20113,#20114)
enclosingStmt(#20113,#20077)
exprContainers(#20113,#20001)
#20108=*
exprs(#20108,89,#20079,-5,"<name-with-dashes/>")
#20109=@"loc,{#10000},3,3,3,21"
locations_default(#20109,#10000,3,3,3,21)
hasLocation(#20108,#20109)
enclosingStmt(#20108,#20077)
exprContainers(#20108,#20001)
#20110=*
exprs(#20110,0,#20108,-1,"name-with-dashes")
#20111=@"loc,{#10000},3,4,3,19"
locations_default(#20111,#10000,3,4,3,19)
hasLocation(#20110,#20111)
enclosingStmt(#20110,#20077)
exprContainers(#20110,#20001)
literals("name-with-dashes","name-with-dashes",#20110)
#20112=*
exprs(#20112,4,#20079,-6,"")
#20113=@"loc,{#10000},4,1,4,0"
locations_default(#20113,#10000,4,1,4,0)
hasLocation(#20112,#20113)
enclosingStmt(#20112,#20077)
exprContainers(#20112,#20001)
literals("
","",#20113)
#20115=*
regexpterm(#20115,14,#20113,0,"
","",#20112)
#20114=*
regexpterm(#20114,14,#20112,0,"
")
#20116=@"loc,{#10000},4,2,4,2"
locations_default(#20116,#10000,4,2,4,2)
hasLocation(#20115,#20116)
regexpConstValue(#20115,"
#20115=@"loc,{#10000},4,2,4,2"
locations_default(#20115,#10000,4,2,4,2)
hasLocation(#20114,#20115)
regexpConstValue(#20114,"
")
#20117=*
entry_cfg_node(#20117,#20001)
#20118=@"loc,{#10000},1,1,1,0"
locations_default(#20118,#10000,1,1,1,0)
hasLocation(#20117,#20118)
#20119=*
exit_cfg_node(#20119,#20001)
hasLocation(#20119,#20075)
#20116=*
entry_cfg_node(#20116,#20001)
#20117=@"loc,{#10000},1,1,1,0"
locations_default(#20117,#10000,1,1,1,0)
hasLocation(#20116,#20117)
#20118=*
exit_cfg_node(#20118,#20001)
hasLocation(#20118,#20075)
successor(#20077,#20080)
successor(#20113,#20079)
successor(#20111,#20109)
successor(#20109,#20113)
successor(#20105,#20111)
successor(#20104,#20097)
successor(#20103,#20099)
successor(#20101,#20103)
successor(#20099,#20104)
successor(#20112,#20079)
successor(#20110,#20108)
successor(#20108,#20112)
successor(#20104,#20110)
successor(#20103,#20097)
successor(#20102,#20099)
successor(#20101,#20102)
successor(#20099,#20103)
successor(#20097,#20095)
successor(#20095,#20105)
successor(#20095,#20104)
successor(#20091,#20101)
successor(#20089,#20086)
successor(#20088,#20089)
@ -397,7 +393,7 @@ successor(#20084,#20081)
successor(#20083,#20084)
successor(#20081,#20088)
successor(#20080,#20083)
successor(#20079,#20119)
successor(#20117,#20077)
successor(#20079,#20118)
successor(#20116,#20077)
numlines(#10000,4,4,0)
filetype(#10000,"typescript")

Просмотреть файл

@ -8,7 +8,7 @@
* @id js/duplicate-html-id
* @tags maintainability
* correctness
* @precision high
* @precision low
*/
import javascript

Просмотреть файл

@ -6,7 +6,7 @@
<overview>
<p>
Sanitizing untrusted input for HTML meta-characters is an important
Sanitizing untrusted input for HTML meta-characters is a common
technique for preventing cross-site scripting attacks. Usually, this
is done by escaping <code>&lt;</code>, <code>&gt;</code>,
<code>&amp;</code> and <code>&quot;</code>. However, the context in which
@ -38,6 +38,14 @@
</p>
<p>
An even safer alternative is to design the application
so that sanitization is not needed, for instance by using HTML
templates that are explicit about the values they treat as HTML.
</p>
</recommendation>
<example>

Просмотреть файл

@ -5,7 +5,7 @@
<overview>
<p>
Sanitizing untrusted input is an important technique for preventing injection attacks such as
Sanitizing untrusted input is a common technique for preventing injection attacks such as
SQL injection or cross-site scripting. Usually, this is done by escaping meta-characters such
as quotes in a domain-specific way so that they are treated as normal characters.
</p>
@ -31,6 +31,14 @@ still have undesirable effects, such as badly rendered or confusing output.
Use a (well-tested) sanitization library if at all possible. These libraries are much more
likely to handle corner cases correctly than a custom implementation.
</p>
<p>
An even safer alternative is to design the application so that sanitization is not
needed, for instance by using prepared statements for SQL queries.
</p>
<p>
Otherwise, make sure to use a regular expression with the <code>g</code> flag to ensure that
all occurrences are replaced, and remember to escape backslashes if applicable.

Просмотреть файл

@ -6,8 +6,8 @@
<overview>
<p>
Sanitizing untrusted input for HTML meta-characters is an
important technique for preventing cross-site scripting attacks. But
Sanitizing untrusted input for HTML meta-characters is a
common technique for preventing cross-site scripting attacks. But
even a sanitized input can be dangerous to use if it is modified
further before a browser treats it as HTML.
@ -28,6 +28,15 @@
them as HTML.
</p>
<p>
An even safer alternative is to design the application
so that sanitization is not needed, for instance by using HTML
templates that are explicit about the values they treat as HTML.
</p>
</recommendation>
<example>

Просмотреть файл

@ -4,7 +4,7 @@
<overview>
<p>
Sanitizing untrusted HTTP request parameters is an important
Sanitizing untrusted HTTP request parameters is a common
technique for preventing injection attacks such as SQL injection or
path traversal. This is sometimes done by checking if the request
parameters contain blacklisted substrings.
@ -35,6 +35,15 @@
is user-controlled.
</p>
<p>
An even safer alternative is to design the application so that sanitization is not
needed, for instance by using prepared statements for SQL queries.
</p>
</recommendation>
<example>

Просмотреть файл

@ -0,0 +1,26 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Failing to set the 'secure' flag on a cookie can cause it to be sent in cleartext.
This makes it easier for an attacker to intercept.</p>
</overview>
<recommendation>
<p>Always set the <code>secure</code> flag to `true` on a cookie before adding it
to an HTTP response (if the default value is `false`).</p>
</recommendation>
<references>
<li>Production Best Practices: Security:<a href="https://expressjs.com/en/advanced/best-practice-security.html#use-cookies-securely">Use cookies securely</a>.</li>
<li>NodeJS security cheat sheet:<a href="https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html#set-cookie-flags-appropriately">Set cookie flags appropriately</a>.</li>
<li>express-session:<a href="https://github.com/expressjs/session#cookiesecure">cookie.secure</a>.</li>
<li>cookie-session:<a href="https://github.com/expressjs/cookie-session#cookie-options">Cookie Options</a>.</li>
<li><a href="https://expressjs.com/en/api.html#res.cookie">express response.cookie</a>.</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie">Set-Cookie</a>.</li>
<li><a href="https://github.com/js-cookie/js-cookie">js-cookie</a>.</li>
</references>
</qhelp>

Просмотреть файл

@ -0,0 +1,18 @@
/**
* @name Failure to set secure cookies
* @description Insecure cookies may be sent in cleartext, which makes them vulnerable to
* interception.
* @kind problem
* @problem.severity error
* @precision high
* @id js/insecure-cookie
* @tags security
* external/cwe/cwe-614
*/
import javascript
import InsecureCookie::Cookie
from Cookie cookie
where not cookie.isSecure()
select cookie, "Cookie is added to response without the 'secure' flag being set to true"

Просмотреть файл

@ -0,0 +1,146 @@
/**
* Provides classes for reasoning about cookies added to response without the 'secure' flag being set.
* A cookie without the 'secure' flag being set can be intercepted and read by a malicious user.
*/
import javascript
module Cookie {
/**
* `secure` property of the cookie options.
*/
string flag() { result = "secure" }
/**
* Abstract class to represent different cases of insecure cookie settings.
*/
abstract class Cookie extends DataFlow::Node {
/**
* Gets the name of the middleware/library used to set the cookie.
*/
abstract string getKind();
/**
* Gets the options used to set this cookie, if any.
*/
abstract DataFlow::Node getCookieOptionsArgument();
/**
* Holds if this cookie is secure.
*/
abstract predicate isSecure();
}
/**
* A cookie set using the `express` module `cookie-session` (https://github.com/expressjs/cookie-session).
*/
class InsecureCookieSession extends ExpressLibraries::CookieSession::MiddlewareInstance, Cookie {
override string getKind() { result = "cookie-session" }
override DataFlow::SourceNode getCookieOptionsArgument() { result = this.getOption("cookie") }
private DataFlow::Node getCookieFlagValue(string flag) {
result = this.getCookieOptionsArgument().getAPropertyWrite(flag).getRhs()
}
override predicate isSecure() {
// The flag `secure` is set to `false` by default for HTTP, `true` by default for HTTPS (https://github.com/expressjs/cookie-session#cookie-options).
// A cookie is secure if the `secure` flag is not explicitly set to `false`.
not getCookieFlagValue(flag()).mayHaveBooleanValue(false)
}
}
/**
* A cookie set using the `express` module `express-session` (https://github.com/expressjs/session).
*/
class InsecureExpressSessionCookie extends ExpressLibraries::ExpressSession::MiddlewareInstance,
Cookie {
override string getKind() { result = "express-session" }
override DataFlow::SourceNode getCookieOptionsArgument() { result = this.getOption("cookie") }
private DataFlow::Node getCookieFlagValue(string flag) {
result = this.getCookieOptionsArgument().getAPropertyWrite(flag).getRhs()
}
override predicate isSecure() {
// The flag `secure` is not set by default (https://github.com/expressjs/session#Cookieecure).
// The default value for cookie options is { path: '/', httpOnly: true, secure: false, maxAge: null }.
// A cookie is secure if there are the cookie options with the `secure` flag set to `true` or to `auto`.
getCookieFlagValue(flag()).mayHaveBooleanValue(true) or
getCookieFlagValue(flag()).mayHaveStringValue("auto")
}
}
/**
* A cookie set using `response.cookie` from `express` module (https://expressjs.com/en/api.html#res.cookie).
*/
class InsecureExpressCookieResponse extends Cookie, DataFlow::MethodCallNode {
InsecureExpressCookieResponse() { this.calls(any(Express::ResponseExpr r).flow(), "cookie") }
override string getKind() { result = "response.cookie" }
override DataFlow::SourceNode getCookieOptionsArgument() {
result = this.getLastArgument().getALocalSource()
}
private DataFlow::Node getCookieFlagValue(string flag) {
result = this.getCookieOptionsArgument().getAPropertyWrite(flag).getRhs()
}
override predicate isSecure() {
// A cookie is secure if there are cookie options with the `secure` flag set to `true`.
getCookieFlagValue(flag()).mayHaveBooleanValue(true)
}
}
/**
* A cookie set using `Set-Cookie` header of an `HTTP` response (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie).
*/
class InsecureSetCookieHeader extends Cookie {
InsecureSetCookieHeader() {
this.asExpr() = any(HTTP::SetCookieHeader setCookie).getHeaderArgument()
}
override string getKind() { result = "set-cookie header" }
override DataFlow::Node getCookieOptionsArgument() {
result.asExpr() = this.asExpr().(ArrayExpr).getAnElement()
}
override predicate isSecure() {
// A cookie is secure if the 'secure' flag is specified in the cookie definition.
exists(string s |
getCookieOptionsArgument().mayHaveStringValue(s) and
s.regexpMatch("(.*;)?\\s*secure.*")
)
}
}
/**
* A cookie set using `js-cookie` library (https://github.com/js-cookie/js-cookie).
*/
class InsecureJsCookie extends Cookie {
InsecureJsCookie() {
this =
[DataFlow::globalVarRef("Cookie"),
DataFlow::globalVarRef("Cookie").getAMemberCall("noConflict"),
DataFlow::moduleImport("js-cookie")].getAMemberCall("set")
}
override string getKind() { result = "js-cookie" }
override DataFlow::SourceNode getCookieOptionsArgument() {
result = this.(DataFlow::CallNode).getAnArgument().getALocalSource()
}
DataFlow::Node getCookieFlagValue(string flag) {
result = this.getCookieOptionsArgument().getAPropertyWrite(flag).getRhs()
}
override predicate isSecure() {
// A cookie is secure if there are cookie options with the `secure` flag set to `true`.
getCookieFlagValue(flag()).mayHaveBooleanValue(true)
}
}
}

Просмотреть файл

@ -181,6 +181,7 @@ class JSXQualifiedName extends Expr, @jsxqualifiedname {
class JSXName extends Expr {
JSXName() {
this instanceof Identifier or
this instanceof ThisExpr or
this.(DotExpr).getBase() instanceof JSXName or
this instanceof JSXQualifiedName
}
@ -198,6 +199,9 @@ class JSXName extends Expr {
exists(JSXQualifiedName qual | qual = this |
result = qual.getNamespace().getName() + ":" + qual.getName().getName()
)
or
this instanceof ThisExpr and
result = "this"
}
}

Просмотреть файл

@ -162,6 +162,17 @@ private predicate isRequire(DataFlow::Node nd) {
not nd.getFile().getExtension() = "mjs"
or
isRequire(nd.getAPredecessor())
or
// `import { createRequire } from 'module';` support.
// specialized to ES2015 modules to avoid recursion in the `DataFlow::moduleImport()` predicate.
exists(ImportDeclaration imp | imp.getImportedPath().getValue() = "module" |
nd =
imp
.getImportedModuleNode()
.(DataFlow::SourceNode)
.getAPropertyRead("createRequire")
.getACall()
)
}
/**

Просмотреть файл

@ -0,0 +1 @@
console.log(".mjs inside a `type:\"commonjs\" is still a ES2015 module`");

Просмотреть файл

@ -0,0 +1,3 @@
{
"type": "commonjs"
}

Просмотреть файл

@ -0,0 +1 @@
console.log("I'm empty! The containing package.json determines the type.");

Просмотреть файл

@ -0,0 +1,3 @@
{
"type": "module"
}

Просмотреть файл

@ -0,0 +1 @@
console.log(".cjs inside a `type:\"module\" is still a CommonJS module`");

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше