mirror of
https://github.com/github/codeql.git
synced 2026-06-06 05:57:07 +02:00
Compare commits
150 Commits
codeql-cli
...
yoff/pytho
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b783ed69c5 | ||
|
|
5b9803e03c | ||
|
|
b2ff09f70a | ||
|
|
4aee0b3c87 | ||
|
|
a2295e7216 | ||
|
|
0623acc7f5 | ||
|
|
dc5aa8e0f5 | ||
|
|
db1e5035b4 | ||
|
|
7a3f546587 | ||
|
|
821325b7e5 | ||
|
|
4d2296d4f0 | ||
|
|
aaa3b363e1 | ||
|
|
9dbe9adb00 | ||
|
|
703cea2b65 | ||
|
|
e6e8e3d005 | ||
|
|
adc9b7714b | ||
|
|
e706c5f444 | ||
|
|
8a1e6d4f64 | ||
|
|
1a747dd8be | ||
|
|
28bb1a6870 | ||
|
|
45b1253b23 | ||
|
|
c99dab1d71 | ||
|
|
f3e3647209 | ||
|
|
8d099cbe38 | ||
|
|
9618e9b35c | ||
|
|
ab4a575243 | ||
|
|
d2f474d998 | ||
|
|
22b08f1ea4 | ||
|
|
e18448dd59 | ||
|
|
a16f1c555c | ||
|
|
43c1152634 | ||
|
|
caae5a8bf1 | ||
|
|
cfb18c2477 | ||
|
|
4c31866910 | ||
|
|
09371339d7 | ||
|
|
6165623cbf | ||
|
|
2eac8890d3 | ||
|
|
2d581504f7 | ||
|
|
9f211cebd5 | ||
|
|
8393b40b59 | ||
|
|
f8ab76e1ba | ||
|
|
34d4e9a8e2 | ||
|
|
ed8b9c29cc | ||
|
|
7718fe40a0 | ||
|
|
aeb82858d7 | ||
|
|
c08cf81665 | ||
|
|
e06158629e | ||
|
|
3e09961662 | ||
|
|
17fe3e4e31 | ||
|
|
313500e581 | ||
|
|
ad56ebd361 | ||
|
|
6be9e2315d | ||
|
|
5c2488e304 | ||
|
|
4fbea4ef95 | ||
|
|
35faec3db1 | ||
|
|
5f54a8691d | ||
|
|
41fd59c1c1 | ||
|
|
d6e7e38e1c | ||
|
|
7723324687 | ||
|
|
d4c7b5b6fe | ||
|
|
6b55f865cd | ||
|
|
42c4d8a98b | ||
|
|
f962eac914 | ||
|
|
c6c3e1474c | ||
|
|
94e6ec6511 | ||
|
|
c902c75651 | ||
|
|
2b4ea18dfe | ||
|
|
98b7659cc1 | ||
|
|
d9c0b9ca31 | ||
|
|
b44bca9ea7 | ||
|
|
e66b1e4beb | ||
|
|
362c48cc6d | ||
|
|
35364a087a | ||
|
|
780591d42a | ||
|
|
3aa69823af | ||
|
|
f18cdcfec6 | ||
|
|
7862922e5c | ||
|
|
fbc861e7a4 | ||
|
|
7f2fb2eb99 | ||
|
|
769b1957a5 | ||
|
|
26da373bd4 | ||
|
|
e07f45fff4 | ||
|
|
3adb7043e8 | ||
|
|
7dcd2d6ab6 | ||
|
|
b6c2915f24 | ||
|
|
6825ccc74f | ||
|
|
c0273ae94f | ||
|
|
1c01bb32d9 | ||
|
|
c3bb5e8eff | ||
|
|
9d0d4e4912 | ||
|
|
a2ac0ab7d5 | ||
|
|
42aaae7cf3 | ||
|
|
cb0fc786c7 | ||
|
|
dd9c066c61 | ||
|
|
f4f85b58ca | ||
|
|
caef72b047 | ||
|
|
9787a8b072 | ||
|
|
c8f7c3d7f2 | ||
|
|
ea6f3a9568 | ||
|
|
5d6dc5c3c3 | ||
|
|
554bdf14b2 | ||
|
|
b031e5b1f8 | ||
|
|
7fa6c4e4a3 | ||
|
|
600a4969c9 | ||
|
|
55194dd757 | ||
|
|
cbe4c81ca6 | ||
|
|
3b7a53f678 | ||
|
|
ccc1dd5d3e | ||
|
|
a966dff76e | ||
|
|
6b58482dfb | ||
|
|
2307839050 | ||
|
|
92838011dd | ||
|
|
5772ee4d9b | ||
|
|
72b683d63c | ||
|
|
8a2a48d2dd | ||
|
|
5d0cb9e805 | ||
|
|
bb9e996cb6 | ||
|
|
c3a9218dcf | ||
|
|
a049850c51 | ||
|
|
49f19092fb | ||
|
|
f668b99d6d | ||
|
|
bfe5aa8d42 | ||
|
|
52d72836f9 | ||
|
|
eb480d1de4 | ||
|
|
1ef557c972 | ||
|
|
2eee2e50dc | ||
|
|
2010844b1e | ||
|
|
406a02fa49 | ||
|
|
6e5e650b42 | ||
|
|
eba9f35673 | ||
|
|
e1a0e204b1 | ||
|
|
5e14a7574e | ||
|
|
6ff404a6d0 | ||
|
|
9902beddec | ||
|
|
e6eac3784a | ||
|
|
5784ef22f6 | ||
|
|
bc96ae6e47 | ||
|
|
15d84b3e53 | ||
|
|
0499932ba0 | ||
|
|
732cc7bee0 | ||
|
|
853a98842d | ||
|
|
d6ef467fba | ||
|
|
c75d819a92 | ||
|
|
75c07996f3 | ||
|
|
9dddd93460 | ||
|
|
f5c3b63a4a | ||
|
|
c30d6ae3aa | ||
|
|
fc2bc26f36 | ||
|
|
3a979ac2f8 | ||
|
|
71cd5be513 |
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/actions-all
|
name: codeql/actions-all
|
||||||
version: 0.4.37
|
version: 0.4.38-dev
|
||||||
library: true
|
library: true
|
||||||
warnOnImplicitThis: true
|
warnOnImplicitThis: true
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/actions-queries
|
name: codeql/actions-queries
|
||||||
version: 0.6.29
|
version: 0.6.30-dev
|
||||||
library: false
|
library: false
|
||||||
warnOnImplicitThis: true
|
warnOnImplicitThis: true
|
||||||
groups: [actions, queries]
|
groups: [actions, queries]
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ class Options extends string {
|
|||||||
predicate overrideReturnsNull(Call call) {
|
predicate overrideReturnsNull(Call call) {
|
||||||
// Used in CVS:
|
// Used in CVS:
|
||||||
call.(FunctionCall).getTarget().hasGlobalName("Xstrdup")
|
call.(FunctionCall).getTarget().hasGlobalName("Xstrdup")
|
||||||
or
|
|
||||||
CustomOptions::overrideReturnsNull(call) // old Options.qll
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,8 +43,6 @@ class Options extends string {
|
|||||||
// Used in CVS:
|
// Used in CVS:
|
||||||
call.(FunctionCall).getTarget().hasGlobalName("Xstrdup") and
|
call.(FunctionCall).getTarget().hasGlobalName("Xstrdup") and
|
||||||
nullValue(call.getArgument(0))
|
nullValue(call.getArgument(0))
|
||||||
or
|
|
||||||
CustomOptions::returnsNull(call) // old Options.qll
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,8 +61,6 @@ class Options extends string {
|
|||||||
f.hasGlobalOrStdName([
|
f.hasGlobalOrStdName([
|
||||||
"exit", "_exit", "_Exit", "abort", "__assert_fail", "longjmp", "__builtin_unreachable"
|
"exit", "_exit", "_Exit", "abort", "__assert_fail", "longjmp", "__builtin_unreachable"
|
||||||
])
|
])
|
||||||
or
|
|
||||||
CustomOptions::exits(f) // old Options.qll
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -79,8 +73,7 @@ class Options extends string {
|
|||||||
* runtime, the program's behavior is undefined)
|
* runtime, the program's behavior is undefined)
|
||||||
*/
|
*/
|
||||||
predicate exprExits(Expr e) {
|
predicate exprExits(Expr e) {
|
||||||
e.(AssumeExpr).getChild(0).(CompileTimeConstantInt).getIntValue() = 0 or
|
e.(AssumeExpr).getChild(0).(CompileTimeConstantInt).getIntValue() = 0
|
||||||
CustomOptions::exprExits(e) // old Options.qll
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,10 +81,7 @@ class Options extends string {
|
|||||||
*
|
*
|
||||||
* By default holds only for `fgets`.
|
* By default holds only for `fgets`.
|
||||||
*/
|
*/
|
||||||
predicate alwaysCheckReturnValue(Function f) {
|
predicate alwaysCheckReturnValue(Function f) { f.hasGlobalOrStdName("fgets") }
|
||||||
f.hasGlobalOrStdName("fgets") or
|
|
||||||
CustomOptions::alwaysCheckReturnValue(f) // old Options.qll
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if it is reasonable to ignore the return value of function
|
* Holds if it is reasonable to ignore the return value of function
|
||||||
@@ -107,8 +97,6 @@ class Options extends string {
|
|||||||
// common way of sleeping using select:
|
// common way of sleeping using select:
|
||||||
fc.getTarget().hasGlobalName("select") and
|
fc.getTarget().hasGlobalName("select") and
|
||||||
fc.getArgument(0).getValue() = "0"
|
fc.getArgument(0).getValue() = "0"
|
||||||
or
|
|
||||||
CustomOptions::okToIgnoreReturnValue(fc) // old Options.qll
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,57 +98,3 @@ class CustomMutexType extends MutexType {
|
|||||||
*/
|
*/
|
||||||
override predicate unlockAccess(FunctionCall fc, Expr arg) { none() }
|
override predicate unlockAccess(FunctionCall fc, Expr arg) { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* DEPRECATED: customize `CustomOptions.overrideReturnsNull` instead.
|
|
||||||
*
|
|
||||||
* This predicate is required to support backwards compatibility for
|
|
||||||
* older `Options.qll` files. It should not be removed or modified by
|
|
||||||
* end users.
|
|
||||||
*/
|
|
||||||
predicate overrideReturnsNull(Call call) { none() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DEPRECATED: customize `CustomOptions.returnsNull` instead.
|
|
||||||
*
|
|
||||||
* This predicate is required to support backwards compatibility for
|
|
||||||
* older `Options.qll` files. It should not be removed or modified by
|
|
||||||
* end users.
|
|
||||||
*/
|
|
||||||
predicate returnsNull(Call call) { none() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DEPRECATED: customize `CustomOptions.exits` instead.
|
|
||||||
*
|
|
||||||
* This predicate is required to support backwards compatibility for
|
|
||||||
* older `Options.qll` files. It should not be removed or modified by
|
|
||||||
* end users.
|
|
||||||
*/
|
|
||||||
predicate exits(Function f) { none() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DEPRECATED: customize `CustomOptions.exprExits` instead.
|
|
||||||
*
|
|
||||||
* This predicate is required to support backwards compatibility for
|
|
||||||
* older `Options.qll` files. It should not be removed or modified by
|
|
||||||
* end users.
|
|
||||||
*/
|
|
||||||
predicate exprExits(Expr e) { none() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DEPRECATED: customize `CustomOptions.alwaysCheckReturnValue` instead.
|
|
||||||
*
|
|
||||||
* This predicate is required to support backwards compatibility for
|
|
||||||
* older `Options.qll` files. It should not be removed or modified by
|
|
||||||
* end users.
|
|
||||||
*/
|
|
||||||
predicate alwaysCheckReturnValue(Function f) { none() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DEPRECATED: customize `CustomOptions.okToIgnoreReturnValue` instead.
|
|
||||||
*
|
|
||||||
* This predicate is required to support backwards compatibility for
|
|
||||||
* older `Options.qll` files. It should not be removed or modified by
|
|
||||||
* end users.
|
|
||||||
*/
|
|
||||||
predicate okToIgnoreReturnValue(FunctionCall fc) { none() }
|
|
||||||
|
|||||||
15
cpp/ql/lib/change-notes/2026-05-27-deprecated-removal.md
Normal file
15
cpp/ql/lib/change-notes/2026-05-27-deprecated-removal.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
category: breaking
|
||||||
|
---
|
||||||
|
* Removed the deprecated `overrideReturnsNull` predicate from `Options.qll`. Use `CustomOptions.overrideReturnsNull` instead.
|
||||||
|
* Removed the deprecated `returnsNull` predicate from `Options.qll`. Use `CustomOptions.returnsNull` instead.
|
||||||
|
* Removed the deprecated `exits` predicate from `Options.qll`. Use `CustomOptions.exits` instead.
|
||||||
|
* Removed the deprecated `exprExits` predicate from `Options.qll`. Use `CustomOptions.exprExits` instead.
|
||||||
|
* Removed the deprecated `alwaysCheckReturnValue` predicate from `Options.qll`. Use `CustomOptions.alwaysCheckReturnValue` instead.
|
||||||
|
* Removed the deprecated `okToIgnoreReturnValue` predicate from `Options.qll`. Use `CustomOptions.okToIgnoreReturnValue` instead.
|
||||||
|
* Removed the deprecated `semmle.code.cpp.Member`. Import `semmle.code.cpp.Element` and/or `semmle.code.cpp.Type` directly.
|
||||||
|
* Removed the deprecated `UnknownDefaultLocation` class. Use `UnknownLocation` instead.
|
||||||
|
* Removed the deprecated `UnknownExprLocation` class. Use `UnknownLocation` instead.
|
||||||
|
* Removed the deprecated `UnknownStmtLocation` class. Use `UnknownLocation` instead.
|
||||||
|
* Removed the deprecated `TemplateParameter` class. Use `TypeTemplateParameter` instead.
|
||||||
|
* Support for class resolution across link targets has been removed for databases which were created with CodeQL versions before 1.23.0.
|
||||||
@@ -32,7 +32,6 @@ import semmle.code.cpp.Class
|
|||||||
import semmle.code.cpp.Struct
|
import semmle.code.cpp.Struct
|
||||||
import semmle.code.cpp.Union
|
import semmle.code.cpp.Union
|
||||||
import semmle.code.cpp.Enum
|
import semmle.code.cpp.Enum
|
||||||
import semmle.code.cpp.Member
|
|
||||||
import semmle.code.cpp.Field
|
import semmle.code.cpp.Field
|
||||||
import semmle.code.cpp.Function
|
import semmle.code.cpp.Function
|
||||||
import semmle.code.cpp.MemberFunction
|
import semmle.code.cpp.MemberFunction
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/cpp-all
|
name: codeql/cpp-all
|
||||||
version: 10.2.0
|
version: 10.2.1-dev
|
||||||
groups: cpp
|
groups: cpp
|
||||||
dbscheme: semmlecode.cpp.dbscheme
|
dbscheme: semmlecode.cpp.dbscheme
|
||||||
extractor: cpp
|
extractor: cpp
|
||||||
|
|||||||
@@ -148,28 +148,3 @@ class UnknownLocation extends Location {
|
|||||||
this.getFile().getAbsolutePath() = "" and locations_default(this, _, 0, 0, 0, 0)
|
this.getFile().getAbsolutePath() = "" and locations_default(this, _, 0, 0, 0, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A dummy location which is used when something doesn't have a location in
|
|
||||||
* the source code but needs to have a `Location` associated with it.
|
|
||||||
*
|
|
||||||
* DEPRECATED: use `UnknownLocation`
|
|
||||||
*/
|
|
||||||
deprecated class UnknownDefaultLocation extends UnknownLocation { }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A dummy location which is used when an expression doesn't have a
|
|
||||||
* location in the source code but needs to have a `Location` associated
|
|
||||||
* with it.
|
|
||||||
*
|
|
||||||
* DEPRECATED: use `UnknownLocation`
|
|
||||||
*/
|
|
||||||
deprecated class UnknownExprLocation extends UnknownLocation { }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A dummy location which is used when a statement doesn't have a location
|
|
||||||
* in the source code but needs to have a `Location` associated with it.
|
|
||||||
*
|
|
||||||
* DEPRECATED: use `UnknownLocation`
|
|
||||||
*/
|
|
||||||
deprecated class UnknownStmtLocation extends UnknownLocation { }
|
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
/**
|
|
||||||
* DEPRECATED: import `semmle.code.cpp.Element` and/or `semmle.code.cpp.Type` directly as required.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import semmle.code.cpp.Element
|
|
||||||
import semmle.code.cpp.Type
|
|
||||||
@@ -35,13 +35,6 @@ class NonTypeTemplateParameter extends Literal, TemplateParameterImpl {
|
|||||||
override string getAPrimaryQlClass() { result = "NonTypeTemplateParameter" }
|
override string getAPrimaryQlClass() { result = "NonTypeTemplateParameter" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A C++ `typename` (or `class`) template parameter.
|
|
||||||
*
|
|
||||||
* DEPRECATED: Use `TypeTemplateParameter` instead.
|
|
||||||
*/
|
|
||||||
deprecated class TemplateParameter = TypeTemplateParameter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A C++ `typename` (or `class`) template parameter.
|
* A C++ `typename` (or `class`) template parameter.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -276,6 +276,45 @@ private predicate isClassConstructedFrom(Class c, Class templateClass) {
|
|||||||
not c.isConstructedFrom(_) and c = templateClass
|
not c.isConstructedFrom(_) and c = templateClass
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gets the fully templated version of `c`. */
|
||||||
|
private Class getFullyTemplatedClassOld(Class c) {
|
||||||
|
not c.isFromUninstantiatedTemplate(_) and
|
||||||
|
isClassConstructedFrom(c, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
private TemplateClass getOriginalClassTemplate(TemplateClass tc) {
|
||||||
|
result = tc.getOriginalTemplate()
|
||||||
|
or
|
||||||
|
not exists(tc.getOriginalTemplate()) and
|
||||||
|
result = tc
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the fully templated version of `c`. */
|
||||||
|
private Class getFullyTemplatedClassNew(Class c) {
|
||||||
|
not c.isFromUninstantiatedTemplate(_) and
|
||||||
|
exists(Class mid |
|
||||||
|
c.isConstructedFrom(mid)
|
||||||
|
or
|
||||||
|
not c.isConstructedFrom(_) and c = mid
|
||||||
|
|
|
||||||
|
result = getOriginalClassTemplate(mid)
|
||||||
|
or
|
||||||
|
not mid instanceof TemplateClass and mid = result
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the fully templated version of `c`. */
|
||||||
|
private Class getFullyTemplatedClass(Class c) {
|
||||||
|
// The `Class::getOriginalTemplate` predicate was introduced in CodeQL
|
||||||
|
// version 2.25.6 and the upgrade script leaves the
|
||||||
|
// `class_template_generated_from` extensionals empty if the database
|
||||||
|
// was generated with an older extractor. So we use the old implementation
|
||||||
|
// if the `class_template_generated_from` extensional is empty.
|
||||||
|
if class_template_generated_from(_, _)
|
||||||
|
then result = getFullyTemplatedClassNew(c)
|
||||||
|
else result = getFullyTemplatedClassOld(c)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `f` is an instantiation of a function template `templateFunc`, or
|
* Holds if `f` is an instantiation of a function template `templateFunc`, or
|
||||||
* holds with `f = templateFunc` if `f` is not an instantiation of any function
|
* holds with `f = templateFunc` if `f` is not an instantiation of any function
|
||||||
@@ -292,7 +331,7 @@ private predicate isFunctionConstructedFrom(Function f, Function templateFunc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the fully templated version of `f`. */
|
/** Gets the fully templated version of `f`. */
|
||||||
Function getFullyTemplatedFunction(Function f) {
|
private Function getFullyTemplatedFunctionOld(Function f) {
|
||||||
not f.isFromUninstantiatedTemplate(_) and
|
not f.isFromUninstantiatedTemplate(_) and
|
||||||
(
|
(
|
||||||
exists(Class c, Class templateClass, int i |
|
exists(Class c, Class templateClass, int i |
|
||||||
@@ -306,13 +345,46 @@ Function getFullyTemplatedFunction(Function f) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TemplateFunction getOriginalFunctionTemplate(TemplateFunction tf) {
|
||||||
|
result = tf.getOriginalTemplate()
|
||||||
|
or
|
||||||
|
not exists(tf.getOriginalTemplate()) and
|
||||||
|
result = tf
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the fully templated version of `f`. */
|
||||||
|
private Function getFullyTemplatedFunctionNew(Function f) {
|
||||||
|
not f.isFromUninstantiatedTemplate(_) and
|
||||||
|
exists(Function mid |
|
||||||
|
f.isConstructedFrom(mid)
|
||||||
|
or
|
||||||
|
not f.isConstructedFrom(_) and f = mid
|
||||||
|
|
|
||||||
|
result = getOriginalFunctionTemplate(mid)
|
||||||
|
or
|
||||||
|
not mid instanceof TemplateFunction and mid = result
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the fully templated version of `f`. */
|
||||||
|
Function getFullyTemplatedFunction(Function f) {
|
||||||
|
// The `Function::getOriginalTemplate` predicate was introduced in CodeQL
|
||||||
|
// version 2.25.6 and the upgrade script leaves the
|
||||||
|
// `function_template_generated_from` extensionals empty if the database
|
||||||
|
// was generated with an older extractor. So we use the old implementation
|
||||||
|
// if the `function_template_generated_from` extensional is empty.
|
||||||
|
if function_template_generated_from(_, _)
|
||||||
|
then result = getFullyTemplatedFunctionNew(f)
|
||||||
|
else result = getFullyTemplatedFunctionOld(f)
|
||||||
|
}
|
||||||
|
|
||||||
/** Prefixes `const` to `s` if `t` is const, or returns `s` otherwise. */
|
/** Prefixes `const` to `s` if `t` is const, or returns `s` otherwise. */
|
||||||
bindingset[s, t]
|
bindingset[s, t]
|
||||||
private string withConst(string s, Type t) {
|
private string withConst(string s, Type t) {
|
||||||
if t.isConst() then result = "const " + s else result = s
|
if t.isConst() then result = "const " + s else result = s
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Prefixes `volatile` to `s` if `t` is const, or returns `s` otherwise. */
|
/** Prefixes `volatile` to `s` if `t` is volatile, or returns `s` otherwise. */
|
||||||
bindingset[s, t]
|
bindingset[s, t]
|
||||||
private string withVolatile(string s, Type t) {
|
private string withVolatile(string s, Type t) {
|
||||||
if t.isVolatile() then result = "volatile " + s else result = s
|
if t.isVolatile() then result = "volatile " + s else result = s
|
||||||
@@ -490,7 +562,7 @@ pragma[nomagic]
|
|||||||
private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining) {
|
private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining) {
|
||||||
// If there is a declaring type then we start by expanding the function templates
|
// If there is a declaring type then we start by expanding the function templates
|
||||||
exists(Class template |
|
exists(Class template |
|
||||||
isClassConstructedFrom(f.getDeclaringType(), template) and
|
template = getFullyTemplatedClass(f.getDeclaringType()) and
|
||||||
remaining = getNumberOfSupportedClassTemplateArguments(template) and
|
remaining = getNumberOfSupportedClassTemplateArguments(template) and
|
||||||
result = getTypeNameWithoutFunctionTemplates(f, n, 0)
|
result = getTypeNameWithoutFunctionTemplates(f, n, 0)
|
||||||
)
|
)
|
||||||
@@ -502,7 +574,7 @@ private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining
|
|||||||
or
|
or
|
||||||
exists(string mid, TypeTemplateParameter tp, Class template |
|
exists(string mid, TypeTemplateParameter tp, Class template |
|
||||||
mid = getTypeNameWithoutClassTemplates(f, n, remaining + 1) and
|
mid = getTypeNameWithoutClassTemplates(f, n, remaining + 1) and
|
||||||
isClassConstructedFrom(f.getDeclaringType(), template) and
|
template = getFullyTemplatedClass(f.getDeclaringType()) and
|
||||||
tp = getSupportedClassTemplateArgument(template, remaining)
|
tp = getSupportedClassTemplateArgument(template, remaining)
|
||||||
|
|
|
|
||||||
result = mid.replaceAll(tp.getName(), "class:" + remaining.toString())
|
result = mid.replaceAll(tp.getName(), "class:" + remaining.toString())
|
||||||
|
|||||||
@@ -1,59 +1,5 @@
|
|||||||
import semmle.code.cpp.Type
|
import semmle.code.cpp.Type
|
||||||
|
|
||||||
/** For upgraded databases without mangled name info. */
|
|
||||||
pragma[noinline]
|
|
||||||
private string getTopLevelClassName(@usertype c) {
|
|
||||||
not mangled_name(_, _, _) and
|
|
||||||
isClass(c) and
|
|
||||||
usertypes(c, result, _) and
|
|
||||||
not namespacembrs(_, c) and // not in a namespace
|
|
||||||
not member(_, _, c) and // not in some structure
|
|
||||||
not class_instantiation(c, _) // not a template instantiation
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For upgraded databases without mangled name info.
|
|
||||||
* Holds if `d` is a unique complete class named `name`.
|
|
||||||
*/
|
|
||||||
pragma[noinline]
|
|
||||||
private predicate existsCompleteWithName(string name, @usertype d) {
|
|
||||||
not mangled_name(_, _, _) and
|
|
||||||
is_complete(d) and
|
|
||||||
name = getTopLevelClassName(d) and
|
|
||||||
onlyOneCompleteClassExistsWithName(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** For upgraded databases without mangled name info. */
|
|
||||||
pragma[noinline]
|
|
||||||
private predicate onlyOneCompleteClassExistsWithName(string name) {
|
|
||||||
not mangled_name(_, _, _) and
|
|
||||||
strictcount(@usertype c | is_complete(c) and getTopLevelClassName(c) = name) = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For upgraded databases without mangled name info.
|
|
||||||
* Holds if `c` is an incomplete class named `name`.
|
|
||||||
*/
|
|
||||||
pragma[noinline]
|
|
||||||
private predicate existsIncompleteWithName(string name, @usertype c) {
|
|
||||||
not mangled_name(_, _, _) and
|
|
||||||
not is_complete(c) and
|
|
||||||
name = getTopLevelClassName(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For upgraded databases without mangled name info.
|
|
||||||
* Holds if `c` is an incomplete class, and there exists a unique complete class `d`
|
|
||||||
* with the same name.
|
|
||||||
*/
|
|
||||||
private predicate oldHasCompleteTwin(@usertype c, @usertype d) {
|
|
||||||
not mangled_name(_, _, _) and
|
|
||||||
exists(string name |
|
|
||||||
existsIncompleteWithName(name, c) and
|
|
||||||
existsCompleteWithName(name, d)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma[noinline]
|
pragma[noinline]
|
||||||
private @mangledname getClassMangledName(@usertype c) {
|
private @mangledname getClassMangledName(@usertype c) {
|
||||||
isClass(c) and
|
isClass(c) and
|
||||||
@@ -103,10 +49,7 @@ private module Cached {
|
|||||||
@usertype resolveClass(@usertype c) {
|
@usertype resolveClass(@usertype c) {
|
||||||
hasCompleteTwin(c, result)
|
hasCompleteTwin(c, result)
|
||||||
or
|
or
|
||||||
oldHasCompleteTwin(c, result)
|
|
||||||
or
|
|
||||||
not hasCompleteTwin(c, _) and
|
not hasCompleteTwin(c, _) and
|
||||||
not oldHasCompleteTwin(c, _) and
|
|
||||||
result = c
|
result = c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/cpp-queries
|
name: codeql/cpp-queries
|
||||||
version: 1.6.4
|
version: 1.6.5-dev
|
||||||
groups:
|
groups:
|
||||||
- cpp
|
- cpp
|
||||||
- queries
|
- queries
|
||||||
|
|||||||
@@ -51,13 +51,16 @@ models
|
|||||||
| 50 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
|
| 50 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
|
||||||
| 51 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
|
| 51 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||||
| 52 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
|
| 52 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||||
| 53 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
| 53 | Summary: ; TemplateClass1; true; templateFunction2<U,V>; (U,V); ; Argument[1]; ReturnValue; value; manual |
|
||||||
| 54 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
| 54 | Summary: ; TemplateClass1<T>; false; templateFunction<U>; (T,U); ; Argument[0]; ReturnValue; value; manual |
|
||||||
| 55 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
|
| 55 | Summary: ; TemplateClass2<T,U>; true; function; (U,T); ; Argument[1]; ReturnValue; value; manual |
|
||||||
| 56 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
|
| 56 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||||
| 57 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
|
| 57 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||||
|
| 58 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
|
||||||
|
| 59 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
|
||||||
|
| 60 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
|
||||||
edges
|
edges
|
||||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:57 |
|
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:60 |
|
||||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:32 |
|
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:32 |
|
||||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:32 Sink:MaD:2 |
|
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:32 Sink:MaD:2 |
|
||||||
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction |
|
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction |
|
||||||
@@ -66,24 +69,24 @@ edges
|
|||||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | |
|
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | |
|
||||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:2 |
|
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:2 |
|
||||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | |
|
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | |
|
||||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:57 |
|
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:60 |
|
||||||
| azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | provenance | MaD:56 |
|
| azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | provenance | MaD:59 |
|
||||||
| azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | provenance | MaD:53 |
|
| azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | provenance | MaD:56 |
|
||||||
| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | provenance | MaD:54 |
|
| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | provenance | MaD:57 |
|
||||||
| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | provenance | MaD:55 |
|
| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | provenance | MaD:58 |
|
||||||
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | provenance | |
|
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | provenance | |
|
||||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:253:48:253:60 | *call to GetBodyStream | provenance | Src:MaD:29 |
|
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:253:48:253:60 | *call to GetBodyStream | provenance | Src:MaD:29 |
|
||||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:257:5:257:8 | *resp | provenance | |
|
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:257:5:257:8 | *resp | provenance | |
|
||||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:262:5:262:8 | *resp | provenance | |
|
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:262:5:262:8 | *resp | provenance | |
|
||||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:266:38:266:41 | *resp | provenance | |
|
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:266:38:266:41 | *resp | provenance | |
|
||||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | provenance | |
|
| azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | provenance | |
|
||||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:53 |
|
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:56 |
|
||||||
| azure.cpp:257:16:257:21 | Read output argument | azure.cpp:258:10:258:16 | * ... | provenance | |
|
| azure.cpp:257:16:257:21 | Read output argument | azure.cpp:258:10:258:16 | * ... | provenance | |
|
||||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | provenance | |
|
| azure.cpp:262:5:262:8 | *resp | azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | provenance | |
|
||||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:54 |
|
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:57 |
|
||||||
| azure.cpp:262:23:262:28 | ReadToCount output argument | azure.cpp:263:10:263:16 | * ... | provenance | |
|
| azure.cpp:262:23:262:28 | ReadToCount output argument | azure.cpp:263:10:263:16 | * ... | provenance | |
|
||||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
|
| azure.cpp:266:38:266:41 | *resp | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
|
||||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:55 |
|
| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:58 |
|
||||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | |
|
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | |
|
||||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:267:10:267:12 | vec [element] | provenance | |
|
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:267:10:267:12 | vec [element] | provenance | |
|
||||||
| azure.cpp:267:10:267:12 | vec [element] | azure.cpp:267:10:267:12 | vec | provenance | |
|
| azure.cpp:267:10:267:12 | vec [element] | azure.cpp:267:10:267:12 | vec | provenance | |
|
||||||
@@ -100,11 +103,11 @@ edges
|
|||||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | provenance | Src:MaD:26 |
|
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | provenance | Src:MaD:26 |
|
||||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:282:21:282:23 | *call to get | provenance | |
|
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:282:21:282:23 | *call to get | provenance | |
|
||||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
|
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
|
||||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:55 |
|
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:58 |
|
||||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:10:282:38 | call to ReadToEnd | provenance | |
|
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:10:282:38 | call to ReadToEnd | provenance | |
|
||||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | |
|
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | |
|
||||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:62:10:62:14 | [summary param] this in Value | provenance | |
|
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:62:10:62:14 | [summary param] this in Value | provenance | |
|
||||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:56 |
|
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:59 |
|
||||||
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:24:289:56 | call to GetHeader | provenance | |
|
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:24:289:56 | call to GetHeader | provenance | |
|
||||||
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:32:289:40 | call to GetHeader | provenance | Src:MaD:30 |
|
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:32:289:40 | call to GetHeader | provenance | Src:MaD:30 |
|
||||||
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:289:63:289:65 | call to Value | provenance | |
|
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:289:63:289:65 | call to Value | provenance | |
|
||||||
@@ -180,6 +183,39 @@ edges
|
|||||||
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:119:10:119:11 | y2 | provenance | Sink:MaD:1 |
|
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:119:10:119:11 | y2 | provenance | Sink:MaD:1 |
|
||||||
| test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | provenance | |
|
| test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | provenance | |
|
||||||
| test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:48 |
|
| test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:48 |
|
||||||
|
| test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | provenance | MaD:54 |
|
||||||
|
| test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | test.cpp:128:5:128:21 | [summary] to write: ReturnValue in templateFunction2 | provenance | MaD:53 |
|
||||||
|
| test.cpp:133:10:133:18 | call to ymlSource | test.cpp:133:10:133:18 | call to ymlSource | provenance | Src:MaD:25 |
|
||||||
|
| test.cpp:133:10:133:18 | call to ymlSource | test.cpp:134:45:134:45 | x | provenance | |
|
||||||
|
| test.cpp:134:13:134:43 | call to templateFunction | test.cpp:134:13:134:43 | call to templateFunction | provenance | |
|
||||||
|
| test.cpp:134:13:134:43 | call to templateFunction | test.cpp:135:10:135:10 | y | provenance | Sink:MaD:1 |
|
||||||
|
| test.cpp:134:45:134:45 | x | test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | provenance | |
|
||||||
|
| test.cpp:134:45:134:45 | x | test.cpp:134:13:134:43 | call to templateFunction | provenance | MaD:54 |
|
||||||
|
| test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | provenance | MaD:55 |
|
||||||
|
| test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | provenance | MaD:55 |
|
||||||
|
| test.cpp:146:10:146:18 | call to ymlSource | test.cpp:146:10:146:18 | call to ymlSource | provenance | Src:MaD:25 |
|
||||||
|
| test.cpp:146:10:146:18 | call to ymlSource | test.cpp:148:26:148:26 | x | provenance | |
|
||||||
|
| test.cpp:148:10:148:27 | call to function | test.cpp:148:10:148:27 | call to function | provenance | |
|
||||||
|
| test.cpp:148:10:148:27 | call to function | test.cpp:149:10:149:10 | z | provenance | Sink:MaD:1 |
|
||||||
|
| test.cpp:148:26:148:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | provenance | |
|
||||||
|
| test.cpp:148:26:148:26 | x | test.cpp:148:10:148:27 | call to function | provenance | MaD:55 |
|
||||||
|
| test.cpp:155:10:155:18 | call to ymlSource | test.cpp:155:10:155:18 | call to ymlSource | provenance | Src:MaD:25 |
|
||||||
|
| test.cpp:155:10:155:18 | call to ymlSource | test.cpp:157:26:157:26 | x | provenance | |
|
||||||
|
| test.cpp:157:13:157:20 | call to function | test.cpp:157:13:157:20 | call to function | provenance | |
|
||||||
|
| test.cpp:157:13:157:20 | call to function | test.cpp:158:10:158:10 | z | provenance | Sink:MaD:1 |
|
||||||
|
| test.cpp:157:26:157:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | provenance | |
|
||||||
|
| test.cpp:157:26:157:26 | x | test.cpp:157:13:157:20 | call to function | provenance | MaD:55 |
|
||||||
|
| test.cpp:164:34:164:34 | x | test.cpp:165:69:165:69 | x | provenance | |
|
||||||
|
| test.cpp:165:12:165:64 | call to templateFunction2 | test.cpp:164:7:164:7 | *templateFunction3 | provenance | |
|
||||||
|
| test.cpp:165:12:165:64 | call to templateFunction2 | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | |
|
||||||
|
| test.cpp:165:69:165:69 | x | test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | provenance | |
|
||||||
|
| test.cpp:165:69:165:69 | x | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | MaD:53 |
|
||||||
|
| test.cpp:170:10:170:18 | call to ymlSource | test.cpp:170:10:170:18 | call to ymlSource | provenance | Src:MaD:25 |
|
||||||
|
| test.cpp:170:10:170:18 | call to ymlSource | test.cpp:172:51:172:51 | x | provenance | |
|
||||||
|
| test.cpp:172:13:172:44 | call to templateFunction3 | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | |
|
||||||
|
| test.cpp:172:13:172:44 | call to templateFunction3 | test.cpp:173:10:173:10 | y | provenance | Sink:MaD:1 |
|
||||||
|
| test.cpp:172:51:172:51 | x | test.cpp:164:34:164:34 | x | provenance | |
|
||||||
|
| test.cpp:172:51:172:51 | x | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | MaD:53 |
|
||||||
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:33 |
|
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:33 |
|
||||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 |
|
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 |
|
||||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:24:8:24:11 | * ... | provenance | |
|
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:24:8:24:11 | * ... | provenance | |
|
||||||
@@ -483,6 +519,43 @@ nodes
|
|||||||
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | semmle.label | call to callWithNonTypeTemplate |
|
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | semmle.label | call to callWithNonTypeTemplate |
|
||||||
| test.cpp:118:44:118:44 | *x | semmle.label | *x |
|
| test.cpp:118:44:118:44 | *x | semmle.label | *x |
|
||||||
| test.cpp:119:10:119:11 | y2 | semmle.label | y2 |
|
| test.cpp:119:10:119:11 | y2 | semmle.label | y2 |
|
||||||
|
| test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | semmle.label | [summary param] 0 in templateFunction |
|
||||||
|
| test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | semmle.label | [summary] to write: ReturnValue in templateFunction |
|
||||||
|
| test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | semmle.label | [summary param] 1 in templateFunction2 |
|
||||||
|
| test.cpp:128:5:128:21 | [summary] to write: ReturnValue in templateFunction2 | semmle.label | [summary] to write: ReturnValue in templateFunction2 |
|
||||||
|
| test.cpp:133:10:133:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||||
|
| test.cpp:133:10:133:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||||
|
| test.cpp:134:13:134:43 | call to templateFunction | semmle.label | call to templateFunction |
|
||||||
|
| test.cpp:134:13:134:43 | call to templateFunction | semmle.label | call to templateFunction |
|
||||||
|
| test.cpp:134:45:134:45 | x | semmle.label | x |
|
||||||
|
| test.cpp:135:10:135:10 | y | semmle.label | y |
|
||||||
|
| test.cpp:140:4:140:11 | [summary param] 1 in function | semmle.label | [summary param] 1 in function |
|
||||||
|
| test.cpp:140:4:140:11 | [summary param] 1 in function | semmle.label | [summary param] 1 in function |
|
||||||
|
| test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | semmle.label | [summary] to write: ReturnValue in function |
|
||||||
|
| test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | semmle.label | [summary] to write: ReturnValue in function |
|
||||||
|
| test.cpp:146:10:146:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||||
|
| test.cpp:146:10:146:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||||
|
| test.cpp:148:10:148:27 | call to function | semmle.label | call to function |
|
||||||
|
| test.cpp:148:10:148:27 | call to function | semmle.label | call to function |
|
||||||
|
| test.cpp:148:26:148:26 | x | semmle.label | x |
|
||||||
|
| test.cpp:149:10:149:10 | z | semmle.label | z |
|
||||||
|
| test.cpp:155:10:155:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||||
|
| test.cpp:155:10:155:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||||
|
| test.cpp:157:13:157:20 | call to function | semmle.label | call to function |
|
||||||
|
| test.cpp:157:13:157:20 | call to function | semmle.label | call to function |
|
||||||
|
| test.cpp:157:26:157:26 | x | semmle.label | x |
|
||||||
|
| test.cpp:158:10:158:10 | z | semmle.label | z |
|
||||||
|
| test.cpp:164:7:164:7 | *templateFunction3 | semmle.label | *templateFunction3 |
|
||||||
|
| test.cpp:164:34:164:34 | x | semmle.label | x |
|
||||||
|
| test.cpp:165:12:165:64 | call to templateFunction2 | semmle.label | call to templateFunction2 |
|
||||||
|
| test.cpp:165:12:165:64 | call to templateFunction2 | semmle.label | call to templateFunction2 |
|
||||||
|
| test.cpp:165:69:165:69 | x | semmle.label | x |
|
||||||
|
| test.cpp:170:10:170:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||||
|
| test.cpp:170:10:170:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||||
|
| test.cpp:172:13:172:44 | call to templateFunction3 | semmle.label | call to templateFunction3 |
|
||||||
|
| test.cpp:172:13:172:44 | call to templateFunction3 | semmle.label | call to templateFunction3 |
|
||||||
|
| test.cpp:172:51:172:51 | x | semmle.label | x |
|
||||||
|
| test.cpp:173:10:173:10 | y | semmle.label | y |
|
||||||
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | semmle.label | [summary param] *0 in CommandLineToArgvA |
|
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | semmle.label | [summary param] *0 in CommandLineToArgvA |
|
||||||
| windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | semmle.label | [summary] to write: ReturnValue[**] in CommandLineToArgvA |
|
| windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | semmle.label | [summary] to write: ReturnValue[**] in CommandLineToArgvA |
|
||||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA |
|
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA |
|
||||||
@@ -688,6 +761,11 @@ subpaths
|
|||||||
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body |
|
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body |
|
||||||
| test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body |
|
| test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body |
|
||||||
| test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate |
|
| test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate |
|
||||||
|
| test.cpp:134:45:134:45 | x | test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | test.cpp:134:13:134:43 | call to templateFunction |
|
||||||
|
| test.cpp:148:26:148:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | test.cpp:148:10:148:27 | call to function |
|
||||||
|
| test.cpp:157:26:157:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | test.cpp:157:13:157:20 | call to function |
|
||||||
|
| test.cpp:165:69:165:69 | x | test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | test.cpp:128:5:128:21 | [summary] to write: ReturnValue in templateFunction2 | test.cpp:165:12:165:64 | call to templateFunction2 |
|
||||||
|
| test.cpp:172:51:172:51 | x | test.cpp:164:34:164:34 | x | test.cpp:164:7:164:7 | *templateFunction3 | test.cpp:172:13:172:44 | call to templateFunction3 |
|
||||||
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA |
|
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA |
|
||||||
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument |
|
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument |
|
||||||
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument |
|
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument |
|
||||||
|
|||||||
@@ -19,3 +19,6 @@ extensions:
|
|||||||
- ["", "", False, "ymlStepGenerated_with_body", "", "", "Argument[0]", "ReturnValue", "taint", "df-generated"]
|
- ["", "", False, "ymlStepGenerated_with_body", "", "", "Argument[0]", "ReturnValue", "taint", "df-generated"]
|
||||||
- ["", "", False, "callWithArgument", "", "", "Argument[1]", "Argument[0].Parameter[0]", "value", "manual"]
|
- ["", "", False, "callWithArgument", "", "", "Argument[1]", "Argument[0].Parameter[0]", "value", "manual"]
|
||||||
- ["", "", False, "callWithNonTypeTemplate<T>", "(const T &)", "", "Argument[*0]", "ReturnValue", "value", "manual"]
|
- ["", "", False, "callWithNonTypeTemplate<T>", "(const T &)", "", "Argument[*0]", "ReturnValue", "value", "manual"]
|
||||||
|
- ["", "TemplateClass1<T>", False, "templateFunction<U>", "(T,U)", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||||
|
- ["", "TemplateClass1", True, "templateFunction2<U,V>", "(U,V)", "", "Argument[1]", "ReturnValue", "value", "manual"]
|
||||||
|
- ["", "TemplateClass2<T,U>", True, "function", "(U,T)", "", "Argument[1]", "ReturnValue", "value", "manual"]
|
||||||
@@ -15,3 +15,7 @@
|
|||||||
| test.cpp:89:11:89:11 | y | test-sink |
|
| test.cpp:89:11:89:11 | y | test-sink |
|
||||||
| test.cpp:116:10:116:11 | y1 | test-sink |
|
| test.cpp:116:10:116:11 | y1 | test-sink |
|
||||||
| test.cpp:119:10:119:11 | y2 | test-sink |
|
| test.cpp:119:10:119:11 | y2 | test-sink |
|
||||||
|
| test.cpp:135:10:135:10 | y | test-sink |
|
||||||
|
| test.cpp:149:10:149:10 | z | test-sink |
|
||||||
|
| test.cpp:158:10:158:10 | z | test-sink |
|
||||||
|
| test.cpp:173:10:173:10 | y | test-sink |
|
||||||
|
|||||||
@@ -9,6 +9,10 @@
|
|||||||
| test.cpp:56:8:56:16 | call to ymlSource | local |
|
| test.cpp:56:8:56:16 | call to ymlSource | local |
|
||||||
| test.cpp:94:10:94:18 | call to ymlSource | local |
|
| test.cpp:94:10:94:18 | call to ymlSource | local |
|
||||||
| test.cpp:114:10:114:18 | call to ymlSource | local |
|
| test.cpp:114:10:114:18 | call to ymlSource | local |
|
||||||
|
| test.cpp:133:10:133:18 | call to ymlSource | local |
|
||||||
|
| test.cpp:146:10:146:18 | call to ymlSource | local |
|
||||||
|
| test.cpp:155:10:155:18 | call to ymlSource | local |
|
||||||
|
| test.cpp:170:10:170:18 | call to ymlSource | local |
|
||||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | local |
|
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | local |
|
||||||
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | local |
|
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | local |
|
||||||
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | local |
|
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | local |
|
||||||
|
|||||||
@@ -118,3 +118,57 @@ void test_callWithNonTypeTemplate() {
|
|||||||
int y2 = callWithNonTypeTemplate<int, 10>(x);
|
int y2 = callWithNonTypeTemplate<int, 10>(x);
|
||||||
ymlSink(y2); // $ ir
|
ymlSink(y2); // $ ir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct TemplateClass1 {
|
||||||
|
template<class U>
|
||||||
|
U templateFunction(T, U);
|
||||||
|
|
||||||
|
template<class U, class V>
|
||||||
|
V templateFunction2(U, V);
|
||||||
|
};
|
||||||
|
|
||||||
|
void test_template_function_in_template_class() {
|
||||||
|
TemplateClass1<int> b;
|
||||||
|
int x = ymlSource();
|
||||||
|
auto y = b.templateFunction<unsigned long>(x, 0UL);
|
||||||
|
ymlSink(y); // $ ir
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class S, class T>
|
||||||
|
struct TemplateClass2 {
|
||||||
|
T function(T, S);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class V> using PartialInstantiationOfTemplateClass2 = TemplateClass2<int, V>;
|
||||||
|
|
||||||
|
void test_partial_class_instantiation() {
|
||||||
|
int x = ymlSource();
|
||||||
|
PartialInstantiationOfTemplateClass2<unsigned long> y;
|
||||||
|
int z = y.function(0UL, x);
|
||||||
|
ymlSink(z); // $ ir
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class V> struct DeriveFromFromPartialTemplateInstantiation : TemplateClass2<int, V> { };
|
||||||
|
|
||||||
|
void test_inheritance() {
|
||||||
|
int x = ymlSource();
|
||||||
|
DeriveFromFromPartialTemplateInstantiation<long> y;
|
||||||
|
auto z = y.function(0L, x);
|
||||||
|
ymlSink(z); // $ ir
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct Class1 : TemplateClass1<T> {
|
||||||
|
template<class U>
|
||||||
|
int templateFunction3(U u, int x) {
|
||||||
|
return TemplateClass1<T>::template templateFunction2<U, int>(u, x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void test_class1() {
|
||||||
|
int x = ymlSource();
|
||||||
|
Class1<int> c;
|
||||||
|
auto y = c.templateFunction3<unsigned long>(0UL, x);
|
||||||
|
ymlSink(y); // $ ir
|
||||||
|
}
|
||||||
@@ -27383,54 +27383,55 @@ getParameterTypeName
|
|||||||
| stl.h:91:24:91:33 | operator++ | 0 | int |
|
| stl.h:91:24:91:33 | operator++ | 0 | int |
|
||||||
| stl.h:95:44:95:44 | back_inserter | 0 | func:0 & |
|
| stl.h:95:44:95:44 | back_inserter | 0 | func:0 & |
|
||||||
| stl.h:95:44:95:44 | back_inserter | 0 | func:0 & |
|
| stl.h:95:44:95:44 | back_inserter | 0 | func:0 & |
|
||||||
| stl.h:148:3:148:14 | basic_string | 0 | const class:2 & |
|
| stl.h:147:12:147:23 | basic_string | 0 | const class:2 & |
|
||||||
| stl.h:149:33:149:44 | basic_string | 0 | const class:0 * |
|
| stl.h:148:3:148:14 | basic_string | 0 | const class:0 * |
|
||||||
| stl.h:149:33:149:44 | basic_string | 1 | const class:2 & |
|
| stl.h:148:3:148:14 | basic_string | 1 | const class:2 & |
|
||||||
| stl.h:151:16:151:20 | c_str | 0 | func:0 |
|
| stl.h:149:33:149:44 | basic_string | 0 | func:0 |
|
||||||
| stl.h:151:16:151:20 | c_str | 1 | func:0 |
|
| stl.h:149:33:149:44 | basic_string | 1 | func:0 |
|
||||||
| stl.h:151:16:151:20 | c_str | 2 | const class:2 & |
|
| stl.h:149:33:149:44 | basic_string | 2 | const class:2 & |
|
||||||
|
| stl.h:165:8:165:16 | push_back | 0 | class:0 |
|
||||||
| stl.h:173:13:173:22 | operator[] | 0 | size_type |
|
| stl.h:173:13:173:22 | operator[] | 0 | size_type |
|
||||||
| stl.h:175:13:175:14 | at | 0 | size_type |
|
| stl.h:175:13:175:14 | at | 0 | size_type |
|
||||||
| stl.h:176:35:176:44 | operator+= | 0 | size_type |
|
| stl.h:176:35:176:44 | operator+= | 0 | const func:0 & |
|
||||||
| stl.h:176:35:176:44 | operator+= | 0 | size_type |
|
| stl.h:176:35:176:44 | operator+= | 0 | const func:0 & |
|
||||||
| stl.h:177:17:177:26 | operator+= | 0 | const func:0 & |
|
| stl.h:177:17:177:26 | operator+= | 0 | const class:0 * |
|
||||||
| stl.h:178:17:178:22 | append | 0 | const class:0 * |
|
| stl.h:178:17:178:22 | append | 0 | const basic_string & |
|
||||||
| stl.h:179:17:179:22 | append | 0 | const basic_string & |
|
| stl.h:179:17:179:22 | append | 0 | const class:0 * |
|
||||||
| stl.h:180:17:180:22 | append | 0 | const class:0 * |
|
| stl.h:180:17:180:22 | append | 0 | size_type |
|
||||||
| stl.h:181:47:181:52 | append | 0 | size_type |
|
| stl.h:180:17:180:22 | append | 1 | class:0 |
|
||||||
| stl.h:181:47:181:52 | append | 1 | class:0 |
|
| stl.h:181:47:181:52 | append | 0 | func:0 |
|
||||||
| stl.h:182:17:182:22 | assign | 0 | func:0 |
|
| stl.h:181:47:181:52 | append | 1 | func:0 |
|
||||||
| stl.h:182:17:182:22 | assign | 1 | func:0 |
|
| stl.h:182:17:182:22 | assign | 0 | const basic_string & |
|
||||||
| stl.h:183:17:183:22 | assign | 0 | const basic_string & |
|
| stl.h:183:17:183:22 | assign | 0 | size_type |
|
||||||
| stl.h:184:47:184:52 | assign | 0 | size_type |
|
| stl.h:183:17:183:22 | assign | 1 | class:0 |
|
||||||
| stl.h:184:47:184:52 | assign | 1 | class:0 |
|
| stl.h:184:47:184:52 | assign | 0 | func:0 |
|
||||||
| stl.h:185:17:185:22 | insert | 0 | func:0 |
|
| stl.h:184:47:184:52 | assign | 1 | func:0 |
|
||||||
| stl.h:185:17:185:22 | insert | 1 | func:0 |
|
| stl.h:185:17:185:22 | insert | 0 | size_type |
|
||||||
|
| stl.h:185:17:185:22 | insert | 1 | const basic_string & |
|
||||||
| stl.h:186:17:186:22 | insert | 0 | size_type |
|
| stl.h:186:17:186:22 | insert | 0 | size_type |
|
||||||
| stl.h:186:17:186:22 | insert | 1 | const basic_string & |
|
| stl.h:186:17:186:22 | insert | 1 | size_type |
|
||||||
|
| stl.h:186:17:186:22 | insert | 2 | class:0 |
|
||||||
| stl.h:187:17:187:22 | insert | 0 | size_type |
|
| stl.h:187:17:187:22 | insert | 0 | size_type |
|
||||||
| stl.h:187:17:187:22 | insert | 1 | size_type |
|
| stl.h:187:17:187:22 | insert | 1 | const class:0 * |
|
||||||
| stl.h:187:17:187:22 | insert | 2 | class:0 |
|
| stl.h:188:12:188:17 | insert | 0 | const_iterator |
|
||||||
| stl.h:188:12:188:17 | insert | 0 | size_type |
|
| stl.h:188:12:188:17 | insert | 1 | size_type |
|
||||||
| stl.h:188:12:188:17 | insert | 1 | const class:0 * |
|
| stl.h:188:12:188:17 | insert | 2 | class:0 |
|
||||||
| stl.h:189:42:189:47 | insert | 0 | const_iterator |
|
| stl.h:189:42:189:47 | insert | 0 | const_iterator |
|
||||||
| stl.h:189:42:189:47 | insert | 1 | size_type |
|
| stl.h:189:42:189:47 | insert | 1 | func:0 |
|
||||||
| stl.h:189:42:189:47 | insert | 2 | class:0 |
|
| stl.h:189:42:189:47 | insert | 2 | func:0 |
|
||||||
| stl.h:190:17:190:23 | replace | 0 | const_iterator |
|
| stl.h:190:17:190:23 | replace | 0 | size_type |
|
||||||
| stl.h:190:17:190:23 | replace | 1 | func:0 |
|
| stl.h:190:17:190:23 | replace | 1 | size_type |
|
||||||
| stl.h:190:17:190:23 | replace | 2 | func:0 |
|
| stl.h:190:17:190:23 | replace | 2 | const basic_string & |
|
||||||
| stl.h:191:17:191:23 | replace | 0 | size_type |
|
| stl.h:191:17:191:23 | replace | 0 | size_type |
|
||||||
| stl.h:191:17:191:23 | replace | 1 | size_type |
|
| stl.h:191:17:191:23 | replace | 1 | size_type |
|
||||||
| stl.h:191:17:191:23 | replace | 2 | const basic_string & |
|
| stl.h:191:17:191:23 | replace | 2 | size_type |
|
||||||
| stl.h:192:13:192:16 | copy | 0 | size_type |
|
| stl.h:191:17:191:23 | replace | 3 | class:0 |
|
||||||
|
| stl.h:192:13:192:16 | copy | 0 | class:0 * |
|
||||||
| stl.h:192:13:192:16 | copy | 1 | size_type |
|
| stl.h:192:13:192:16 | copy | 1 | size_type |
|
||||||
| stl.h:192:13:192:16 | copy | 2 | size_type |
|
| stl.h:192:13:192:16 | copy | 2 | size_type |
|
||||||
| stl.h:192:13:192:16 | copy | 3 | class:0 |
|
| stl.h:194:16:194:21 | substr | 0 | size_type |
|
||||||
| stl.h:193:8:193:12 | clear | 0 | class:0 * |
|
| stl.h:194:16:194:21 | substr | 1 | size_type |
|
||||||
| stl.h:193:8:193:12 | clear | 1 | size_type |
|
| stl.h:195:8:195:11 | swap | 0 | basic_string & |
|
||||||
| stl.h:193:8:193:12 | clear | 2 | size_type |
|
|
||||||
| stl.h:195:8:195:11 | swap | 0 | size_type |
|
|
||||||
| stl.h:195:8:195:11 | swap | 1 | size_type |
|
|
||||||
| stl.h:198:94:198:102 | operator+ | 0 | const basic_string & |
|
| stl.h:198:94:198:102 | operator+ | 0 | const basic_string & |
|
||||||
| stl.h:198:94:198:102 | operator+ | 1 | const basic_string & |
|
| stl.h:198:94:198:102 | operator+ | 1 | const basic_string & |
|
||||||
| stl.h:199:94:199:102 | operator+ | 0 | const basic_string & |
|
| stl.h:199:94:199:102 | operator+ | 0 | const basic_string & |
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
| file://:0:0:0:0 | E<C>'s friend | loop.cpp:5:26:5:26 | E<D> |
|
|
||||||
| file://:0:0:0:0 | E<C>'s friend | loop.cpp:5:26:5:26 | E<T> |
|
| file://:0:0:0:0 | E<C>'s friend | loop.cpp:5:26:5:26 | E<T> |
|
||||||
| file://:0:0:0:0 | E<C>'s friend | loop.cpp:10:26:10:26 | F<D> |
|
| file://:0:0:0:0 | E<C>'s friend | loop.cpp:5:26:5:29 | E<D> |
|
||||||
| file://:0:0:0:0 | E<C>'s friend | loop.cpp:10:26:10:26 | F<T> |
|
| file://:0:0:0:0 | E<C>'s friend | loop.cpp:10:26:10:26 | F<T> |
|
||||||
| file://:0:0:0:0 | E<D>'s friend | loop.cpp:5:26:5:26 | E<C> |
|
| file://:0:0:0:0 | E<C>'s friend | loop.cpp:10:26:10:29 | F<D> |
|
||||||
| file://:0:0:0:0 | E<D>'s friend | loop.cpp:5:26:5:26 | E<T> |
|
| file://:0:0:0:0 | E<D>'s friend | loop.cpp:5:26:5:26 | E<T> |
|
||||||
| file://:0:0:0:0 | E<D>'s friend | loop.cpp:10:26:10:26 | F<D> |
|
| file://:0:0:0:0 | E<D>'s friend | loop.cpp:5:26:5:29 | E<C> |
|
||||||
| file://:0:0:0:0 | E<D>'s friend | loop.cpp:10:26:10:26 | F<T> |
|
| file://:0:0:0:0 | E<D>'s friend | loop.cpp:10:26:10:26 | F<T> |
|
||||||
| file://:0:0:0:0 | F<D>'s friend | loop.cpp:5:26:5:26 | E<C> |
|
| file://:0:0:0:0 | E<D>'s friend | loop.cpp:10:26:10:29 | F<D> |
|
||||||
| file://:0:0:0:0 | F<D>'s friend | loop.cpp:5:26:5:26 | E<D> |
|
|
||||||
| file://:0:0:0:0 | F<D>'s friend | loop.cpp:5:26:5:26 | E<T> |
|
| file://:0:0:0:0 | F<D>'s friend | loop.cpp:5:26:5:26 | E<T> |
|
||||||
|
| file://:0:0:0:0 | F<D>'s friend | loop.cpp:5:26:5:29 | E<C> |
|
||||||
|
| file://:0:0:0:0 | F<D>'s friend | loop.cpp:5:26:5:29 | E<D> |
|
||||||
| loop.cpp:6:5:6:5 | E<T>'s friend | loop.cpp:5:26:5:26 | E<T> |
|
| loop.cpp:6:5:6:5 | E<T>'s friend | loop.cpp:5:26:5:26 | E<T> |
|
||||||
| loop.cpp:7:5:7:5 | E<T>'s friend | loop.cpp:7:36:7:36 | F<U> |
|
| loop.cpp:7:5:7:5 | E<T>'s friend | loop.cpp:7:36:7:36 | F<U> |
|
||||||
| loop.cpp:11:5:11:5 | F<T>'s friend | loop.cpp:11:36:11:36 | E<U> |
|
| loop.cpp:11:5:11:5 | F<T>'s friend | loop.cpp:11:36:11:36 | E<U> |
|
||||||
|
|||||||
@@ -664,7 +664,7 @@ namespace Semmle.Extraction.CSharp
|
|||||||
// Find the (possibly unbound) original extension method that maps to this implementation (if any).
|
// Find the (possibly unbound) original extension method that maps to this implementation (if any).
|
||||||
var unboundDeclaration = extensions.SelectMany(e => e.GetMembers())
|
var unboundDeclaration = extensions.SelectMany(e => e.GetMembers())
|
||||||
.OfType<IMethodSymbol>()
|
.OfType<IMethodSymbol>()
|
||||||
.FirstOrDefault(m => SymbolEqualityComparer.Default.Equals(m.AssociatedExtensionImplementation, method.ConstructedFrom));
|
.FirstOrDefault(m => SymbolEqualityComparer.Default.Equals(m.AssociatedExtensionImplementation?.ConstructedFrom, method.ConstructedFrom));
|
||||||
|
|
||||||
var isFullyConstructed = method.IsBoundGenericMethod();
|
var isFullyConstructed = method.IsBoundGenericMethod();
|
||||||
if (isFullyConstructed && unboundDeclaration?.ContainingType is INamedTypeSymbol extensionType)
|
if (isFullyConstructed && unboundDeclaration?.ContainingType is INamedTypeSymbol extensionType)
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
Overrides(trapFile);
|
Overrides(trapFile);
|
||||||
|
ExtractRefReturn(trapFile, Symbol, this);
|
||||||
|
|
||||||
if (Symbol.FromSource() && !HasBody)
|
if (Symbol.FromSource() && !HasBody)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ source https://api.nuget.org/v3/index.json
|
|||||||
# behave like nuget in choosing transitive dependency versions
|
# behave like nuget in choosing transitive dependency versions
|
||||||
strategy: max
|
strategy: max
|
||||||
|
|
||||||
nuget Basic.CompilerLog.Util 0.9.25
|
nuget Basic.CompilerLog.Util 0.9.39
|
||||||
nuget Mono.Posix.NETStandard
|
nuget Mono.Posix.NETStandard
|
||||||
nuget Newtonsoft.Json
|
nuget Newtonsoft.Json
|
||||||
nuget NuGet.Versioning
|
nuget NuGet.Versioning
|
||||||
@@ -12,7 +12,7 @@ nuget xunit
|
|||||||
nuget xunit.runner.visualstudio
|
nuget xunit.runner.visualstudio
|
||||||
nuget xunit.runner.utility
|
nuget xunit.runner.utility
|
||||||
nuget Microsoft.NET.Test.Sdk
|
nuget Microsoft.NET.Test.Sdk
|
||||||
nuget Microsoft.CodeAnalysis.CSharp 5.0.0
|
nuget Microsoft.CodeAnalysis.CSharp 5.3.0
|
||||||
nuget Microsoft.CodeAnalysis 5.0.0
|
nuget Microsoft.CodeAnalysis 5.3.0
|
||||||
nuget Microsoft.Build 18.0.2
|
nuget Microsoft.Build 18.6.3
|
||||||
nuget Microsoft.VisualStudio.SolutionPersistence
|
nuget Microsoft.VisualStudio.SolutionPersistence
|
||||||
|
|||||||
100
csharp/paket.lock
generated
100
csharp/paket.lock
generated
@@ -3,45 +3,42 @@ STRATEGY: MAX
|
|||||||
RESTRICTION: == net10.0
|
RESTRICTION: == net10.0
|
||||||
NUGET
|
NUGET
|
||||||
remote: https://api.nuget.org/v3/index.json
|
remote: https://api.nuget.org/v3/index.json
|
||||||
Basic.CompilerLog.Util (0.9.25)
|
Basic.CompilerLog.Util (0.9.39)
|
||||||
MessagePack (>= 3.1.4)
|
MessagePack (>= 3.1.4)
|
||||||
Microsoft.Bcl.Memory (>= 9.0.10)
|
Microsoft.Bcl.Memory (>= 10.0.7)
|
||||||
Microsoft.CodeAnalysis (>= 4.8)
|
Microsoft.CodeAnalysis (>= 4.8)
|
||||||
Microsoft.CodeAnalysis.CSharp (>= 4.8)
|
Microsoft.CodeAnalysis.CSharp (>= 4.8)
|
||||||
Microsoft.CodeAnalysis.VisualBasic (>= 4.8)
|
Microsoft.CodeAnalysis.VisualBasic (>= 4.8)
|
||||||
Microsoft.Extensions.ObjectPool (>= 9.0.10)
|
Microsoft.Extensions.ObjectPool (>= 10.0.7)
|
||||||
MSBuild.StructuredLogger (>= 2.3.71)
|
MSBuild.StructuredLogger (>= 2.3.178)
|
||||||
NaturalSort.Extension (>= 4.4)
|
|
||||||
NuGet.Versioning (>= 6.14)
|
|
||||||
Humanizer.Core (3.0.10)
|
Humanizer.Core (3.0.10)
|
||||||
MessagePack (3.1.4)
|
MessagePack (3.1.6)
|
||||||
MessagePack.Annotations (>= 3.1.4)
|
MessagePack.Annotations (>= 3.1.6)
|
||||||
MessagePackAnalyzer (>= 3.1.4)
|
MessagePackAnalyzer (>= 3.1.6)
|
||||||
Microsoft.NET.StringTools (>= 17.11.4)
|
Microsoft.NET.StringTools (>= 17.11.4)
|
||||||
MessagePack.Annotations (3.1.4)
|
MessagePack.Annotations (3.1.6)
|
||||||
MessagePackAnalyzer (3.1.4)
|
MessagePackAnalyzer (3.1.6)
|
||||||
Microsoft.Bcl.AsyncInterfaces (10.0.8)
|
Microsoft.Bcl.AsyncInterfaces (10.0.8)
|
||||||
Microsoft.Bcl.Memory (10.0.8)
|
Microsoft.Bcl.Memory (10.0.8)
|
||||||
Microsoft.Build (18.0.2)
|
Microsoft.Build (18.6.3)
|
||||||
Microsoft.Build.Framework (>= 18.0.2)
|
Microsoft.Build.Framework (>= 18.6.3)
|
||||||
Microsoft.NET.StringTools (>= 18.0.2)
|
System.Configuration.ConfigurationManager (>= 10.0.3)
|
||||||
System.Configuration.ConfigurationManager (>= 9.0)
|
System.Diagnostics.EventLog (>= 10.0.3)
|
||||||
System.Diagnostics.EventLog (>= 9.0)
|
System.Reflection.MetadataLoadContext (>= 10.0.3)
|
||||||
System.Reflection.MetadataLoadContext (>= 9.0)
|
System.Security.Cryptography.ProtectedData (>= 10.0.3)
|
||||||
System.Security.Cryptography.ProtectedData (>= 9.0.6)
|
Microsoft.Build.Framework (18.6.3)
|
||||||
Microsoft.Build.Framework (18.4)
|
Microsoft.NET.StringTools (>= 18.6.3)
|
||||||
Microsoft.Build.Utilities.Core (18.4)
|
Microsoft.Build.Utilities.Core (18.6.3)
|
||||||
Microsoft.Build.Framework (>= 18.4)
|
Microsoft.Build.Framework (>= 18.6.3)
|
||||||
Microsoft.NET.StringTools (>= 18.4)
|
System.Configuration.ConfigurationManager (>= 10.0.3)
|
||||||
System.Configuration.ConfigurationManager (>= 10.0.1)
|
System.Diagnostics.EventLog (>= 10.0.3)
|
||||||
System.Diagnostics.EventLog (>= 10.0.1)
|
System.Security.Cryptography.ProtectedData (>= 10.0.3)
|
||||||
System.Security.Cryptography.ProtectedData (>= 10.0.1)
|
Microsoft.CodeAnalysis (5.3)
|
||||||
Microsoft.CodeAnalysis (5.0)
|
|
||||||
Humanizer.Core (>= 2.14.1)
|
Humanizer.Core (>= 2.14.1)
|
||||||
Microsoft.Bcl.AsyncInterfaces (>= 9.0)
|
Microsoft.Bcl.AsyncInterfaces (>= 9.0)
|
||||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1)
|
||||||
Microsoft.CodeAnalysis.CSharp.Workspaces (5.0)
|
Microsoft.CodeAnalysis.CSharp.Workspaces (5.3)
|
||||||
Microsoft.CodeAnalysis.VisualBasic.Workspaces (5.0)
|
Microsoft.CodeAnalysis.VisualBasic.Workspaces (5.3)
|
||||||
System.Buffers (>= 4.6)
|
System.Buffers (>= 4.6)
|
||||||
System.Collections.Immutable (>= 9.0)
|
System.Collections.Immutable (>= 9.0)
|
||||||
System.Composition (>= 9.0)
|
System.Composition (>= 9.0)
|
||||||
@@ -54,36 +51,36 @@ NUGET
|
|||||||
System.Threading.Channels (>= 8.0)
|
System.Threading.Channels (>= 8.0)
|
||||||
System.Threading.Tasks.Extensions (>= 4.6)
|
System.Threading.Tasks.Extensions (>= 4.6)
|
||||||
Microsoft.CodeAnalysis.Analyzers (5.3)
|
Microsoft.CodeAnalysis.Analyzers (5.3)
|
||||||
Microsoft.CodeAnalysis.Common (5.0)
|
Microsoft.CodeAnalysis.Common (5.3)
|
||||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1)
|
||||||
Microsoft.CodeAnalysis.CSharp (5.0)
|
Microsoft.CodeAnalysis.CSharp (5.3)
|
||||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1)
|
||||||
Microsoft.CodeAnalysis.Common (5.0)
|
Microsoft.CodeAnalysis.Common (5.3)
|
||||||
Microsoft.CodeAnalysis.CSharp.Workspaces (5.0)
|
Microsoft.CodeAnalysis.CSharp.Workspaces (5.3)
|
||||||
Humanizer.Core (>= 2.14.1)
|
Humanizer.Core (>= 2.14.1)
|
||||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1)
|
||||||
Microsoft.CodeAnalysis.Common (5.0)
|
Microsoft.CodeAnalysis.Common (5.3)
|
||||||
Microsoft.CodeAnalysis.CSharp (5.0)
|
Microsoft.CodeAnalysis.CSharp (5.3)
|
||||||
Microsoft.CodeAnalysis.Workspaces.Common (5.0)
|
Microsoft.CodeAnalysis.Workspaces.Common (5.3)
|
||||||
System.Composition (>= 9.0)
|
System.Composition (>= 9.0)
|
||||||
Microsoft.CodeAnalysis.VisualBasic (5.0)
|
Microsoft.CodeAnalysis.VisualBasic (5.3)
|
||||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1)
|
||||||
Microsoft.CodeAnalysis.Common (5.0)
|
Microsoft.CodeAnalysis.Common (5.3)
|
||||||
Microsoft.CodeAnalysis.VisualBasic.Workspaces (5.0)
|
Microsoft.CodeAnalysis.VisualBasic.Workspaces (5.3)
|
||||||
Humanizer.Core (>= 2.14.1)
|
Humanizer.Core (>= 2.14.1)
|
||||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1)
|
||||||
Microsoft.CodeAnalysis.Common (5.0)
|
Microsoft.CodeAnalysis.Common (5.3)
|
||||||
Microsoft.CodeAnalysis.VisualBasic (5.0)
|
Microsoft.CodeAnalysis.VisualBasic (5.3)
|
||||||
Microsoft.CodeAnalysis.Workspaces.Common (5.0)
|
Microsoft.CodeAnalysis.Workspaces.Common (5.3)
|
||||||
System.Composition (>= 9.0)
|
System.Composition (>= 9.0)
|
||||||
Microsoft.CodeAnalysis.Workspaces.Common (5.0)
|
Microsoft.CodeAnalysis.Workspaces.Common (5.3)
|
||||||
Humanizer.Core (>= 2.14.1)
|
Humanizer.Core (>= 2.14.1)
|
||||||
Microsoft.CodeAnalysis.Analyzers (>= 3.11)
|
Microsoft.CodeAnalysis.Analyzers (>= 5.3.0-2.25625.1)
|
||||||
Microsoft.CodeAnalysis.Common (5.0)
|
Microsoft.CodeAnalysis.Common (5.3)
|
||||||
System.Composition (>= 9.0)
|
System.Composition (>= 9.0)
|
||||||
Microsoft.CodeCoverage (18.5.1)
|
Microsoft.CodeCoverage (18.5.1)
|
||||||
Microsoft.Extensions.ObjectPool (10.0.8)
|
Microsoft.Extensions.ObjectPool (10.0.8)
|
||||||
Microsoft.NET.StringTools (18.4)
|
Microsoft.NET.StringTools (18.6.3)
|
||||||
Microsoft.NET.Test.Sdk (18.5.1)
|
Microsoft.NET.Test.Sdk (18.5.1)
|
||||||
Microsoft.CodeCoverage (>= 18.5.1)
|
Microsoft.CodeCoverage (>= 18.5.1)
|
||||||
Microsoft.TestPlatform.TestHost (>= 18.5.1)
|
Microsoft.TestPlatform.TestHost (>= 18.5.1)
|
||||||
@@ -97,7 +94,6 @@ NUGET
|
|||||||
MSBuild.StructuredLogger (2.3.204)
|
MSBuild.StructuredLogger (2.3.204)
|
||||||
Microsoft.Build.Framework (>= 17.5)
|
Microsoft.Build.Framework (>= 17.5)
|
||||||
Microsoft.Build.Utilities.Core (>= 17.5)
|
Microsoft.Build.Utilities.Core (>= 17.5)
|
||||||
NaturalSort.Extension (4.4.1)
|
|
||||||
Newtonsoft.Json (13.0.4)
|
Newtonsoft.Json (13.0.4)
|
||||||
NuGet.Versioning (7.6)
|
NuGet.Versioning (7.6)
|
||||||
System.Buffers (4.6.1)
|
System.Buffers (4.6.1)
|
||||||
|
|||||||
31
csharp/paket.main.bzl
generated
31
csharp/paket.main.bzl
generated
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/csharp-solorigate-all
|
name: codeql/csharp-solorigate-all
|
||||||
version: 1.7.68
|
version: 1.7.69-dev
|
||||||
groups:
|
groups:
|
||||||
- csharp
|
- csharp
|
||||||
- solorigate
|
- solorigate
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/csharp-solorigate-queries
|
name: codeql/csharp-solorigate-queries
|
||||||
version: 1.7.68
|
version: 1.7.69-dev
|
||||||
groups:
|
groups:
|
||||||
- csharp
|
- csharp
|
||||||
- solorigate
|
- solorigate
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
| [...]/csharp/tools/[...]/Microsoft.Win32.Primitives.dll |
|
| [...]/csharp/tools/[...]/Microsoft.Win32.Primitives.dll |
|
||||||
| [...]/csharp/tools/[...]/Microsoft.Win32.Registry.dll |
|
| [...]/csharp/tools/[...]/Microsoft.Win32.Registry.dll |
|
||||||
| [...]/csharp/tools/[...]/Mono.Posix.NETStandard.dll |
|
| [...]/csharp/tools/[...]/Mono.Posix.NETStandard.dll |
|
||||||
| [...]/csharp/tools/[...]/NaturalSort.Extension.dll |
|
|
||||||
| [...]/csharp/tools/[...]/Newtonsoft.Json.dll |
|
| [...]/csharp/tools/[...]/Newtonsoft.Json.dll |
|
||||||
| [...]/csharp/tools/[...]/NuGet.Versioning.dll |
|
| [...]/csharp/tools/[...]/NuGet.Versioning.dll |
|
||||||
| [...]/csharp/tools/[...]/StructuredLogger.dll |
|
| [...]/csharp/tools/[...]/StructuredLogger.dll |
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* Improved call target resolution for ref-return properties and indexers.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/csharp-all
|
name: codeql/csharp-all
|
||||||
version: 6.0.2
|
version: 6.0.3-dev
|
||||||
groups: csharp
|
groups: csharp
|
||||||
dbscheme: semmlecode.csharp.dbscheme
|
dbscheme: semmlecode.csharp.dbscheme
|
||||||
extractor: csharp
|
extractor: csharp
|
||||||
|
|||||||
@@ -766,7 +766,16 @@ class PropertyCall extends AccessorCall, PropertyAccessExpr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override Accessor getWriteTarget() {
|
override Accessor getWriteTarget() {
|
||||||
this instanceof AssignableWrite and result = this.getProperty().getSetter()
|
this instanceof AssignableWrite and
|
||||||
|
exists(Property p | p = this.getProperty() |
|
||||||
|
result = p.getSetter()
|
||||||
|
or
|
||||||
|
result =
|
||||||
|
any(Getter g |
|
||||||
|
g = p.getGetter() and
|
||||||
|
g.getAnnotatedReturnType().isRef()
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override Expr getArgument(int i) {
|
override Expr getArgument(int i) {
|
||||||
@@ -801,7 +810,16 @@ class IndexerCall extends AccessorCall, IndexerAccessExpr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override Accessor getWriteTarget() {
|
override Accessor getWriteTarget() {
|
||||||
this instanceof AssignableWrite and result = this.getIndexer().getSetter()
|
this instanceof AssignableWrite and
|
||||||
|
exists(Indexer i | i = this.getIndexer() |
|
||||||
|
result = i.getSetter()
|
||||||
|
or
|
||||||
|
result =
|
||||||
|
any(Getter g |
|
||||||
|
g = i.getGetter() and
|
||||||
|
g.getAnnotatedReturnType().isRef()
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override Expr getArgument(int i) {
|
override Expr getArgument(int i) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/csharp-queries
|
name: codeql/csharp-queries
|
||||||
version: 1.7.4
|
version: 1.7.5-dev
|
||||||
groups:
|
groups:
|
||||||
- csharp
|
- csharp
|
||||||
- queries
|
- queries
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ returnTypes
|
|||||||
| NullableRefTypes.cs:107:26:107:36 | ReturnsRef5 | readonly MyClass! |
|
| NullableRefTypes.cs:107:26:107:36 | ReturnsRef5 | readonly MyClass! |
|
||||||
| NullableRefTypes.cs:108:26:108:36 | ReturnsRef6 | readonly MyClass! |
|
| NullableRefTypes.cs:108:26:108:36 | ReturnsRef6 | readonly MyClass! |
|
||||||
| NullableRefTypes.cs:110:10:110:20 | Parameters1 | Void! |
|
| NullableRefTypes.cs:110:10:110:20 | Parameters1 | Void! |
|
||||||
| NullableRefTypes.cs:113:32:113:44 | get_RefProperty | MyClass! |
|
| NullableRefTypes.cs:113:32:113:44 | get_RefProperty | ref MyClass! |
|
||||||
| NullableRefTypes.cs:116:7:116:23 | <object initializer> | Void |
|
| NullableRefTypes.cs:116:7:116:23 | <object initializer> | Void |
|
||||||
| NullableRefTypes.cs:116:7:116:23 | ToStringWithTypes | Void! |
|
| NullableRefTypes.cs:116:7:116:23 | ToStringWithTypes | Void! |
|
||||||
| NullableRefTypes.cs:136:7:136:24 | <object initializer> | Void |
|
| NullableRefTypes.cs:136:7:136:24 | <object initializer> | Void |
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
class SBCS
|
class SBCS
|
||||||
{
|
{
|
||||||
string sbcs = "<22>";
|
string sbcs = "<22>";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
| indexers.cs:24:21:24:24 | Item | indexers.cs:62:22:62:29 | access to indexer | indexers.cs:26:13:26:15 | get_Item |
|
||||||
|
| indexers.cs:24:21:24:24 | Item | indexers.cs:65:25:65:32 | access to indexer | indexers.cs:34:13:34:15 | set_Item |
|
||||||
|
| indexers.cs:143:24:143:27 | Item | indexers.cs:156:13:156:16 | access to indexer | indexers.cs:145:13:145:15 | get_Item |
|
||||||
|
| indexers.cs:143:24:143:27 | Item | indexers.cs:157:21:157:24 | access to indexer | indexers.cs:145:13:145:15 | get_Item |
|
||||||
8
csharp/ql/test/library-tests/indexers/Indexers13.ql
Normal file
8
csharp/ql/test/library-tests/indexers/Indexers13.ql
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import csharp
|
||||||
|
|
||||||
|
from IndexerCall ic, Indexer i, Accessor target
|
||||||
|
where
|
||||||
|
ic.getIndexer() = i and
|
||||||
|
ic.getTarget() = target and
|
||||||
|
i.fromSource()
|
||||||
|
select i, ic, target
|
||||||
@@ -360,3 +360,57 @@ indexers.cs:
|
|||||||
# 130| 4: [BlockStmt] {...}
|
# 130| 4: [BlockStmt] {...}
|
||||||
# 130| 0: [ReturnStmt] return ...;
|
# 130| 0: [ReturnStmt] return ...;
|
||||||
# 130| 0: [IntLiteral] 0
|
# 130| 0: [IntLiteral] 0
|
||||||
|
# 134| 5: [RefStruct] S
|
||||||
|
# 136| 6: [Field] x
|
||||||
|
# 136| -1: [TypeMention] int
|
||||||
|
# 138| 7: [InstanceConstructor] S
|
||||||
|
#-----| 2: (Parameters)
|
||||||
|
# 138| 0: [Parameter] v
|
||||||
|
# 138| -1: [TypeMention] int
|
||||||
|
# 139| 4: [BlockStmt] {...}
|
||||||
|
# 140| 0: [ExprStmt] ...;
|
||||||
|
# 140| 0: [AssignExpr] ... = ...
|
||||||
|
# 140| 0: [FieldAccess] access to field x
|
||||||
|
# 140| 1: [RefExpr] ref ...
|
||||||
|
# 140| 0: [ParameterAccess] access to parameter v
|
||||||
|
# 143| 8: [Indexer] Item
|
||||||
|
# 143| -1: [TypeMention] int
|
||||||
|
#-----| 1: (Parameters)
|
||||||
|
# 143| 0: [Parameter] i
|
||||||
|
# 143| -1: [TypeMention] int
|
||||||
|
# 145| 3: [Getter] get_Item
|
||||||
|
#-----| 2: (Parameters)
|
||||||
|
# 143| 0: [Parameter] i
|
||||||
|
# 145| 4: [BlockStmt] {...}
|
||||||
|
# 145| 0: [ReturnStmt] return ...;
|
||||||
|
# 145| 0: [RefExpr] ref ...
|
||||||
|
# 145| 0: [FieldAccess] access to field x
|
||||||
|
# 149| 6: [Class] TestRefReturns
|
||||||
|
# 151| 6: [Method] M
|
||||||
|
# 151| -1: [TypeMention] Void
|
||||||
|
# 152| 4: [BlockStmt] {...}
|
||||||
|
# 153| 0: [LocalVariableDeclStmt] ... ...;
|
||||||
|
# 153| 0: [LocalVariableDeclAndInitExpr] Int32 a = ...
|
||||||
|
# 153| -1: [TypeMention] int
|
||||||
|
# 153| 0: [LocalVariableAccess] access to local variable a
|
||||||
|
# 153| 1: [IntLiteral] 0
|
||||||
|
# 155| 1: [LocalVariableDeclStmt] ... ...;
|
||||||
|
# 155| 0: [LocalVariableDeclAndInitExpr] S s = ...
|
||||||
|
# 155| -1: [TypeMention] S
|
||||||
|
# 155| 0: [LocalVariableAccess] access to local variable s
|
||||||
|
# 155| 1: [ObjectCreation] object creation of type S
|
||||||
|
# 155| -1: [TypeMention] S
|
||||||
|
# 155| 0: [LocalVariableAccess] access to local variable a
|
||||||
|
# 156| 2: [ExprStmt] ...;
|
||||||
|
# 156| 0: [AssignExpr] ... = ...
|
||||||
|
# 156| 0: [IndexerCall] access to indexer
|
||||||
|
# 156| -1: [LocalVariableAccess] access to local variable s
|
||||||
|
# 156| 0: [IntLiteral] 0
|
||||||
|
# 156| 1: [IntLiteral] 1
|
||||||
|
# 157| 3: [LocalVariableDeclStmt] ... ...;
|
||||||
|
# 157| 0: [LocalVariableDeclAndInitExpr] Int32 x = ...
|
||||||
|
# 157| -1: [TypeMention] int
|
||||||
|
# 157| 0: [LocalVariableAccess] access to local variable x
|
||||||
|
# 157| 1: [IndexerCall] access to indexer
|
||||||
|
# 157| -1: [LocalVariableAccess] access to local variable s
|
||||||
|
# 157| 0: [IntLiteral] 0
|
||||||
|
|||||||
@@ -130,4 +130,31 @@ namespace Indexers
|
|||||||
get { return 0; }
|
get { return 0; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ref struct S
|
||||||
|
{
|
||||||
|
private ref int x;
|
||||||
|
|
||||||
|
public S(ref int v)
|
||||||
|
{
|
||||||
|
x = ref v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ref int this[int i]
|
||||||
|
{
|
||||||
|
get { return ref x; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestRefReturns
|
||||||
|
{
|
||||||
|
public void M()
|
||||||
|
{
|
||||||
|
int a = 0;
|
||||||
|
|
||||||
|
S s = new S(ref a);
|
||||||
|
s[0] = 1;
|
||||||
|
var x = s[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -246,3 +246,50 @@ properties.cs:
|
|||||||
# 133| 0: [FieldAccess] access to field Prop.field
|
# 133| 0: [FieldAccess] access to field Prop.field
|
||||||
# 133| 1: [ParameterAccess] access to parameter value
|
# 133| 1: [ParameterAccess] access to parameter value
|
||||||
# 130| 7: [Field] Prop.field
|
# 130| 7: [Field] Prop.field
|
||||||
|
# 137| 11: [RefStruct] S
|
||||||
|
# 139| 6: [Field] x
|
||||||
|
# 139| -1: [TypeMention] int
|
||||||
|
# 141| 7: [InstanceConstructor] S
|
||||||
|
#-----| 2: (Parameters)
|
||||||
|
# 141| 0: [Parameter] v
|
||||||
|
# 141| -1: [TypeMention] int
|
||||||
|
# 142| 4: [BlockStmt] {...}
|
||||||
|
# 143| 0: [ExprStmt] ...;
|
||||||
|
# 143| 0: [AssignExpr] ... = ...
|
||||||
|
# 143| 0: [FieldAccess] access to field x
|
||||||
|
# 143| 1: [RefExpr] ref ...
|
||||||
|
# 143| 0: [ParameterAccess] access to parameter v
|
||||||
|
# 146| 8: [Property] Prop
|
||||||
|
# 146| -1: [TypeMention] int
|
||||||
|
# 148| 3: [Getter] get_Prop
|
||||||
|
# 148| 4: [BlockStmt] {...}
|
||||||
|
# 148| 0: [ReturnStmt] return ...;
|
||||||
|
# 148| 0: [RefExpr] ref ...
|
||||||
|
# 148| 0: [FieldAccess] access to field x
|
||||||
|
# 152| 12: [Class] TestRefReturns
|
||||||
|
# 154| 6: [Method] M
|
||||||
|
# 154| -1: [TypeMention] Void
|
||||||
|
# 155| 4: [BlockStmt] {...}
|
||||||
|
# 156| 0: [LocalVariableDeclStmt] ... ...;
|
||||||
|
# 156| 0: [LocalVariableDeclAndInitExpr] Int32 a = ...
|
||||||
|
# 156| -1: [TypeMention] int
|
||||||
|
# 156| 0: [LocalVariableAccess] access to local variable a
|
||||||
|
# 156| 1: [IntLiteral] 0
|
||||||
|
# 158| 1: [LocalVariableDeclStmt] ... ...;
|
||||||
|
# 158| 0: [LocalVariableDeclAndInitExpr] S s = ...
|
||||||
|
# 158| -1: [TypeMention] S
|
||||||
|
# 158| 0: [LocalVariableAccess] access to local variable s
|
||||||
|
# 158| 1: [ObjectCreation] object creation of type S
|
||||||
|
# 158| -1: [TypeMention] S
|
||||||
|
# 158| 0: [LocalVariableAccess] access to local variable a
|
||||||
|
# 159| 2: [ExprStmt] ...;
|
||||||
|
# 159| 0: [AssignExpr] ... = ...
|
||||||
|
# 159| 0: [PropertyCall] access to property Prop
|
||||||
|
# 159| -1: [LocalVariableAccess] access to local variable s
|
||||||
|
# 159| 1: [IntLiteral] 1
|
||||||
|
# 160| 3: [LocalVariableDeclStmt] ... ...;
|
||||||
|
# 160| 0: [LocalVariableDeclAndInitExpr] Int32 x = ...
|
||||||
|
# 160| -1: [TypeMention] int
|
||||||
|
# 160| 0: [LocalVariableAccess] access to local variable x
|
||||||
|
# 160| 1: [PropertyCall] access to property Prop
|
||||||
|
# 160| -1: [LocalVariableAccess] access to local variable s
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
| Prop.field |
|
| Prop.field |
|
||||||
| caption |
|
| caption |
|
||||||
| next |
|
| next |
|
||||||
|
| x |
|
||||||
| y |
|
| y |
|
||||||
| z |
|
| z |
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
| properties.cs:12:23:12:29 | Caption | properties.cs:29:13:29:28 | access to property Caption | properties.cs:17:13:17:15 | set_Caption |
|
||||||
|
| properties.cs:12:23:12:29 | Caption | properties.cs:30:24:30:39 | access to property Caption | properties.cs:15:13:15:15 | get_Caption |
|
||||||
|
| properties.cs:57:20:57:20 | X | properties.cs:61:13:61:13 | access to property X | properties.cs:57:37:57:39 | set_X |
|
||||||
|
| properties.cs:58:20:58:20 | Y | properties.cs:62:13:62:13 | access to property Y | properties.cs:58:37:58:39 | set_Y |
|
||||||
|
| properties.cs:70:28:70:28 | X | properties.cs:82:46:82:51 | access to property X | properties.cs:70:32:70:34 | get_X |
|
||||||
|
| properties.cs:71:28:71:28 | Y | properties.cs:83:39:83:44 | access to property Y | properties.cs:74:13:74:15 | set_Y |
|
||||||
|
| properties.cs:146:24:146:27 | Prop | properties.cs:159:13:159:18 | access to property Prop | properties.cs:148:13:148:15 | get_Prop |
|
||||||
|
| properties.cs:146:24:146:27 | Prop | properties.cs:160:21:160:26 | access to property Prop | properties.cs:148:13:148:15 | get_Prop |
|
||||||
8
csharp/ql/test/library-tests/properties/Properties19.ql
Normal file
8
csharp/ql/test/library-tests/properties/Properties19.ql
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import csharp
|
||||||
|
|
||||||
|
from PropertyCall pc, Property p, Accessor target
|
||||||
|
where
|
||||||
|
pc.getProperty() = p and
|
||||||
|
pc.getTarget() = target and
|
||||||
|
p.fromSource()
|
||||||
|
select p, pc, target
|
||||||
@@ -133,4 +133,31 @@ namespace Properties
|
|||||||
set { field = value; }
|
set { field = value; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ref struct S
|
||||||
|
{
|
||||||
|
private ref int x;
|
||||||
|
|
||||||
|
public S(ref int v)
|
||||||
|
{
|
||||||
|
x = ref v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ref int Prop
|
||||||
|
{
|
||||||
|
get { return ref x; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestRefReturns
|
||||||
|
{
|
||||||
|
public void M()
|
||||||
|
{
|
||||||
|
int a = 0;
|
||||||
|
|
||||||
|
S s = new S(ref a);
|
||||||
|
s.Prop = 1;
|
||||||
|
var x = s.Prop;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
| Quality.cs:26:19:26:26 | access to indexer | Call without target $@. | Quality.cs:26:19:26:26 | access to indexer | access to indexer |
|
| Quality.cs:26:19:26:26 | access to indexer | Call without target $@. | Quality.cs:26:19:26:26 | access to indexer | access to indexer |
|
||||||
| Quality.cs:29:21:29:27 | access to indexer | Call without target $@. | Quality.cs:29:21:29:27 | access to indexer | access to indexer |
|
| Quality.cs:29:21:29:27 | access to indexer | Call without target $@. | Quality.cs:29:21:29:27 | access to indexer | access to indexer |
|
||||||
| Quality.cs:32:9:32:21 | access to indexer | Call without target $@. | Quality.cs:32:9:32:21 | access to indexer | access to indexer |
|
|
||||||
|
|||||||
@@ -9,6 +9,5 @@
|
|||||||
| Quality.cs:23:9:23:30 | delegate call | Call without target $@. | Quality.cs:23:9:23:30 | delegate call | delegate call |
|
| Quality.cs:23:9:23:30 | delegate call | Call without target $@. | Quality.cs:23:9:23:30 | delegate call | delegate call |
|
||||||
| Quality.cs:26:19:26:26 | access to indexer | Call without target $@. | Quality.cs:26:19:26:26 | access to indexer | access to indexer |
|
| Quality.cs:26:19:26:26 | access to indexer | Call without target $@. | Quality.cs:26:19:26:26 | access to indexer | access to indexer |
|
||||||
| Quality.cs:29:21:29:27 | access to indexer | Call without target $@. | Quality.cs:29:21:29:27 | access to indexer | access to indexer |
|
| Quality.cs:29:21:29:27 | access to indexer | Call without target $@. | Quality.cs:29:21:29:27 | access to indexer | access to indexer |
|
||||||
| Quality.cs:32:9:32:21 | access to indexer | Call without target $@. | Quality.cs:32:9:32:21 | access to indexer | access to indexer |
|
|
||||||
| Quality.cs:38:16:38:26 | access to property MyProperty2 | Call without target $@. | Quality.cs:38:16:38:26 | access to property MyProperty2 | access to property MyProperty2 |
|
| Quality.cs:38:16:38:26 | access to property MyProperty2 | Call without target $@. | Quality.cs:38:16:38:26 | access to property MyProperty2 | access to property MyProperty2 |
|
||||||
| Quality.cs:50:20:50:26 | object creation of type T | Call without target $@. | Quality.cs:50:20:50:26 | object creation of type T | object creation of type T |
|
| Quality.cs:50:20:50:26 | object creation of type T | Call without target $@. | Quality.cs:50:20:50:26 | object creation of type T | object creation of type T |
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class Test
|
|||||||
var slice = sp[..3]; // TODO: this is not an indexer call, but rather a `sp.Slice(0, 3)` call.
|
var slice = sp[..3]; // TODO: this is not an indexer call, but rather a `sp.Slice(0, 3)` call.
|
||||||
|
|
||||||
Span<byte> guidBytes = stackalloc byte[16];
|
Span<byte> guidBytes = stackalloc byte[16];
|
||||||
guidBytes[08] = 1; // TODO: this indexer call has no target, because the target is a `ref` returning getter.
|
guidBytes[08] = 1;
|
||||||
|
|
||||||
new MyList([new(), new Test()]);
|
new MyList([new(), new Test()]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql-go-consistency-queries
|
name: codeql-go-consistency-queries
|
||||||
version: 1.0.51
|
version: 1.0.52-dev
|
||||||
groups:
|
groups:
|
||||||
- go
|
- go
|
||||||
- queries
|
- queries
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* More logging functions are now recognized as not returning or panicking.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/go-all
|
name: codeql/go-all
|
||||||
version: 7.1.2
|
version: 7.1.3-dev
|
||||||
groups: go
|
groups: go
|
||||||
dbscheme: go.dbscheme
|
dbscheme: go.dbscheme
|
||||||
extractor: go
|
extractor: go
|
||||||
|
|||||||
@@ -413,17 +413,13 @@ private class ExternalLoggerCall extends LoggerCall::Range, DataFlow::CallNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private class HeuristicLoggerFunction extends Method {
|
||||||
* A call to an interface that looks like a logger. It is common to use a
|
string logFunctionPrefix;
|
||||||
* locally-defined interface for logging to make it easy to changing logging
|
|
||||||
* library.
|
HeuristicLoggerFunction() {
|
||||||
*/
|
exists(string tp, string name |
|
||||||
private class HeuristicLoggerCall extends LoggerCall::Range, DataFlow::CallNode {
|
this.hasQualifiedName(_, tp, name) and
|
||||||
HeuristicLoggerCall() {
|
this.getReceiverBaseType().getUnderlyingType() instanceof InterfaceType
|
||||||
exists(Method m, string tp, string logFunctionPrefix, string name |
|
|
||||||
m = this.getTarget() and
|
|
||||||
m.hasQualifiedName(_, tp, name) and
|
|
||||||
m.getReceiverBaseType().getUnderlyingType() instanceof InterfaceType
|
|
||||||
|
|
|
|
||||||
tp.regexpMatch(".*[lL]ogger") and
|
tp.regexpMatch(".*[lL]ogger") and
|
||||||
logFunctionPrefix =
|
logFunctionPrefix =
|
||||||
@@ -435,6 +431,19 @@ private class HeuristicLoggerCall extends LoggerCall::Range, DataFlow::CallNode
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override predicate mayReturnNormally() { logFunctionPrefix != "Fatal" }
|
||||||
|
|
||||||
|
override predicate mustPanic() { logFunctionPrefix = "Panic" }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A call to an interface that looks like a logger. It is common to use a
|
||||||
|
* locally-defined interface for logging to make it easy to change logging
|
||||||
|
* library.
|
||||||
|
*/
|
||||||
|
private class HeuristicLoggerCall extends LoggerCall::Range, DataFlow::CallNode {
|
||||||
|
HeuristicLoggerCall() { this.getTarget() instanceof HeuristicLoggerFunction }
|
||||||
|
|
||||||
override DataFlow::Node getAMessageComponent() { result = this.getASyntacticArgument() }
|
override DataFlow::Node getAMessageComponent() { result = this.getASyntacticArgument() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,17 +12,37 @@ import go
|
|||||||
* forks.
|
* forks.
|
||||||
*/
|
*/
|
||||||
module Glog {
|
module Glog {
|
||||||
|
/** Gets a package name for `glog` or `klog` (which is a fork). */
|
||||||
|
string packagePath() {
|
||||||
|
result =
|
||||||
|
package([
|
||||||
|
"github.com/golang/glog", "gopkg.in/glog", "k8s.io/klog", "github.com/barakmich/glog"
|
||||||
|
], "")
|
||||||
|
}
|
||||||
|
|
||||||
private class GlogFunction extends Function {
|
private class GlogFunction extends Function {
|
||||||
int firstPrintedArg;
|
int firstPrintedArg;
|
||||||
|
string format;
|
||||||
|
string level;
|
||||||
|
|
||||||
GlogFunction() {
|
GlogFunction() {
|
||||||
exists(string pkg, string fn, string level |
|
exists(string pkg, string context, int nContextArgs, string depth, int nDepthArgs, string fn |
|
||||||
pkg = package(["github.com/golang/glog", "gopkg.in/glog", "k8s.io/klog"], "") and
|
pkg = packagePath() and
|
||||||
level = ["Error", "Exit", "Fatal", "Info", "Warning"] and
|
level = ["Error", "Exit", "Fatal", "Info", "Warning"] and
|
||||||
(
|
(
|
||||||
fn = level + ["", "f", "ln"] and firstPrintedArg = 0
|
context = "" and nContextArgs = 0
|
||||||
or
|
or
|
||||||
fn = level + "Depth" and firstPrintedArg = 1
|
context = "Context" and nContextArgs = 1
|
||||||
|
) and
|
||||||
|
(
|
||||||
|
depth = "" and nDepthArgs = 0
|
||||||
|
or
|
||||||
|
depth = "Depth" and nDepthArgs = 1
|
||||||
|
) and
|
||||||
|
format = ["", "f", "ln"] and
|
||||||
|
(
|
||||||
|
fn = level + context + depth + format and
|
||||||
|
firstPrintedArg = nContextArgs + nDepthArgs
|
||||||
)
|
)
|
||||||
|
|
|
|
||||||
this.hasQualifiedName(pkg, fn)
|
this.hasQualifiedName(pkg, fn)
|
||||||
@@ -35,10 +55,15 @@ module Glog {
|
|||||||
* Gets the index of the first argument that may be output, including a format string if one is present.
|
* Gets the index of the first argument that may be output, including a format string if one is present.
|
||||||
*/
|
*/
|
||||||
int getFirstPrintedArg() { result = firstPrintedArg }
|
int getFirstPrintedArg() { result = firstPrintedArg }
|
||||||
|
|
||||||
|
/** Holds if this function takes a format string. */
|
||||||
|
predicate formatter() { format = "f" }
|
||||||
|
|
||||||
|
override predicate mayReturnNormally() { level != "Fatal" and level != "Exit" }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class StringFormatter extends StringOps::Formatting::Range instanceof GlogFunction {
|
private class StringFormatter extends StringOps::Formatting::Range instanceof GlogFunction {
|
||||||
StringFormatter() { this.getName().matches("%f") }
|
StringFormatter() { this.formatter() }
|
||||||
|
|
||||||
override int getFormatStringIndex() { result = super.getFirstPrintedArg() }
|
override int getFormatStringIndex() { result = super.getFirstPrintedArg() }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,12 @@ module Logrus {
|
|||||||
this.(Method).hasQualifiedName(packagePath(), ["Entry", "Logger"], name)
|
this.(Method).hasQualifiedName(packagePath(), ["Entry", "Logger"], name)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override predicate mayReturnNormally() {
|
||||||
|
not exists(string level, string suffix | level = ["Fatal", "Panic"] |
|
||||||
|
this.getName() = level + suffix
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class StringFormatters extends StringOps::Formatting::Range instanceof LogFunction {
|
private class StringFormatters extends StringOps::Formatting::Range instanceof LogFunction {
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ module Zap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** A Zap logging function which always panics. */
|
/** A Zap logging function which always panics. */
|
||||||
private class FatalLogMethod extends Method {
|
private class FatalLogMethod extends ZapFunction {
|
||||||
FatalLogMethod() {
|
FatalLogMethod() {
|
||||||
this.hasQualifiedName(packagePath(), "Logger", "Fatal")
|
this.hasQualifiedName(packagePath(), "Logger", "Fatal")
|
||||||
or
|
or
|
||||||
@@ -58,7 +58,7 @@ module Zap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** A Zap logging function which always panics. */
|
/** A Zap logging function which always panics. */
|
||||||
private class MustPanicLogMethod extends Method {
|
private class MustPanicLogMethod extends ZapFunction {
|
||||||
MustPanicLogMethod() {
|
MustPanicLogMethod() {
|
||||||
this.hasQualifiedName(packagePath(), "Logger", "Panic")
|
this.hasQualifiedName(packagePath(), "Logger", "Panic")
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -29,18 +29,37 @@ module Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class LogFormatter extends StringOps::Formatting::Range instanceof LogFunction {
|
private class LogFormatter extends StringOps::Formatting::Range instanceof LogFunction {
|
||||||
LogFormatter() { this.getName() = ["Fatalf", "Panicf", "Printf"] }
|
LogFormatter() { this.getName() = ["Fatalf", "Panicf", "Printf", "Panic", "Panicf", "Panicln"] }
|
||||||
|
|
||||||
override int getFormatStringIndex() { result = 0 }
|
override int getFormatStringIndex() { result = 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A fatal log function, which calls `os.Exit`. */
|
/** A fatal log function, which calls `os.Exit`. */
|
||||||
private class FatalLogFunction extends Function {
|
private class FatalLogFunction extends Function {
|
||||||
FatalLogFunction() { this.hasQualifiedName("log", ["Fatal", "Fatalf", "Fatalln"]) }
|
FatalLogFunction() {
|
||||||
|
exists(string fn | fn = ["Fatal", "Fatalf", "Fatalln"] |
|
||||||
|
this.hasQualifiedName("log", fn)
|
||||||
|
or
|
||||||
|
this.(Method).hasQualifiedName("log", "Logger", fn)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override predicate mayReturnNormally() { none() }
|
override predicate mayReturnNormally() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A log function which must panic. */
|
||||||
|
private class PanicLogFunction extends Function {
|
||||||
|
PanicLogFunction() {
|
||||||
|
exists(string fn | fn = ["Panic", "Panicf", "Panicln"] |
|
||||||
|
this.hasQualifiedName("log", fn)
|
||||||
|
or
|
||||||
|
this.(Method).hasQualifiedName("log", "Logger", fn)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override predicate mustPanic() { any() }
|
||||||
|
}
|
||||||
|
|
||||||
// These models are not implemented using Models-as-Data because they represent reverse flow.
|
// These models are not implemented using Models-as-Data because they represent reverse flow.
|
||||||
private class FunctionModels extends TaintTracking::FunctionModel {
|
private class FunctionModels extends TaintTracking::FunctionModel {
|
||||||
FunctionInput inp;
|
FunctionInput inp;
|
||||||
@@ -63,30 +82,6 @@ module Log {
|
|||||||
FunctionOutput outp;
|
FunctionOutput outp;
|
||||||
|
|
||||||
MethodModels() {
|
MethodModels() {
|
||||||
// signature: func (*Logger) Fatal(v ...interface{})
|
|
||||||
this.hasQualifiedName("log", "Logger", "Fatal") and
|
|
||||||
(inp.isParameter(_) and outp.isReceiver())
|
|
||||||
or
|
|
||||||
// signature: func (*Logger) Fatalf(format string, v ...interface{})
|
|
||||||
this.hasQualifiedName("log", "Logger", "Fatalf") and
|
|
||||||
(inp.isParameter(_) and outp.isReceiver())
|
|
||||||
or
|
|
||||||
// signature: func (*Logger) Fatalln(v ...interface{})
|
|
||||||
this.hasQualifiedName("log", "Logger", "Fatalln") and
|
|
||||||
(inp.isParameter(_) and outp.isReceiver())
|
|
||||||
or
|
|
||||||
// signature: func (*Logger) Panic(v ...interface{})
|
|
||||||
this.hasQualifiedName("log", "Logger", "Panic") and
|
|
||||||
(inp.isParameter(_) and outp.isReceiver())
|
|
||||||
or
|
|
||||||
// signature: func (*Logger) Panicf(format string, v ...interface{})
|
|
||||||
this.hasQualifiedName("log", "Logger", "Panicf") and
|
|
||||||
(inp.isParameter(_) and outp.isReceiver())
|
|
||||||
or
|
|
||||||
// signature: func (*Logger) Panicln(v ...interface{})
|
|
||||||
this.hasQualifiedName("log", "Logger", "Panicln") and
|
|
||||||
(inp.isParameter(_) and outp.isReceiver())
|
|
||||||
or
|
|
||||||
// signature: func (*Logger) Print(v ...interface{})
|
// signature: func (*Logger) Print(v ...interface{})
|
||||||
this.hasQualifiedName("log", "Logger", "Print") and
|
this.hasQualifiedName("log", "Logger", "Print") and
|
||||||
(inp.isParameter(_) and outp.isReceiver())
|
(inp.isParameter(_) and outp.isReceiver())
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/go-queries
|
name: codeql/go-queries
|
||||||
version: 1.6.4
|
version: 1.6.5-dev
|
||||||
groups:
|
groups:
|
||||||
- go
|
- go
|
||||||
- queries
|
- queries
|
||||||
|
|||||||
@@ -1,54 +1,181 @@
|
|||||||
//go:generate depstubber -vendor github.com/golang/glog "" Error,ErrorDepth,Errorf,Errorln,Exit,ExitDepth,Exitf,Exitln,Fatal,FatalDepth,Fatalf,Fatalln,Info,InfoDepth,Infof,Infoln,Warning,WarningDepth,Warningf,Warningln
|
//go:generate depstubber -vendor github.com/golang/glog Level,Verbose Error,ErrorContext,ErrorContextDepth,ErrorContextDepthf,ErrorContextf,ErrorDepth,ErrorDepthf,Errorf,Errorln,Exit,ExitContext,ExitContextDepth,ExitContextDepthf,ExitContextf,ExitDepth,ExitDepthf,Exitf,Exitln,Fatal,FatalContext,FatalContextDepth,FatalContextDepthf,FatalContextf,FatalDepth,FatalDepthf,Fatalf,Fatalln,Info,InfoContext,InfoContextDepth,InfoContextDepthf,InfoContextf,InfoDepth,InfoDepthf,Infof,Infoln,V,VDepth,Warning,WarningContext,WarningContextDepth,WarningContextDepthf,WarningContextf,WarningDepth,WarningDepthf,Warningf,Warningln
|
||||||
//go:generate depstubber -vendor k8s.io/klog "" Error,ErrorDepth,Errorf,Errorln,Exit,ExitDepth,Exitf,Exitln,Fatal,FatalDepth,Fatalf,Fatalln,Info,InfoDepth,Infof,Infoln,Warning,WarningDepth,Warningf,Warningln
|
//go:generate depstubber -vendor k8s.io/klog Level,Verbose Error,ErrorDepth,Errorf,Errorln,Exit,ExitDepth,Exitf,Exitln,Fatal,FatalDepth,Fatalf,Fatalln,Info,InfoDepth,Infof,Infoln,V,Warning,WarningDepth,Warningf,Warningln
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
)
|
)
|
||||||
|
|
||||||
func glogTest() {
|
func glogTest(selector int) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
glog.Error(text) // $ logger=text
|
glog.Error(text) // $ logger=text
|
||||||
|
glog.ErrorContext(ctx, text) // $ logger=text
|
||||||
|
glog.ErrorContextDepth(ctx, 0, text) // $ logger=text
|
||||||
|
glog.ErrorContextDepthf(ctx, 0, fmt, text) // $ logger=fmt logger=text
|
||||||
|
glog.ErrorContextf(ctx, fmt, text) // $ logger=fmt logger=text
|
||||||
glog.ErrorDepth(0, text) // $ logger=text
|
glog.ErrorDepth(0, text) // $ logger=text
|
||||||
|
glog.ErrorDepthf(0, fmt, text) // $ logger=fmt logger=text
|
||||||
glog.Errorf(fmt, text) // $ logger=fmt logger=text
|
glog.Errorf(fmt, text) // $ logger=fmt logger=text
|
||||||
glog.Errorln(text) // $ logger=text
|
glog.Errorln(text) // $ logger=text
|
||||||
|
if selector == 1 {
|
||||||
glog.Exit(text) // $ logger=text
|
glog.Exit(text) // $ logger=text
|
||||||
|
}
|
||||||
|
if selector == 2 {
|
||||||
|
glog.ExitContext(ctx, text) // $ logger=text
|
||||||
|
}
|
||||||
|
if selector == 3 {
|
||||||
|
glog.ExitContextDepth(ctx, 0, text) // $ logger=text
|
||||||
|
}
|
||||||
|
if selector == 4 {
|
||||||
|
glog.ExitContextDepthf(ctx, 0, fmt, text) // $ logger=fmt logger=text
|
||||||
|
}
|
||||||
|
if selector == 5 {
|
||||||
|
glog.ExitContextf(ctx, fmt, text) // $ logger=fmt logger=text
|
||||||
|
}
|
||||||
|
if selector == 6 {
|
||||||
glog.ExitDepth(0, text) // $ logger=text
|
glog.ExitDepth(0, text) // $ logger=text
|
||||||
|
}
|
||||||
|
if selector == 7 {
|
||||||
|
glog.ExitDepthf(0, fmt, text) // $ logger=fmt logger=text
|
||||||
|
}
|
||||||
|
if selector == 8 {
|
||||||
glog.Exitf(fmt, text) // $ logger=fmt logger=text
|
glog.Exitf(fmt, text) // $ logger=fmt logger=text
|
||||||
|
}
|
||||||
|
if selector == 9 {
|
||||||
glog.Exitln(text) // $ logger=text
|
glog.Exitln(text) // $ logger=text
|
||||||
|
}
|
||||||
|
if selector == 10 {
|
||||||
glog.Fatal(text) // $ logger=text
|
glog.Fatal(text) // $ logger=text
|
||||||
|
}
|
||||||
|
if selector == 11 {
|
||||||
|
glog.FatalContext(ctx, text) // $ logger=text
|
||||||
|
}
|
||||||
|
if selector == 12 {
|
||||||
|
glog.FatalContextDepth(ctx, 0, text) // $ logger=text
|
||||||
|
}
|
||||||
|
if selector == 13 {
|
||||||
|
glog.FatalContextDepthf(ctx, 0, fmt, text) // $ logger=fmt logger=text
|
||||||
|
}
|
||||||
|
if selector == 14 {
|
||||||
|
glog.FatalContextf(ctx, fmt, text) // $ logger=fmt logger=text
|
||||||
|
}
|
||||||
|
if selector == 15 {
|
||||||
glog.FatalDepth(0, text) // $ logger=text
|
glog.FatalDepth(0, text) // $ logger=text
|
||||||
|
}
|
||||||
|
if selector == 16 {
|
||||||
|
glog.FatalDepthf(0, fmt, text) // $ logger=fmt logger=text
|
||||||
|
}
|
||||||
|
if selector == 17 {
|
||||||
glog.Fatalf(fmt, text) // $ logger=fmt logger=text
|
glog.Fatalf(fmt, text) // $ logger=fmt logger=text
|
||||||
|
}
|
||||||
|
if selector == 18 {
|
||||||
glog.Fatalln(text) // $ logger=text
|
glog.Fatalln(text) // $ logger=text
|
||||||
|
}
|
||||||
glog.Info(text) // $ logger=text
|
glog.Info(text) // $ logger=text
|
||||||
|
glog.InfoContext(ctx, text) // $ logger=text
|
||||||
|
glog.InfoContextDepth(ctx, 0, text) // $ logger=text
|
||||||
|
glog.InfoContextDepthf(ctx, 0, fmt, text) // $ logger=fmt logger=text
|
||||||
|
glog.InfoContextf(ctx, fmt, text) // $ logger=fmt logger=text
|
||||||
glog.InfoDepth(0, text) // $ logger=text
|
glog.InfoDepth(0, text) // $ logger=text
|
||||||
|
glog.InfoDepthf(0, fmt, text) // $ logger=fmt logger=text
|
||||||
glog.Infof(fmt, text) // $ logger=fmt logger=text
|
glog.Infof(fmt, text) // $ logger=fmt logger=text
|
||||||
glog.Infoln(text) // $ logger=text
|
glog.Infoln(text) // $ logger=text
|
||||||
glog.Warning(text) // $ logger=text
|
glog.Warning(text) // $ logger=text
|
||||||
|
glog.WarningContext(ctx, text) // $ logger=text
|
||||||
|
glog.WarningContextDepth(ctx, 0, text) // $ logger=text
|
||||||
|
glog.WarningContextDepthf(ctx, 0, fmt, text) // $ logger=fmt logger=text
|
||||||
|
glog.WarningContextf(ctx, fmt, text) // $ logger=fmt logger=text
|
||||||
glog.WarningDepth(0, text) // $ logger=text
|
glog.WarningDepth(0, text) // $ logger=text
|
||||||
|
glog.WarningDepthf(0, fmt, text) // $ logger=fmt logger=text
|
||||||
glog.Warningf(fmt, text) // $ logger=fmt logger=text
|
glog.Warningf(fmt, text) // $ logger=fmt logger=text
|
||||||
glog.Warningln(text) // $ logger=text
|
glog.Warningln(text) // $ logger=text
|
||||||
|
|
||||||
|
glog.V(0).Info(text) // $ logger=text
|
||||||
|
glog.V(0).InfoContext(ctx, text) // $ logger=text
|
||||||
|
glog.V(0).InfoContextDepth(ctx, 0, text) // $ logger=text
|
||||||
|
glog.V(0).InfoContextDepthf(ctx, 0, fmt, text) // $ logger=fmt logger=text
|
||||||
|
glog.V(0).InfoContextf(ctx, fmt, text) // $ logger=fmt logger=text
|
||||||
|
glog.V(0).InfoDepth(0, text) // $ logger=text
|
||||||
|
glog.V(0).InfoDepthf(0, fmt, text) // $ logger=fmt logger=text
|
||||||
|
glog.V(0).Infof(fmt, text) // $ logger=fmt logger=text
|
||||||
|
glog.V(0).Infoln(text) // $ logger=text
|
||||||
|
glog.VDepth(0, 0).Info(text) // $ logger=text
|
||||||
|
|
||||||
// components corresponding to the format specifier "%T" are not considered vulnerable
|
// components corresponding to the format specifier "%T" are not considered vulnerable
|
||||||
|
glog.ErrorContextDepthf(ctx, 0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
glog.ErrorContextf(ctx, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
glog.ErrorDepthf(0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
glog.Errorf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
glog.Errorf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
if selector == 19 {
|
||||||
|
glog.ExitContextDepthf(ctx, 0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
}
|
||||||
|
if selector == 20 {
|
||||||
|
glog.ExitContextf(ctx, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
}
|
||||||
|
if selector == 21 {
|
||||||
|
glog.ExitDepthf(0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
}
|
||||||
|
if selector == 22 {
|
||||||
glog.Exitf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
glog.Exitf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
}
|
||||||
|
if selector == 23 {
|
||||||
|
glog.FatalContextDepthf(ctx, 0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
}
|
||||||
|
if selector == 24 {
|
||||||
|
glog.FatalContextf(ctx, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
}
|
||||||
|
if selector == 25 {
|
||||||
|
glog.FatalDepthf(0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
}
|
||||||
|
if selector == 26 {
|
||||||
glog.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
glog.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
}
|
||||||
|
glog.InfoContextDepthf(ctx, 0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
glog.InfoContextf(ctx, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
glog.InfoDepthf(0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
glog.Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
glog.Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
glog.WarningContextDepthf(ctx, 0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
glog.WarningContextf(ctx, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
glog.WarningDepthf(0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
glog.Warningf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
glog.Warningf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
glog.V(0).InfoContextDepthf(ctx, 0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
glog.V(0).InfoContextf(ctx, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
glog.V(0).InfoDepthf(0, "%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
glog.V(0).Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
|
||||||
klog.Error(text) // $ logger=text
|
klog.Error(text) // $ logger=text
|
||||||
klog.ErrorDepth(0, text) // $ logger=text
|
klog.ErrorDepth(0, text) // $ logger=text
|
||||||
klog.Errorf(fmt, text) // $ logger=fmt logger=text
|
klog.Errorf(fmt, text) // $ logger=fmt logger=text
|
||||||
klog.Errorln(text) // $ logger=text
|
klog.Errorln(text) // $ logger=text
|
||||||
|
if selector == 27 {
|
||||||
klog.Exit(text) // $ logger=text
|
klog.Exit(text) // $ logger=text
|
||||||
|
}
|
||||||
|
if selector == 28 {
|
||||||
klog.ExitDepth(0, text) // $ logger=text
|
klog.ExitDepth(0, text) // $ logger=text
|
||||||
|
}
|
||||||
|
if selector == 29 {
|
||||||
klog.Exitf(fmt, text) // $ logger=fmt logger=text
|
klog.Exitf(fmt, text) // $ logger=fmt logger=text
|
||||||
|
}
|
||||||
|
if selector == 30 {
|
||||||
klog.Exitln(text) // $ logger=text
|
klog.Exitln(text) // $ logger=text
|
||||||
|
}
|
||||||
|
if selector == 31 {
|
||||||
klog.Fatal(text) // $ logger=text
|
klog.Fatal(text) // $ logger=text
|
||||||
|
}
|
||||||
|
if selector == 32 {
|
||||||
klog.FatalDepth(0, text) // $ logger=text
|
klog.FatalDepth(0, text) // $ logger=text
|
||||||
|
}
|
||||||
|
if selector == 33 {
|
||||||
klog.Fatalf(fmt, text) // $ logger=fmt logger=text
|
klog.Fatalf(fmt, text) // $ logger=fmt logger=text
|
||||||
|
}
|
||||||
|
if selector == 34 {
|
||||||
klog.Fatalln(text) // $ logger=text
|
klog.Fatalln(text) // $ logger=text
|
||||||
|
}
|
||||||
klog.Info(text) // $ logger=text
|
klog.Info(text) // $ logger=text
|
||||||
klog.InfoDepth(0, text) // $ logger=text
|
klog.InfoDepth(0, text) // $ logger=text
|
||||||
klog.Infof(fmt, text) // $ logger=fmt logger=text
|
klog.Infof(fmt, text) // $ logger=fmt logger=text
|
||||||
@@ -57,11 +184,19 @@ func glogTest() {
|
|||||||
klog.WarningDepth(0, text) // $ logger=text
|
klog.WarningDepth(0, text) // $ logger=text
|
||||||
klog.Warningf(fmt, text) // $ logger=fmt logger=text
|
klog.Warningf(fmt, text) // $ logger=fmt logger=text
|
||||||
klog.Warningln(text) // $ logger=text
|
klog.Warningln(text) // $ logger=text
|
||||||
|
klog.V(0).Info(text) // $ logger=text
|
||||||
|
klog.V(0).Infof(fmt, text) // $ logger=fmt logger=text
|
||||||
|
klog.V(0).Infoln(text) // $ logger=text
|
||||||
|
|
||||||
// components corresponding to the format specifier "%T" are not considered vulnerable
|
// components corresponding to the format specifier "%T" are not considered vulnerable
|
||||||
klog.Errorf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
klog.Errorf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
if selector == 35 {
|
||||||
klog.Exitf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
klog.Exitf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
}
|
||||||
|
if selector == 36 {
|
||||||
klog.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
klog.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
}
|
||||||
klog.Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
klog.Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
klog.Warningf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
klog.Warningf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
klog.V(0).Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ module codeql-go-tests/concepts/loggercall
|
|||||||
go 1.15
|
go 1.15
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
github.com/golang/glog v1.2.5
|
||||||
github.com/sirupsen/logrus v1.7.0
|
github.com/sirupsen/logrus v1.7.0
|
||||||
k8s.io/klog v1.0.0
|
k8s.io/klog v1.0.0
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,5 +6,6 @@ const text = "test"
|
|||||||
var v []byte
|
var v []byte
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
glogTest(len(v))
|
||||||
stdlib()
|
stdlib()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,47 +2,125 @@
|
|||||||
// This is a simple stub for github.com/golang/glog, strictly for use in testing.
|
// This is a simple stub for github.com/golang/glog, strictly for use in testing.
|
||||||
|
|
||||||
// See the LICENSE file for information about the licensing of the original library.
|
// See the LICENSE file for information about the licensing of the original library.
|
||||||
// Source: github.com/golang/glog (exports: ; functions: Error,ErrorDepth,Errorf,Errorln,Exit,ExitDepth,Exitf,Exitln,Fatal,FatalDepth,Fatalf,Fatalln,Info,InfoDepth,Infof,Infoln,Warning,WarningDepth,Warningf,Warningln)
|
// Source: github.com/golang/glog (exports: Level,Verbose; functions: Error,ErrorContext,ErrorContextDepth,ErrorContextDepthf,ErrorContextf,ErrorDepth,ErrorDepthf,Errorf,Errorln,Exit,ExitContext,ExitContextDepth,ExitContextDepthf,ExitContextf,ExitDepth,ExitDepthf,Exitf,Exitln,Fatal,FatalContext,FatalContextDepth,FatalContextDepthf,FatalContextf,FatalDepth,FatalDepthf,Fatalf,Fatalln,Info,InfoContext,InfoContextDepth,InfoContextDepthf,InfoContextf,InfoDepth,InfoDepthf,Infof,Infoln,V,VDepth,Warning,WarningContext,WarningContextDepth,WarningContextDepthf,WarningContextf,WarningDepth,WarningDepthf,Warningf,Warningln)
|
||||||
|
|
||||||
// Package glog is a stub of github.com/golang/glog, generated by depstubber.
|
// Package glog is a stub of github.com/golang/glog, generated by depstubber.
|
||||||
package glog
|
package glog
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
type Level int32
|
||||||
|
|
||||||
|
type Verbose bool
|
||||||
|
|
||||||
func Error(_ ...interface{}) {}
|
func Error(_ ...interface{}) {}
|
||||||
|
|
||||||
|
func ErrorContext(_ context.Context, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func ErrorContextDepth(_ context.Context, _ int, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func ErrorContextDepthf(_ context.Context, _ int, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func ErrorContextf(_ context.Context, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
func ErrorDepth(_ int, _ ...interface{}) {}
|
func ErrorDepth(_ int, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func ErrorDepthf(_ int, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
func Errorf(_ string, _ ...interface{}) {}
|
func Errorf(_ string, _ ...interface{}) {}
|
||||||
|
|
||||||
func Errorln(_ ...interface{}) {}
|
func Errorln(_ ...interface{}) {}
|
||||||
|
|
||||||
func Exit(_ ...interface{}) {}
|
func Exit(_ ...interface{}) {}
|
||||||
|
|
||||||
|
func ExitContext(_ context.Context, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func ExitContextDepth(_ context.Context, _ int, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func ExitContextDepthf(_ context.Context, _ int, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func ExitContextf(_ context.Context, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
func ExitDepth(_ int, _ ...interface{}) {}
|
func ExitDepth(_ int, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func ExitDepthf(_ int, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
func Exitf(_ string, _ ...interface{}) {}
|
func Exitf(_ string, _ ...interface{}) {}
|
||||||
|
|
||||||
func Exitln(_ ...interface{}) {}
|
func Exitln(_ ...interface{}) {}
|
||||||
|
|
||||||
func Fatal(_ ...interface{}) {}
|
func Fatal(_ ...interface{}) {}
|
||||||
|
|
||||||
|
func FatalContext(_ context.Context, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func FatalContextDepth(_ context.Context, _ int, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func FatalContextDepthf(_ context.Context, _ int, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func FatalContextf(_ context.Context, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
func FatalDepth(_ int, _ ...interface{}) {}
|
func FatalDepth(_ int, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func FatalDepthf(_ int, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
func Fatalf(_ string, _ ...interface{}) {}
|
func Fatalf(_ string, _ ...interface{}) {}
|
||||||
|
|
||||||
func Fatalln(_ ...interface{}) {}
|
func Fatalln(_ ...interface{}) {}
|
||||||
|
|
||||||
func Info(_ ...interface{}) {}
|
func Info(_ ...interface{}) {}
|
||||||
|
|
||||||
|
func InfoContext(_ context.Context, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func InfoContextDepth(_ context.Context, _ int, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func InfoContextDepthf(_ context.Context, _ int, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func InfoContextf(_ context.Context, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
func InfoDepth(_ int, _ ...interface{}) {}
|
func InfoDepth(_ int, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func InfoDepthf(_ int, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
func Infof(_ string, _ ...interface{}) {}
|
func Infof(_ string, _ ...interface{}) {}
|
||||||
|
|
||||||
func Infoln(_ ...interface{}) {}
|
func Infoln(_ ...interface{}) {}
|
||||||
|
|
||||||
|
func V(_ Level) Verbose { return false }
|
||||||
|
|
||||||
|
func VDepth(_ int, _ Level) Verbose { return false }
|
||||||
|
|
||||||
func Warning(_ ...interface{}) {}
|
func Warning(_ ...interface{}) {}
|
||||||
|
|
||||||
|
func WarningContext(_ context.Context, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func WarningContextDepth(_ context.Context, _ int, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func WarningContextDepthf(_ context.Context, _ int, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func WarningContextf(_ context.Context, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
func WarningDepth(_ int, _ ...interface{}) {}
|
func WarningDepth(_ int, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func WarningDepthf(_ int, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
func Warningf(_ string, _ ...interface{}) {}
|
func Warningf(_ string, _ ...interface{}) {}
|
||||||
|
|
||||||
func Warningln(_ ...interface{}) {}
|
func Warningln(_ ...interface{}) {}
|
||||||
|
|
||||||
|
func (_ Verbose) Info(_ ...interface{}) {}
|
||||||
|
|
||||||
|
func (_ Verbose) InfoContext(_ context.Context, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func (_ Verbose) InfoContextDepth(_ context.Context, _ int, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func (_ Verbose) InfoContextDepthf(_ context.Context, _ int, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func (_ Verbose) InfoContextf(_ context.Context, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func (_ Verbose) InfoDepth(_ int, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func (_ Verbose) InfoDepthf(_ int, _ string, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func (_ Verbose) Infof(_ string, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func (_ Verbose) Infoln(_ ...interface{}) {}
|
||||||
|
|||||||
14
go/ql/test/library-tests/semmle/go/concepts/LoggerCall/vendor/k8s.io/klog/stub.go
generated
vendored
14
go/ql/test/library-tests/semmle/go/concepts/LoggerCall/vendor/k8s.io/klog/stub.go
generated
vendored
@@ -2,11 +2,15 @@
|
|||||||
// This is a simple stub for k8s.io/klog, strictly for use in testing.
|
// This is a simple stub for k8s.io/klog, strictly for use in testing.
|
||||||
|
|
||||||
// See the LICENSE file for information about the licensing of the original library.
|
// See the LICENSE file for information about the licensing of the original library.
|
||||||
// Source: k8s.io/klog (exports: ; functions: Error,ErrorDepth,Errorf,Errorln,Exit,ExitDepth,Exitf,Exitln,Fatal,FatalDepth,Fatalf,Fatalln,Info,InfoDepth,Infof,Infoln,Warning,WarningDepth,Warningf,Warningln)
|
// Source: k8s.io/klog (exports: Level,Verbose; functions: Error,ErrorDepth,Errorf,Errorln,Exit,ExitDepth,Exitf,Exitln,Fatal,FatalDepth,Fatalf,Fatalln,Info,InfoDepth,Infof,Infoln,V,Warning,WarningDepth,Warningf,Warningln)
|
||||||
|
|
||||||
// Package klog is a stub of k8s.io/klog, generated by depstubber.
|
// Package klog is a stub of k8s.io/klog, generated by depstubber.
|
||||||
package klog
|
package klog
|
||||||
|
|
||||||
|
type Level int32
|
||||||
|
|
||||||
|
type Verbose bool
|
||||||
|
|
||||||
func Error(_ ...interface{}) {}
|
func Error(_ ...interface{}) {}
|
||||||
|
|
||||||
func ErrorDepth(_ int, _ ...interface{}) {}
|
func ErrorDepth(_ int, _ ...interface{}) {}
|
||||||
@@ -39,6 +43,8 @@ func Infof(_ string, _ ...interface{}) {}
|
|||||||
|
|
||||||
func Infoln(_ ...interface{}) {}
|
func Infoln(_ ...interface{}) {}
|
||||||
|
|
||||||
|
func V(_ Level) Verbose { return false }
|
||||||
|
|
||||||
func Warning(_ ...interface{}) {}
|
func Warning(_ ...interface{}) {}
|
||||||
|
|
||||||
func WarningDepth(_ int, _ ...interface{}) {}
|
func WarningDepth(_ int, _ ...interface{}) {}
|
||||||
@@ -46,3 +52,9 @@ func WarningDepth(_ int, _ ...interface{}) {}
|
|||||||
func Warningf(_ string, _ ...interface{}) {}
|
func Warningf(_ string, _ ...interface{}) {}
|
||||||
|
|
||||||
func Warningln(_ ...interface{}) {}
|
func Warningln(_ ...interface{}) {}
|
||||||
|
|
||||||
|
func (_ Verbose) Info(_ ...interface{}) {}
|
||||||
|
|
||||||
|
func (_ Verbose) Infof(_ string, _ ...interface{}) {}
|
||||||
|
|
||||||
|
func (_ Verbose) Infoln(_ ...interface{}) {}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
# github.com/golang/glog v1.2.5
|
||||||
## explicit
|
## explicit
|
||||||
github.com/golang/glog
|
github.com/golang/glog
|
||||||
# github.com/sirupsen/logrus v1.7.0
|
# github.com/sirupsen/logrus v1.7.0
|
||||||
|
|||||||
@@ -1,11 +1,21 @@
|
|||||||
| file://:0:0:0:0 | Exit | package os |
|
| file://:0:0:0:0 | Exit | os.Exit |
|
||||||
| file://:0:0:0:0 | Fatal | package log |
|
| file://:0:0:0:0 | Fatal | log.Fatal |
|
||||||
| file://:0:0:0:0 | Fatalf | package log |
|
| file://:0:0:0:0 | Fatal | log.Logger.Fatal |
|
||||||
| file://:0:0:0:0 | Fatalln | package log |
|
| file://:0:0:0:0 | Fatalf | log.Fatalf |
|
||||||
| noretfunctions.go:8:6:8:12 | isNoRet | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph |
|
| file://:0:0:0:0 | Fatalf | log.Logger.Fatalf |
|
||||||
| noretfunctions.go:20:6:20:22 | noRetUsesLogFatal | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph |
|
| file://:0:0:0:0 | Fatalln | log.Fatalln |
|
||||||
| noretfunctions.go:24:6:24:23 | noRetUsesLogFatalf | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph |
|
| file://:0:0:0:0 | Fatalln | log.Logger.Fatalln |
|
||||||
| stmts7.go:10:6:10:15 | canRecover | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph |
|
| file://:0:0:0:0 | Panic | log.Logger.Panic |
|
||||||
| stmts.go:10:6:10:10 | test5 | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph |
|
| file://:0:0:0:0 | Panic | log.Panic |
|
||||||
| stmts.go:46:6:46:10 | test6 | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph |
|
| file://:0:0:0:0 | Panicf | log.Logger.Panicf |
|
||||||
| stmts.go:112:6:112:10 | test9 | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph |
|
| file://:0:0:0:0 | Panicf | log.Panicf |
|
||||||
|
| file://:0:0:0:0 | Panicln | log.Logger.Panicln |
|
||||||
|
| file://:0:0:0:0 | Panicln | log.Panicln |
|
||||||
|
| file://:0:0:0:0 | panic | panic |
|
||||||
|
| noretfunctions.go:8:6:8:12 | isNoRet | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.isNoRet |
|
||||||
|
| noretfunctions.go:20:6:20:22 | noRetUsesLogFatal | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.noRetUsesLogFatal |
|
||||||
|
| noretfunctions.go:24:6:24:23 | noRetUsesLogFatalf | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.noRetUsesLogFatalf |
|
||||||
|
| stmts7.go:10:6:10:15 | canRecover | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.canRecover |
|
||||||
|
| stmts.go:10:6:10:10 | test5 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.test5 |
|
||||||
|
| stmts.go:46:6:46:10 | test6 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.test6 |
|
||||||
|
| stmts.go:112:6:112:10 | test9 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.test9 |
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ import go
|
|||||||
|
|
||||||
from Function f
|
from Function f
|
||||||
where not f.mayReturnNormally()
|
where not f.mayReturnNormally()
|
||||||
select f, f.getPackage()
|
select f, f.getQualifiedName()
|
||||||
|
|||||||
@@ -15,62 +15,6 @@ func TaintStepTest_LogNew_B0I0O0(sourceCQL interface{}) interface{} {
|
|||||||
return intoWriter414
|
return intoWriter414
|
||||||
}
|
}
|
||||||
|
|
||||||
func TaintStepTest_LogLoggerFatal_B0I0O0(sourceCQL interface{}) interface{} {
|
|
||||||
fromInterface518 := sourceCQL.(interface{})
|
|
||||||
var intoLogger650 log.Logger
|
|
||||||
intoLogger650.Fatal(fromInterface518)
|
|
||||||
return intoLogger650
|
|
||||||
}
|
|
||||||
|
|
||||||
func TaintStepTest_LogLoggerFatalf_B0I0O0(sourceCQL interface{}) interface{} {
|
|
||||||
fromString784 := sourceCQL.(string)
|
|
||||||
var intoLogger957 log.Logger
|
|
||||||
intoLogger957.Fatalf(fromString784, nil)
|
|
||||||
return intoLogger957
|
|
||||||
}
|
|
||||||
|
|
||||||
func TaintStepTest_LogLoggerFatalf_B0I1O0(sourceCQL interface{}) interface{} {
|
|
||||||
fromInterface520 := sourceCQL.(interface{})
|
|
||||||
var intoLogger443 log.Logger
|
|
||||||
intoLogger443.Fatalf("", fromInterface520)
|
|
||||||
return intoLogger443
|
|
||||||
}
|
|
||||||
|
|
||||||
func TaintStepTest_LogLoggerFatalln_B0I0O0(sourceCQL interface{}) interface{} {
|
|
||||||
fromInterface127 := sourceCQL.(interface{})
|
|
||||||
var intoLogger483 log.Logger
|
|
||||||
intoLogger483.Fatalln(fromInterface127)
|
|
||||||
return intoLogger483
|
|
||||||
}
|
|
||||||
|
|
||||||
func TaintStepTest_LogLoggerPanic_B0I0O0(sourceCQL interface{}) interface{} {
|
|
||||||
fromInterface989 := sourceCQL.(interface{})
|
|
||||||
var intoLogger982 log.Logger
|
|
||||||
intoLogger982.Panic(fromInterface989)
|
|
||||||
return intoLogger982
|
|
||||||
}
|
|
||||||
|
|
||||||
func TaintStepTest_LogLoggerPanicf_B0I0O0(sourceCQL interface{}) interface{} {
|
|
||||||
fromString417 := sourceCQL.(string)
|
|
||||||
var intoLogger584 log.Logger
|
|
||||||
intoLogger584.Panicf(fromString417, nil)
|
|
||||||
return intoLogger584
|
|
||||||
}
|
|
||||||
|
|
||||||
func TaintStepTest_LogLoggerPanicf_B0I1O0(sourceCQL interface{}) interface{} {
|
|
||||||
fromInterface991 := sourceCQL.(interface{})
|
|
||||||
var intoLogger881 log.Logger
|
|
||||||
intoLogger881.Panicf("", fromInterface991)
|
|
||||||
return intoLogger881
|
|
||||||
}
|
|
||||||
|
|
||||||
func TaintStepTest_LogLoggerPanicln_B0I0O0(sourceCQL interface{}) interface{} {
|
|
||||||
fromInterface186 := sourceCQL.(interface{})
|
|
||||||
var intoLogger284 log.Logger
|
|
||||||
intoLogger284.Panicln(fromInterface186)
|
|
||||||
return intoLogger284
|
|
||||||
}
|
|
||||||
|
|
||||||
func TaintStepTest_LogLoggerPrint_B0I0O0(sourceCQL interface{}) interface{} {
|
func TaintStepTest_LogLoggerPrint_B0I0O0(sourceCQL interface{}) interface{} {
|
||||||
fromInterface908 := sourceCQL.(interface{})
|
fromInterface908 := sourceCQL.(interface{})
|
||||||
var intoLogger137 log.Logger
|
var intoLogger137 log.Logger
|
||||||
@@ -125,46 +69,6 @@ func RunAllTaints_Log() {
|
|||||||
out := TaintStepTest_LogNew_B0I0O0(source)
|
out := TaintStepTest_LogNew_B0I0O0(source)
|
||||||
sink(0, out)
|
sink(0, out)
|
||||||
}
|
}
|
||||||
{
|
|
||||||
source := newSource(1)
|
|
||||||
out := TaintStepTest_LogLoggerFatal_B0I0O0(source)
|
|
||||||
sink(1, out)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
source := newSource(2)
|
|
||||||
out := TaintStepTest_LogLoggerFatalf_B0I0O0(source)
|
|
||||||
sink(2, out)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
source := newSource(3)
|
|
||||||
out := TaintStepTest_LogLoggerFatalf_B0I1O0(source)
|
|
||||||
sink(3, out)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
source := newSource(4)
|
|
||||||
out := TaintStepTest_LogLoggerFatalln_B0I0O0(source)
|
|
||||||
sink(4, out)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
source := newSource(5)
|
|
||||||
out := TaintStepTest_LogLoggerPanic_B0I0O0(source)
|
|
||||||
sink(5, out)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
source := newSource(6)
|
|
||||||
out := TaintStepTest_LogLoggerPanicf_B0I0O0(source)
|
|
||||||
sink(6, out)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
source := newSource(7)
|
|
||||||
out := TaintStepTest_LogLoggerPanicf_B0I1O0(source)
|
|
||||||
sink(7, out)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
source := newSource(8)
|
|
||||||
out := TaintStepTest_LogLoggerPanicln_B0I0O0(source)
|
|
||||||
sink(8, out)
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
source := newSource(9)
|
source := newSource(9)
|
||||||
out := TaintStepTest_LogLoggerPrint_B0I0O0(source)
|
out := TaintStepTest_LogLoggerPrint_B0I0O0(source)
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ reverseRead
|
|||||||
| LogInjection.go:33:14:33:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
| LogInjection.go:33:14:33:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||||
| LogInjection.go:34:18:34:20 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
| LogInjection.go:34:18:34:20 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||||
| LogInjection.go:35:14:35:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
| LogInjection.go:35:14:35:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||||
| LogInjection.go:447:14:447:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
| LogInjection.go:551:14:551:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||||
| LogInjection.go:455:14:455:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
| LogInjection.go:559:14:559:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||||
| LogInjection.go:463:14:463:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
| LogInjection.go:567:14:567:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||||
| LogInjection.go:498:14:498:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
| LogInjection.go:602:14:602:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||||
| LogInjection.go:499:14:499:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
| LogInjection.go:603:14:603:16 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||||
| LogInjection.go:724:12:724:14 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
| LogInjection.go:828:12:828:14 | implicit dereference | Origin of readStep is missing a PostUpdateNode. |
|
||||||
|
|||||||
@@ -49,22 +49,22 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
log.Printf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
|
log.Printf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
|
||||||
log.Println("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
log.Println("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
||||||
|
|
||||||
if testFlag == "true" {
|
if testFlag == "1" {
|
||||||
log.Fatal("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
log.Fatal("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
||||||
}
|
}
|
||||||
if testFlag == "true" {
|
if testFlag == "2" {
|
||||||
log.Fatalf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
|
log.Fatalf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
|
||||||
}
|
}
|
||||||
if testFlag == "true" {
|
if testFlag == "3" {
|
||||||
log.Fatalln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
log.Fatalln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
||||||
}
|
}
|
||||||
if testFlag == "true" {
|
if testFlag == "4" {
|
||||||
log.Panic("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
log.Panic("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
||||||
}
|
}
|
||||||
if testFlag == "true" {
|
if testFlag == "5" {
|
||||||
log.Panicf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
|
log.Panicf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
|
||||||
}
|
}
|
||||||
if testFlag == "true" {
|
if testFlag == "6" {
|
||||||
log.Panicln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
log.Panicln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,13 +72,25 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
logger.Print("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
logger.Print("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
||||||
logger.Printf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
|
logger.Printf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
|
||||||
logger.Println("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
logger.Println("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
||||||
|
if testFlag == "7" {
|
||||||
logger.Fatal("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
logger.Fatal("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
||||||
|
}
|
||||||
|
if testFlag == "8" {
|
||||||
logger.Fatalf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
|
logger.Fatalf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
|
||||||
|
}
|
||||||
|
if testFlag == "9" {
|
||||||
logger.Fatalln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
logger.Fatalln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
||||||
|
}
|
||||||
|
if testFlag == "10" {
|
||||||
logger.Panic("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
logger.Panic("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
||||||
|
}
|
||||||
|
if testFlag == "11" {
|
||||||
logger.Panicf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
|
logger.Panicf(formatString, username, password) // $ hasTaintFlow="formatString" hasTaintFlow="username" hasTaintFlow="password"
|
||||||
|
}
|
||||||
|
if testFlag == "12" {
|
||||||
logger.Panicln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
logger.Panicln("user is logged in:", username, password) // $ hasTaintFlow="username" hasTaintFlow="password"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// k8s.io/klog
|
// k8s.io/klog
|
||||||
{
|
{
|
||||||
verbose := klog.V(0)
|
verbose := klog.V(0)
|
||||||
@@ -91,13 +103,25 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
klog.Error(username) // $ hasTaintFlow="username"
|
klog.Error(username) // $ hasTaintFlow="username"
|
||||||
klog.Errorf(username) // $ hasTaintFlow="username"
|
klog.Errorf(username) // $ hasTaintFlow="username"
|
||||||
klog.Errorln(username) // $ hasTaintFlow="username"
|
klog.Errorln(username) // $ hasTaintFlow="username"
|
||||||
|
if testFlag == "77" {
|
||||||
klog.Fatal(username) // $ hasTaintFlow="username"
|
klog.Fatal(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "78" {
|
||||||
klog.Fatalf(username) // $ hasTaintFlow="username"
|
klog.Fatalf(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "79" {
|
||||||
klog.Fatalln(username) // $ hasTaintFlow="username"
|
klog.Fatalln(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "80" {
|
||||||
klog.Exit(username) // $ hasTaintFlow="username"
|
klog.Exit(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "81" {
|
||||||
klog.Exitf(username) // $ hasTaintFlow="username"
|
klog.Exitf(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "82" {
|
||||||
klog.Exitln(username) // $ hasTaintFlow="username"
|
klog.Exitln(username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// astaxie/beego
|
// astaxie/beego
|
||||||
{
|
{
|
||||||
beego.Alert(username) // $ hasTaintFlow="username"
|
beego.Alert(username) // $ hasTaintFlow="username"
|
||||||
@@ -161,14 +185,30 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
glog.ErrorDepth(0, username) // $ hasTaintFlow="username"
|
glog.ErrorDepth(0, username) // $ hasTaintFlow="username"
|
||||||
glog.Errorf(username) // $ hasTaintFlow="username"
|
glog.Errorf(username) // $ hasTaintFlow="username"
|
||||||
glog.Errorln(username) // $ hasTaintFlow="username"
|
glog.Errorln(username) // $ hasTaintFlow="username"
|
||||||
|
if testFlag == "83" {
|
||||||
glog.Fatal(username) // $ hasTaintFlow="username"
|
glog.Fatal(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "84" {
|
||||||
glog.FatalDepth(0, username) // $ hasTaintFlow="username"
|
glog.FatalDepth(0, username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "85" {
|
||||||
glog.Fatalf(username) // $ hasTaintFlow="username"
|
glog.Fatalf(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "86" {
|
||||||
glog.Fatalln(username) // $ hasTaintFlow="username"
|
glog.Fatalln(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "87" {
|
||||||
glog.Exit(username) // $ hasTaintFlow="username"
|
glog.Exit(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "88" {
|
||||||
glog.ExitDepth(0, username) // $ hasTaintFlow="username"
|
glog.ExitDepth(0, username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "89" {
|
||||||
glog.Exitf(username) // $ hasTaintFlow="username"
|
glog.Exitf(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "90" {
|
||||||
glog.Exitln(username) // $ hasTaintFlow="username"
|
glog.Exitln(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// sirupsen/logrus
|
// sirupsen/logrus
|
||||||
@@ -187,18 +227,34 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
logrus.Errorf(username, "") // $ hasTaintFlow="username"
|
logrus.Errorf(username, "") // $ hasTaintFlow="username"
|
||||||
logrus.Errorf("", username) // $ hasTaintFlow="username"
|
logrus.Errorf("", username) // $ hasTaintFlow="username"
|
||||||
logrus.Errorln(username) // $ hasTaintFlow="username"
|
logrus.Errorln(username) // $ hasTaintFlow="username"
|
||||||
|
if testFlag == "13" {
|
||||||
logrus.Fatal(username) // $ hasTaintFlow="username"
|
logrus.Fatal(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "14" {
|
||||||
logrus.Fatalf(username, "") // $ hasTaintFlow="username"
|
logrus.Fatalf(username, "") // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "15" {
|
||||||
logrus.Fatalf("", username) // $ hasTaintFlow="username"
|
logrus.Fatalf("", username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "16" {
|
||||||
logrus.Fatalln(username) // $ hasTaintFlow="username"
|
logrus.Fatalln(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
logrus.Info(username) // $ hasTaintFlow="username"
|
logrus.Info(username) // $ hasTaintFlow="username"
|
||||||
logrus.Infof(username, "") // $ hasTaintFlow="username"
|
logrus.Infof(username, "") // $ hasTaintFlow="username"
|
||||||
logrus.Infof("", username) // $ hasTaintFlow="username"
|
logrus.Infof("", username) // $ hasTaintFlow="username"
|
||||||
logrus.Infoln(username) // $ hasTaintFlow="username"
|
logrus.Infoln(username) // $ hasTaintFlow="username"
|
||||||
|
if testFlag == "17" {
|
||||||
logrus.Panic(username) // $ hasTaintFlow="username"
|
logrus.Panic(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "18" {
|
||||||
logrus.Panicf(username, "") // $ hasTaintFlow="username"
|
logrus.Panicf(username, "") // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "19" {
|
||||||
logrus.Panicf("", username) // $ hasTaintFlow="username"
|
logrus.Panicf("", username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "20" {
|
||||||
logrus.Panicln(username) // $ hasTaintFlow="username"
|
logrus.Panicln(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
logrus.Print(username) // $ hasTaintFlow="username"
|
logrus.Print(username) // $ hasTaintFlow="username"
|
||||||
logrus.Printf(username, "") // $ hasTaintFlow="username"
|
logrus.Printf(username, "") // $ hasTaintFlow="username"
|
||||||
logrus.Printf("", username) // $ hasTaintFlow="username"
|
logrus.Printf("", username) // $ hasTaintFlow="username"
|
||||||
@@ -228,10 +284,18 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
entry.Errorf(username, "") // $ hasTaintFlow="username"
|
entry.Errorf(username, "") // $ hasTaintFlow="username"
|
||||||
entry.Errorf("", username) // $ hasTaintFlow="username"
|
entry.Errorf("", username) // $ hasTaintFlow="username"
|
||||||
entry.Errorln(username) // $ hasTaintFlow="username"
|
entry.Errorln(username) // $ hasTaintFlow="username"
|
||||||
|
if testFlag == "21" {
|
||||||
entry.Fatal(username) // $ hasTaintFlow="username"
|
entry.Fatal(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "22" {
|
||||||
entry.Fatalf(username, "") // $ hasTaintFlow="username"
|
entry.Fatalf(username, "") // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "23" {
|
||||||
entry.Fatalf("", username) // $ hasTaintFlow="username"
|
entry.Fatalf("", username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "24" {
|
||||||
entry.Fatalln(username) // $ hasTaintFlow="username"
|
entry.Fatalln(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
entry.Info(username) // $ hasTaintFlow="username"
|
entry.Info(username) // $ hasTaintFlow="username"
|
||||||
entry.Infof(username, "") // $ hasTaintFlow="username"
|
entry.Infof(username, "") // $ hasTaintFlow="username"
|
||||||
entry.Infof("", username) // $ hasTaintFlow="username"
|
entry.Infof("", username) // $ hasTaintFlow="username"
|
||||||
@@ -240,10 +304,18 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
entry.Logf(0, username, "") // $ hasTaintFlow="username"
|
entry.Logf(0, username, "") // $ hasTaintFlow="username"
|
||||||
entry.Logf(0, "", username) // $ hasTaintFlow="username"
|
entry.Logf(0, "", username) // $ hasTaintFlow="username"
|
||||||
entry.Logln(0, username) // $ hasTaintFlow="username"
|
entry.Logln(0, username) // $ hasTaintFlow="username"
|
||||||
|
if testFlag == "25" {
|
||||||
entry.Panic(username) // $ hasTaintFlow="username"
|
entry.Panic(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "26" {
|
||||||
entry.Panicf(username, "") // $ hasTaintFlow="username"
|
entry.Panicf(username, "") // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "27" {
|
||||||
entry.Panicf("", username) // $ hasTaintFlow="username"
|
entry.Panicf("", username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "28" {
|
||||||
entry.Panicln(username) // $ hasTaintFlow="username"
|
entry.Panicln(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
entry.Print(username) // $ hasTaintFlow="username"
|
entry.Print(username) // $ hasTaintFlow="username"
|
||||||
entry.Printf(username, "") // $ hasTaintFlow="username"
|
entry.Printf(username, "") // $ hasTaintFlow="username"
|
||||||
entry.Printf("", username) // $ hasTaintFlow="username"
|
entry.Printf("", username) // $ hasTaintFlow="username"
|
||||||
@@ -273,10 +345,18 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
logger.Errorf(username, "") // $ hasTaintFlow="username"
|
logger.Errorf(username, "") // $ hasTaintFlow="username"
|
||||||
logger.Errorf("", username) // $ hasTaintFlow="username"
|
logger.Errorf("", username) // $ hasTaintFlow="username"
|
||||||
logger.Errorln(username) // $ hasTaintFlow="username"
|
logger.Errorln(username) // $ hasTaintFlow="username"
|
||||||
|
if testFlag == "29" {
|
||||||
logger.Fatal(username) // $ hasTaintFlow="username"
|
logger.Fatal(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "30" {
|
||||||
logger.Fatalf(username, "") // $ hasTaintFlow="username"
|
logger.Fatalf(username, "") // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "31" {
|
||||||
logger.Fatalf("", username) // $ hasTaintFlow="username"
|
logger.Fatalf("", username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "32" {
|
||||||
logger.Fatalln(username) // $ hasTaintFlow="username"
|
logger.Fatalln(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
logger.Info(username) // $ hasTaintFlow="username"
|
logger.Info(username) // $ hasTaintFlow="username"
|
||||||
logger.Infof(username, "") // $ hasTaintFlow="username"
|
logger.Infof(username, "") // $ hasTaintFlow="username"
|
||||||
logger.Infof("", username) // $ hasTaintFlow="username"
|
logger.Infof("", username) // $ hasTaintFlow="username"
|
||||||
@@ -285,10 +365,18 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
logger.Logf(0, username, "") // $ hasTaintFlow="username"
|
logger.Logf(0, username, "") // $ hasTaintFlow="username"
|
||||||
logger.Logf(0, "", username) // $ hasTaintFlow="username"
|
logger.Logf(0, "", username) // $ hasTaintFlow="username"
|
||||||
logger.Logln(0, username) // $ hasTaintFlow="username"
|
logger.Logln(0, username) // $ hasTaintFlow="username"
|
||||||
|
if testFlag == "33" {
|
||||||
logger.Panic(username) // $ hasTaintFlow="username"
|
logger.Panic(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "34" {
|
||||||
logger.Panicf(username, "") // $ hasTaintFlow="username"
|
logger.Panicf(username, "") // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "35" {
|
||||||
logger.Panicf("", username) // $ hasTaintFlow="username"
|
logger.Panicf("", username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "36" {
|
||||||
logger.Panicln(username) // $ hasTaintFlow="username"
|
logger.Panicln(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
logger.Print(username) // $ hasTaintFlow="username"
|
logger.Print(username) // $ hasTaintFlow="username"
|
||||||
logger.Printf(username, "") // $ hasTaintFlow="username"
|
logger.Printf(username, "") // $ hasTaintFlow="username"
|
||||||
logger.Printf("", username) // $ hasTaintFlow="username"
|
logger.Printf("", username) // $ hasTaintFlow="username"
|
||||||
@@ -319,18 +407,34 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
fieldlogger.Errorf(username, "") // $ hasTaintFlow="username"
|
fieldlogger.Errorf(username, "") // $ hasTaintFlow="username"
|
||||||
fieldlogger.Errorf("", username) // $ hasTaintFlow="username"
|
fieldlogger.Errorf("", username) // $ hasTaintFlow="username"
|
||||||
fieldlogger.Errorln(username) // $ hasTaintFlow="username"
|
fieldlogger.Errorln(username) // $ hasTaintFlow="username"
|
||||||
|
if testFlag == "37" {
|
||||||
fieldlogger.Fatal(username) // $ hasTaintFlow="username"
|
fieldlogger.Fatal(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "38" {
|
||||||
fieldlogger.Fatalf(username, "") // $ hasTaintFlow="username"
|
fieldlogger.Fatalf(username, "") // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "39" {
|
||||||
fieldlogger.Fatalf("", username) // $ hasTaintFlow="username"
|
fieldlogger.Fatalf("", username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "40" {
|
||||||
fieldlogger.Fatalln(username) // $ hasTaintFlow="username"
|
fieldlogger.Fatalln(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
fieldlogger.Info(username) // $ hasTaintFlow="username"
|
fieldlogger.Info(username) // $ hasTaintFlow="username"
|
||||||
fieldlogger.Infof(username, "") // $ hasTaintFlow="username"
|
fieldlogger.Infof(username, "") // $ hasTaintFlow="username"
|
||||||
fieldlogger.Infof("", username) // $ hasTaintFlow="username"
|
fieldlogger.Infof("", username) // $ hasTaintFlow="username"
|
||||||
fieldlogger.Infoln(username) // $ hasTaintFlow="username"
|
fieldlogger.Infoln(username) // $ hasTaintFlow="username"
|
||||||
|
if testFlag == "41" {
|
||||||
fieldlogger.Panic(username) // $ hasTaintFlow="username"
|
fieldlogger.Panic(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "42" {
|
||||||
fieldlogger.Panicf(username, "") // $ hasTaintFlow="username"
|
fieldlogger.Panicf(username, "") // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "43" {
|
||||||
fieldlogger.Panicf("", username) // $ hasTaintFlow="username"
|
fieldlogger.Panicf("", username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
|
if testFlag == "44" {
|
||||||
fieldlogger.Panicln(username) // $ hasTaintFlow="username"
|
fieldlogger.Panicln(username) // $ hasTaintFlow="username"
|
||||||
|
}
|
||||||
fieldlogger.Print(username) // $ hasTaintFlow="username"
|
fieldlogger.Print(username) // $ hasTaintFlow="username"
|
||||||
fieldlogger.Printf(username, "") // $ hasTaintFlow="username"
|
fieldlogger.Printf(username, "") // $ hasTaintFlow="username"
|
||||||
fieldlogger.Printf("", username) // $ hasTaintFlow="username"
|
fieldlogger.Printf("", username) // $ hasTaintFlow="username"
|
||||||
@@ -366,11 +470,11 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
logger.DPanic(username) // $ hasTaintFlow="username"
|
logger.DPanic(username) // $ hasTaintFlow="username"
|
||||||
logger.Debug(username) // $ hasTaintFlow="username"
|
logger.Debug(username) // $ hasTaintFlow="username"
|
||||||
logger.Error(username) // $ hasTaintFlow="username"
|
logger.Error(username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "45" {
|
||||||
logger.Fatal(username) // $ hasTaintFlow="username"
|
logger.Fatal(username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
logger.Info(username) // $ hasTaintFlow="username"
|
logger.Info(username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "46" {
|
||||||
logger.Panic(username) // $ hasTaintFlow="username"
|
logger.Panic(username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
logger.Warn(username) // $ hasTaintFlow="username"
|
logger.Warn(username) // $ hasTaintFlow="username"
|
||||||
@@ -382,33 +486,33 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
sLogger.DPanic(username) // $ hasTaintFlow="username"
|
sLogger.DPanic(username) // $ hasTaintFlow="username"
|
||||||
sLogger.Debug(username) // $ hasTaintFlow="username"
|
sLogger.Debug(username) // $ hasTaintFlow="username"
|
||||||
sLogger.Error(username) // $ hasTaintFlow="username"
|
sLogger.Error(username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "47" {
|
||||||
sLogger.Fatal(username) // $ hasTaintFlow="username"
|
sLogger.Fatal(username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
sLogger.Info(username) // $ hasTaintFlow="username"
|
sLogger.Info(username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "48" {
|
||||||
sLogger.Panic(username) // $ hasTaintFlow="username"
|
sLogger.Panic(username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
sLogger.Warn(username) // $ hasTaintFlow="username"
|
sLogger.Warn(username) // $ hasTaintFlow="username"
|
||||||
sLogger.DPanicf(username) // $ hasTaintFlow="username"
|
sLogger.DPanicf(username) // $ hasTaintFlow="username"
|
||||||
sLogger.Debugf(username) // $ hasTaintFlow="username"
|
sLogger.Debugf(username) // $ hasTaintFlow="username"
|
||||||
sLogger.Errorf(username) // $ hasTaintFlow="username"
|
sLogger.Errorf(username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "49" {
|
||||||
sLogger.Fatalf(username) // $ hasTaintFlow="username"
|
sLogger.Fatalf(username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
sLogger.Infof(username) // $ hasTaintFlow="username"
|
sLogger.Infof(username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "50" {
|
||||||
sLogger.Panicf(username) // $ hasTaintFlow="username"
|
sLogger.Panicf(username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
sLogger.Warnf(username) // $ hasTaintFlow="username"
|
sLogger.Warnf(username) // $ hasTaintFlow="username"
|
||||||
sLogger.DPanicw(username) // $ hasTaintFlow="username"
|
sLogger.DPanicw(username) // $ hasTaintFlow="username"
|
||||||
sLogger.Debugw(username) // $ hasTaintFlow="username"
|
sLogger.Debugw(username) // $ hasTaintFlow="username"
|
||||||
sLogger.Errorw(username) // $ hasTaintFlow="username"
|
sLogger.Errorw(username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "51" {
|
||||||
sLogger.Fatalw(username) // $ hasTaintFlow="username"
|
sLogger.Fatalw(username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
sLogger.Infow(username) // $ hasTaintFlow="username"
|
sLogger.Infow(username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "52" {
|
||||||
sLogger.Panicw(username) // $ hasTaintFlow="username"
|
sLogger.Panicw(username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
sLogger.Warnw(username) // $ hasTaintFlow="username"
|
sLogger.Warnw(username) // $ hasTaintFlow="username"
|
||||||
@@ -515,10 +619,10 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
verbose.Infof("user %q logged in.\n", username)
|
verbose.Infof("user %q logged in.\n", username)
|
||||||
klog.Infof("user %q logged in.\n", username)
|
klog.Infof("user %q logged in.\n", username)
|
||||||
klog.Errorf("user %q logged in.\n", username)
|
klog.Errorf("user %q logged in.\n", username)
|
||||||
if testFlag == " true" {
|
if testFlag == "53" {
|
||||||
klog.Fatalf("user %q logged in.\n", username)
|
klog.Fatalf("user %q logged in.\n", username)
|
||||||
}
|
}
|
||||||
if testFlag == " true" {
|
if testFlag == "54" {
|
||||||
klog.Exitf("user %q logged in.\n", username)
|
klog.Exitf("user %q logged in.\n", username)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -534,10 +638,10 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
|
|
||||||
glog.Infof("user %q logged in.\n", username)
|
glog.Infof("user %q logged in.\n", username)
|
||||||
glog.Errorf("user %q logged in.\n", username)
|
glog.Errorf("user %q logged in.\n", username)
|
||||||
if testFlag == " true" {
|
if testFlag == "55" {
|
||||||
glog.Fatalf("user %q logged in.\n", username)
|
glog.Fatalf("user %q logged in.\n", username)
|
||||||
}
|
}
|
||||||
if testFlag == " true" {
|
if testFlag == "56" {
|
||||||
glog.Exitf("user %q logged in.\n", username)
|
glog.Exitf("user %q logged in.\n", username)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -545,11 +649,11 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
{
|
{
|
||||||
logrus.Debugf("user %q logged in.\n", username)
|
logrus.Debugf("user %q logged in.\n", username)
|
||||||
logrus.Errorf("user %q logged in.\n", username)
|
logrus.Errorf("user %q logged in.\n", username)
|
||||||
if testFlag == " true" {
|
if testFlag == "57" {
|
||||||
logrus.Fatalf("user %q logged in.\n", username)
|
logrus.Fatalf("user %q logged in.\n", username)
|
||||||
}
|
}
|
||||||
logrus.Infof("user %q logged in.\n", username)
|
logrus.Infof("user %q logged in.\n", username)
|
||||||
if testFlag == " true" {
|
if testFlag == "58" {
|
||||||
logrus.Panicf("user %q logged in.\n", username)
|
logrus.Panicf("user %q logged in.\n", username)
|
||||||
}
|
}
|
||||||
logrus.Printf("user %q logged in.\n", username)
|
logrus.Printf("user %q logged in.\n", username)
|
||||||
@@ -561,12 +665,12 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
entry := logrus.WithFields(fields)
|
entry := logrus.WithFields(fields)
|
||||||
entry.Debugf("user %q logged in.\n", username)
|
entry.Debugf("user %q logged in.\n", username)
|
||||||
entry.Errorf("user %q logged in.\n", username)
|
entry.Errorf("user %q logged in.\n", username)
|
||||||
if testFlag == " true" {
|
if testFlag == "59" {
|
||||||
entry.Fatalf("user %q logged in.\n", username)
|
entry.Fatalf("user %q logged in.\n", username)
|
||||||
}
|
}
|
||||||
entry.Infof("user %q logged in.\n", username)
|
entry.Infof("user %q logged in.\n", username)
|
||||||
entry.Logf(0, "user %q logged in.\n", username)
|
entry.Logf(0, "user %q logged in.\n", username)
|
||||||
if testFlag == " true" {
|
if testFlag == "60" {
|
||||||
entry.Panicf("user %q logged in.\n", username)
|
entry.Panicf("user %q logged in.\n", username)
|
||||||
}
|
}
|
||||||
entry.Printf("user %q logged in.\n", username)
|
entry.Printf("user %q logged in.\n", username)
|
||||||
@@ -577,12 +681,12 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
logger := entry.Logger
|
logger := entry.Logger
|
||||||
logger.Debugf("user %q logged in.\n", username)
|
logger.Debugf("user %q logged in.\n", username)
|
||||||
logger.Errorf("user %q logged in.\n", username)
|
logger.Errorf("user %q logged in.\n", username)
|
||||||
if testFlag == " true" {
|
if testFlag == "61" {
|
||||||
logger.Fatalf("user %q logged in.\n", username)
|
logger.Fatalf("user %q logged in.\n", username)
|
||||||
}
|
}
|
||||||
logger.Infof("user %q logged in.\n", username)
|
logger.Infof("user %q logged in.\n", username)
|
||||||
logger.Logf(0, "user %q logged in.\n", username)
|
logger.Logf(0, "user %q logged in.\n", username)
|
||||||
if testFlag == " true" {
|
if testFlag == "62" {
|
||||||
logger.Panicf("user %q logged in.\n", username)
|
logger.Panicf("user %q logged in.\n", username)
|
||||||
}
|
}
|
||||||
logger.Printf("user %q logged in.\n", username)
|
logger.Printf("user %q logged in.\n", username)
|
||||||
@@ -603,11 +707,11 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
sLogger.DPanicf("user %q logged in.\n", username)
|
sLogger.DPanicf("user %q logged in.\n", username)
|
||||||
sLogger.Debugf("user %q logged in.\n", username)
|
sLogger.Debugf("user %q logged in.\n", username)
|
||||||
sLogger.Errorf("user %q logged in.\n", username)
|
sLogger.Errorf("user %q logged in.\n", username)
|
||||||
if testFlag == " true" {
|
if testFlag == "63" {
|
||||||
sLogger.Fatalf("user %q logged in.\n", username)
|
sLogger.Fatalf("user %q logged in.\n", username)
|
||||||
}
|
}
|
||||||
sLogger.Infof("user %q logged in.\n", username)
|
sLogger.Infof("user %q logged in.\n", username)
|
||||||
if testFlag == " true" {
|
if testFlag == "64" {
|
||||||
sLogger.Panicf("user %q logged in.\n", username)
|
sLogger.Panicf("user %q logged in.\n", username)
|
||||||
}
|
}
|
||||||
sLogger.Warnf("user %q logged in.\n", username)
|
sLogger.Warnf("user %q logged in.\n", username)
|
||||||
@@ -620,10 +724,10 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
verbose.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
verbose.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
klog.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
klog.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
klog.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
klog.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "65" {
|
||||||
klog.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
klog.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
if testFlag == " true" {
|
if testFlag == "66" {
|
||||||
klog.Exitf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
klog.Exitf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -639,10 +743,10 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
|
|
||||||
glog.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
glog.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
glog.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
glog.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "67" {
|
||||||
glog.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
glog.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
if testFlag == " true" {
|
if testFlag == "68" {
|
||||||
glog.Exitf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
glog.Exitf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -650,11 +754,11 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
{
|
{
|
||||||
logrus.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
logrus.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
logrus.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
logrus.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "69" {
|
||||||
logrus.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
logrus.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
logrus.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
logrus.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "70" {
|
||||||
logrus.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
logrus.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
logrus.Printf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
logrus.Printf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
@@ -666,12 +770,12 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
entry := logrus.WithFields(fields)
|
entry := logrus.WithFields(fields)
|
||||||
entry.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
entry.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
entry.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
entry.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "71" {
|
||||||
entry.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
entry.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
entry.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
entry.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
entry.Logf(0, "user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
entry.Logf(0, "user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "72" {
|
||||||
entry.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
entry.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
entry.Printf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
entry.Printf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
@@ -682,12 +786,12 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
logger := entry.Logger
|
logger := entry.Logger
|
||||||
logger.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
logger.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
logger.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
logger.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "73" {
|
||||||
logger.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
logger.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
logger.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
logger.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
logger.Logf(0, "user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
logger.Logf(0, "user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "74" {
|
||||||
logger.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
logger.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
logger.Printf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
logger.Printf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
@@ -708,11 +812,11 @@ func handlerGood4(req *http.Request, ctx *goproxy.ProxyCtx) {
|
|||||||
sLogger.DPanicf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
sLogger.DPanicf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
sLogger.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
sLogger.Debugf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
sLogger.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
sLogger.Errorf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "75" {
|
||||||
sLogger.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
sLogger.Fatalf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
sLogger.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
sLogger.Infof("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
if testFlag == " true" {
|
if testFlag == "76" {
|
||||||
sLogger.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
sLogger.Panicf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
}
|
}
|
||||||
sLogger.Warnf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
sLogger.Warnf("user %#q logged in.\n", username) // $ hasTaintFlow="username"
|
||||||
|
|||||||
@@ -37,22 +37,22 @@
|
|||||||
| passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | $@ flows to a logging call. | passwords.go:26:14:26:23 | selection of password | Sensitive data returned by an access to password |
|
| passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | $@ flows to a logging call. | passwords.go:26:14:26:23 | selection of password | Sensitive data returned by an access to password |
|
||||||
| passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | $@ flows to a logging call. | passwords.go:27:14:27:26 | call to getPassword | Sensitive data returned by a call to getPassword |
|
| passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | $@ flows to a logging call. | passwords.go:27:14:27:26 | call to getPassword | Sensitive data returned by a call to getPassword |
|
||||||
| passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | $@ flows to a logging call. | passwords.go:28:14:28:28 | call to getPassword | Sensitive data returned by a call to getPassword |
|
| passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | $@ flows to a logging call. | passwords.go:28:14:28:28 | call to getPassword | Sensitive data returned by a call to getPassword |
|
||||||
| passwords.go:32:12:32:19 | password | passwords.go:21:2:21:9 | definition of password | passwords.go:32:12:32:19 | password | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
| passwords.go:33:13:33:20 | password | passwords.go:21:2:21:9 | definition of password | passwords.go:33:13:33:20 | password | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
||||||
| passwords.go:34:14:34:35 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:34:14:34:35 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
| passwords.go:36:14:36:35 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:36:14:36:35 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
||||||
| passwords.go:39:14:39:17 | obj1 | passwords.go:37:13:37:13 | x | passwords.go:39:14:39:17 | obj1 | $@ flows to a logging call. | passwords.go:37:13:37:13 | x | Sensitive data returned by an access to password |
|
| passwords.go:41:14:41:17 | obj1 | passwords.go:39:13:39:13 | x | passwords.go:41:14:41:17 | obj1 | $@ flows to a logging call. | passwords.go:39:13:39:13 | x | Sensitive data returned by an access to password |
|
||||||
| passwords.go:44:14:44:17 | obj2 | passwords.go:21:2:21:9 | definition of password | passwords.go:44:14:44:17 | obj2 | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
| passwords.go:46:14:46:17 | obj2 | passwords.go:21:2:21:9 | definition of password | passwords.go:46:14:46:17 | obj2 | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
||||||
| passwords.go:51:14:51:27 | fixed_password | passwords.go:50:2:50:15 | definition of fixed_password | passwords.go:51:14:51:27 | fixed_password | $@ flows to a logging call. | passwords.go:50:2:50:15 | definition of fixed_password | Sensitive data returned by an access to fixed_password |
|
| passwords.go:53:14:53:27 | fixed_password | passwords.go:52:2:52:15 | definition of fixed_password | passwords.go:53:14:53:27 | fixed_password | $@ flows to a logging call. | passwords.go:52:2:52:15 | definition of fixed_password | Sensitive data returned by an access to fixed_password |
|
||||||
| passwords.go:89:14:89:26 | utilityObject | passwords.go:87:16:87:36 | call to make | passwords.go:89:14:89:26 | utilityObject | $@ flows to a logging call. | passwords.go:87:16:87:36 | call to make | Sensitive data returned by an access to passwordSet |
|
| passwords.go:91:14:91:26 | utilityObject | passwords.go:89:16:89:36 | call to make | passwords.go:91:14:91:26 | utilityObject | $@ flows to a logging call. | passwords.go:89:16:89:36 | call to make | Sensitive data returned by an access to passwordSet |
|
||||||
| passwords.go:92:23:92:28 | secret | passwords.go:21:2:21:9 | definition of password | passwords.go:92:23:92:28 | secret | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
| passwords.go:94:23:94:28 | secret | passwords.go:21:2:21:9 | definition of password | passwords.go:94:23:94:28 | secret | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
||||||
| passwords.go:102:15:102:40 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:102:15:102:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
| passwords.go:104:15:104:40 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:104:15:104:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
||||||
| passwords.go:108:16:108:41 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:108:16:108:41 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
| passwords.go:110:16:110:41 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:110:16:110:41 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
||||||
| passwords.go:113:15:113:40 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:113:15:113:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
| passwords.go:115:15:115:40 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:115:15:115:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
||||||
| passwords.go:117:14:117:45 | ...+... | passwords.go:116:6:116:14 | definition of password1 | passwords.go:117:14:117:45 | ...+... | $@ flows to a logging call. | passwords.go:116:6:116:14 | definition of password1 | Sensitive data returned by an access to password1 |
|
| passwords.go:119:14:119:45 | ...+... | passwords.go:118:6:118:14 | definition of password1 | passwords.go:119:14:119:45 | ...+... | $@ flows to a logging call. | passwords.go:118:6:118:14 | definition of password1 | Sensitive data returned by an access to password1 |
|
||||||
| passwords.go:127:14:127:19 | config | passwords.go:21:2:21:9 | definition of password | passwords.go:127:14:127:19 | config | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
| passwords.go:129:14:129:19 | config | passwords.go:21:2:21:9 | definition of password | passwords.go:129:14:129:19 | config | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
||||||
| passwords.go:127:14:127:19 | config | passwords.go:121:13:121:14 | x3 | passwords.go:127:14:127:19 | config | $@ flows to a logging call. | passwords.go:121:13:121:14 | x3 | Sensitive data returned by an access to password |
|
| passwords.go:129:14:129:19 | config | passwords.go:123:13:123:14 | x3 | passwords.go:129:14:129:19 | config | $@ flows to a logging call. | passwords.go:123:13:123:14 | x3 | Sensitive data returned by an access to password |
|
||||||
| passwords.go:127:14:127:19 | config | passwords.go:124:13:124:25 | call to getPassword | passwords.go:127:14:127:19 | config | $@ flows to a logging call. | passwords.go:124:13:124:25 | call to getPassword | Sensitive data returned by a call to getPassword |
|
| passwords.go:129:14:129:19 | config | passwords.go:126:13:126:25 | call to getPassword | passwords.go:129:14:129:19 | config | $@ flows to a logging call. | passwords.go:126:13:126:25 | call to getPassword | Sensitive data returned by a call to getPassword |
|
||||||
| passwords.go:128:14:128:21 | selection of x | passwords.go:21:2:21:9 | definition of password | passwords.go:128:14:128:21 | selection of x | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
| passwords.go:130:14:130:21 | selection of x | passwords.go:21:2:21:9 | definition of password | passwords.go:130:14:130:21 | selection of x | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
|
||||||
| passwords.go:129:14:129:21 | selection of y | passwords.go:124:13:124:25 | call to getPassword | passwords.go:129:14:129:21 | selection of y | $@ flows to a logging call. | passwords.go:124:13:124:25 | call to getPassword | Sensitive data returned by a call to getPassword |
|
| passwords.go:131:14:131:21 | selection of y | passwords.go:126:13:126:25 | call to getPassword | passwords.go:131:14:131:21 | selection of y | $@ flows to a logging call. | passwords.go:126:13:126:25 | call to getPassword | Sensitive data returned by a call to getPassword |
|
||||||
| protobuf.go:14:14:14:35 | call to GetDescription | protobuf.go:9:2:9:9 | definition of password | protobuf.go:14:14:14:35 | call to GetDescription | $@ flows to a logging call. | protobuf.go:9:2:9:9 | definition of password | Sensitive data returned by an access to password |
|
| protobuf.go:14:14:14:35 | call to GetDescription | protobuf.go:9:2:9:9 | definition of password | protobuf.go:14:14:14:35 | call to GetDescription | $@ flows to a logging call. | protobuf.go:9:2:9:9 | definition of password | Sensitive data returned by an access to password |
|
||||||
edges
|
edges
|
||||||
| klog.go:21:3:26:3 | range statement[1] | klog.go:22:27:22:33 | headers | provenance | |
|
| klog.go:21:3:26:3 | range statement[1] | klog.go:22:27:22:33 | headers | provenance | |
|
||||||
@@ -82,95 +82,15 @@ edges
|
|||||||
| main.go:53:11:53:18 | password | main.go:54:12:54:19 | password | provenance | |
|
| main.go:53:11:53:18 | password | main.go:54:12:54:19 | password | provenance | |
|
||||||
| main.go:53:11:53:18 | password | main.go:54:12:54:19 | password | provenance | |
|
| main.go:53:11:53:18 | password | main.go:54:12:54:19 | password | provenance | |
|
||||||
| main.go:54:12:54:19 | password | main.go:56:11:56:18 | password | provenance | |
|
| main.go:54:12:54:19 | password | main.go:56:11:56:18 | password | provenance | |
|
||||||
| main.go:54:12:54:19 | password | main.go:56:11:56:18 | password | provenance | |
|
|
||||||
| main.go:54:12:54:19 | password | main.go:59:18:59:25 | password | provenance | |
|
| main.go:54:12:54:19 | password | main.go:59:18:59:25 | password | provenance | |
|
||||||
| main.go:54:12:54:19 | password | main.go:59:18:59:25 | password | provenance | |
|
|
||||||
| main.go:54:12:54:19 | password | main.go:62:12:62:19 | password | provenance | |
|
|
||||||
| main.go:54:12:54:19 | password | main.go:62:12:62:19 | password | provenance | Sink:MaD:7 |
|
| main.go:54:12:54:19 | password | main.go:62:12:62:19 | password | provenance | Sink:MaD:7 |
|
||||||
| main.go:54:12:54:19 | password | main.go:65:13:65:20 | password | provenance | |
|
| main.go:54:12:54:19 | password | main.go:65:13:65:20 | password | provenance | |
|
||||||
| main.go:54:12:54:19 | password | main.go:65:13:65:20 | password | provenance | |
|
|
||||||
| main.go:54:12:54:19 | password | main.go:68:11:68:18 | password | provenance | |
|
|
||||||
| main.go:54:12:54:19 | password | main.go:68:11:68:18 | password | provenance | |
|
| main.go:54:12:54:19 | password | main.go:68:11:68:18 | password | provenance | |
|
||||||
| main.go:54:12:54:19 | password | main.go:71:18:71:25 | password | provenance | |
|
| main.go:54:12:54:19 | password | main.go:71:18:71:25 | password | provenance | |
|
||||||
| main.go:54:12:54:19 | password | main.go:71:18:71:25 | password | provenance | |
|
|
||||||
| main.go:54:12:54:19 | password | main.go:74:12:74:19 | password | provenance | |
|
|
||||||
| main.go:54:12:54:19 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 |
|
| main.go:54:12:54:19 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 |
|
||||||
| main.go:54:12:54:19 | password | main.go:77:13:77:20 | password | provenance | |
|
| main.go:54:12:54:19 | password | main.go:77:13:77:20 | password | provenance | |
|
||||||
| main.go:54:12:54:19 | password | main.go:77:13:77:20 | password | provenance | |
|
|
||||||
| main.go:54:12:54:19 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 |
|
| main.go:54:12:54:19 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 |
|
||||||
| main.go:54:12:54:19 | password | main.go:80:17:80:24 | password | provenance | |
|
| main.go:54:12:54:19 | password | main.go:80:17:80:24 | password | provenance | |
|
||||||
| main.go:56:11:56:18 | password | main.go:59:18:59:25 | password | provenance | |
|
|
||||||
| main.go:56:11:56:18 | password | main.go:59:18:59:25 | password | provenance | |
|
|
||||||
| main.go:56:11:56:18 | password | main.go:62:12:62:19 | password | provenance | |
|
|
||||||
| main.go:56:11:56:18 | password | main.go:62:12:62:19 | password | provenance | Sink:MaD:7 |
|
|
||||||
| main.go:56:11:56:18 | password | main.go:65:13:65:20 | password | provenance | |
|
|
||||||
| main.go:56:11:56:18 | password | main.go:65:13:65:20 | password | provenance | |
|
|
||||||
| main.go:56:11:56:18 | password | main.go:68:11:68:18 | password | provenance | |
|
|
||||||
| main.go:56:11:56:18 | password | main.go:68:11:68:18 | password | provenance | |
|
|
||||||
| main.go:56:11:56:18 | password | main.go:71:18:71:25 | password | provenance | |
|
|
||||||
| main.go:56:11:56:18 | password | main.go:71:18:71:25 | password | provenance | |
|
|
||||||
| main.go:56:11:56:18 | password | main.go:74:12:74:19 | password | provenance | |
|
|
||||||
| main.go:56:11:56:18 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 |
|
|
||||||
| main.go:56:11:56:18 | password | main.go:77:13:77:20 | password | provenance | |
|
|
||||||
| main.go:56:11:56:18 | password | main.go:77:13:77:20 | password | provenance | |
|
|
||||||
| main.go:56:11:56:18 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 |
|
|
||||||
| main.go:56:11:56:18 | password | main.go:80:17:80:24 | password | provenance | |
|
|
||||||
| main.go:59:18:59:25 | password | main.go:62:12:62:19 | password | provenance | |
|
|
||||||
| main.go:59:18:59:25 | password | main.go:62:12:62:19 | password | provenance | Sink:MaD:7 |
|
|
||||||
| main.go:59:18:59:25 | password | main.go:65:13:65:20 | password | provenance | |
|
|
||||||
| main.go:59:18:59:25 | password | main.go:65:13:65:20 | password | provenance | |
|
|
||||||
| main.go:59:18:59:25 | password | main.go:68:11:68:18 | password | provenance | |
|
|
||||||
| main.go:59:18:59:25 | password | main.go:68:11:68:18 | password | provenance | |
|
|
||||||
| main.go:59:18:59:25 | password | main.go:71:18:71:25 | password | provenance | |
|
|
||||||
| main.go:59:18:59:25 | password | main.go:71:18:71:25 | password | provenance | |
|
|
||||||
| main.go:59:18:59:25 | password | main.go:74:12:74:19 | password | provenance | |
|
|
||||||
| main.go:59:18:59:25 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 |
|
|
||||||
| main.go:59:18:59:25 | password | main.go:77:13:77:20 | password | provenance | |
|
|
||||||
| main.go:59:18:59:25 | password | main.go:77:13:77:20 | password | provenance | |
|
|
||||||
| main.go:59:18:59:25 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 |
|
|
||||||
| main.go:59:18:59:25 | password | main.go:80:17:80:24 | password | provenance | |
|
|
||||||
| main.go:62:12:62:19 | password | main.go:65:13:65:20 | password | provenance | |
|
|
||||||
| main.go:62:12:62:19 | password | main.go:65:13:65:20 | password | provenance | |
|
|
||||||
| main.go:62:12:62:19 | password | main.go:68:11:68:18 | password | provenance | |
|
|
||||||
| main.go:62:12:62:19 | password | main.go:68:11:68:18 | password | provenance | |
|
|
||||||
| main.go:62:12:62:19 | password | main.go:71:18:71:25 | password | provenance | |
|
|
||||||
| main.go:62:12:62:19 | password | main.go:71:18:71:25 | password | provenance | |
|
|
||||||
| main.go:62:12:62:19 | password | main.go:74:12:74:19 | password | provenance | |
|
|
||||||
| main.go:62:12:62:19 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 |
|
|
||||||
| main.go:62:12:62:19 | password | main.go:77:13:77:20 | password | provenance | |
|
|
||||||
| main.go:62:12:62:19 | password | main.go:77:13:77:20 | password | provenance | |
|
|
||||||
| main.go:62:12:62:19 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 |
|
|
||||||
| main.go:62:12:62:19 | password | main.go:80:17:80:24 | password | provenance | |
|
|
||||||
| main.go:65:13:65:20 | password | main.go:68:11:68:18 | password | provenance | |
|
|
||||||
| main.go:65:13:65:20 | password | main.go:68:11:68:18 | password | provenance | |
|
|
||||||
| main.go:65:13:65:20 | password | main.go:71:18:71:25 | password | provenance | |
|
|
||||||
| main.go:65:13:65:20 | password | main.go:71:18:71:25 | password | provenance | |
|
|
||||||
| main.go:65:13:65:20 | password | main.go:74:12:74:19 | password | provenance | |
|
|
||||||
| main.go:65:13:65:20 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 |
|
|
||||||
| main.go:65:13:65:20 | password | main.go:77:13:77:20 | password | provenance | |
|
|
||||||
| main.go:65:13:65:20 | password | main.go:77:13:77:20 | password | provenance | |
|
|
||||||
| main.go:65:13:65:20 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 |
|
|
||||||
| main.go:65:13:65:20 | password | main.go:80:17:80:24 | password | provenance | |
|
|
||||||
| main.go:68:11:68:18 | password | main.go:71:18:71:25 | password | provenance | |
|
|
||||||
| main.go:68:11:68:18 | password | main.go:71:18:71:25 | password | provenance | |
|
|
||||||
| main.go:68:11:68:18 | password | main.go:74:12:74:19 | password | provenance | |
|
|
||||||
| main.go:68:11:68:18 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 |
|
|
||||||
| main.go:68:11:68:18 | password | main.go:77:13:77:20 | password | provenance | |
|
|
||||||
| main.go:68:11:68:18 | password | main.go:77:13:77:20 | password | provenance | |
|
|
||||||
| main.go:68:11:68:18 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 |
|
|
||||||
| main.go:68:11:68:18 | password | main.go:80:17:80:24 | password | provenance | |
|
|
||||||
| main.go:71:18:71:25 | password | main.go:74:12:74:19 | password | provenance | |
|
|
||||||
| main.go:71:18:71:25 | password | main.go:74:12:74:19 | password | provenance | Sink:MaD:9 |
|
|
||||||
| main.go:71:18:71:25 | password | main.go:77:13:77:20 | password | provenance | |
|
|
||||||
| main.go:71:18:71:25 | password | main.go:77:13:77:20 | password | provenance | |
|
|
||||||
| main.go:71:18:71:25 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 |
|
|
||||||
| main.go:71:18:71:25 | password | main.go:80:17:80:24 | password | provenance | |
|
|
||||||
| main.go:74:12:74:19 | password | main.go:77:13:77:20 | password | provenance | |
|
|
||||||
| main.go:74:12:74:19 | password | main.go:77:13:77:20 | password | provenance | |
|
|
||||||
| main.go:74:12:74:19 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 |
|
|
||||||
| main.go:74:12:74:19 | password | main.go:80:17:80:24 | password | provenance | |
|
|
||||||
| main.go:77:13:77:20 | password | main.go:79:14:79:21 | password | provenance | Sink:MaD:8 |
|
|
||||||
| main.go:77:13:77:20 | password | main.go:80:17:80:24 | password | provenance | |
|
|
||||||
| main.go:80:17:80:24 | password | main.go:82:12:82:19 | password | provenance | |
|
| main.go:80:17:80:24 | password | main.go:82:12:82:19 | password | provenance | |
|
||||||
| main.go:80:17:80:24 | password | main.go:83:17:83:24 | password | provenance | |
|
| main.go:80:17:80:24 | password | main.go:83:17:83:24 | password | provenance | |
|
||||||
| main.go:80:17:80:24 | password | main.go:86:19:86:26 | password | provenance | |
|
| main.go:80:17:80:24 | password | main.go:86:19:86:26 | password | provenance | |
|
||||||
@@ -182,46 +102,46 @@ edges
|
|||||||
| passwords.go:8:12:8:12 | definition of x | passwords.go:9:14:9:14 | x | provenance | |
|
| passwords.go:8:12:8:12 | definition of x | passwords.go:9:14:9:14 | x | provenance | |
|
||||||
| passwords.go:21:2:21:9 | definition of password | passwords.go:25:14:25:21 | password | provenance | |
|
| passwords.go:21:2:21:9 | definition of password | passwords.go:25:14:25:21 | password | provenance | |
|
||||||
| passwords.go:21:2:21:9 | definition of password | passwords.go:30:8:30:15 | password | provenance | |
|
| passwords.go:21:2:21:9 | definition of password | passwords.go:30:8:30:15 | password | provenance | |
|
||||||
| passwords.go:21:2:21:9 | definition of password | passwords.go:32:12:32:19 | password | provenance | |
|
| passwords.go:21:2:21:9 | definition of password | passwords.go:33:13:33:20 | password | provenance | |
|
||||||
| passwords.go:21:2:21:9 | definition of password | passwords.go:34:28:34:35 | password | provenance | |
|
| passwords.go:21:2:21:9 | definition of password | passwords.go:36:28:36:35 | password | provenance | |
|
||||||
| passwords.go:30:8:30:15 | password | passwords.go:8:12:8:12 | definition of x | provenance | |
|
| passwords.go:30:8:30:15 | password | passwords.go:8:12:8:12 | definition of x | provenance | |
|
||||||
| passwords.go:34:28:34:35 | password | passwords.go:34:14:34:35 | ...+... | provenance | Config |
|
| passwords.go:36:28:36:35 | password | passwords.go:36:14:36:35 | ...+... | provenance | Config |
|
||||||
| passwords.go:34:28:34:35 | password | passwords.go:42:6:42:13 | password | provenance | |
|
| passwords.go:36:28:36:35 | password | passwords.go:44:6:44:13 | password | provenance | |
|
||||||
| passwords.go:36:10:38:2 | struct literal | passwords.go:39:14:39:17 | obj1 | provenance | |
|
| passwords.go:38:10:40:2 | struct literal | passwords.go:41:14:41:17 | obj1 | provenance | |
|
||||||
| passwords.go:37:13:37:13 | x | passwords.go:36:10:38:2 | struct literal | provenance | Config |
|
| passwords.go:39:13:39:13 | x | passwords.go:38:10:40:2 | struct literal | provenance | Config |
|
||||||
| passwords.go:41:10:43:2 | struct literal | passwords.go:44:14:44:17 | obj2 | provenance | |
|
| passwords.go:43:10:45:2 | struct literal | passwords.go:46:14:46:17 | obj2 | provenance | |
|
||||||
| passwords.go:42:6:42:13 | password | passwords.go:41:10:43:2 | struct literal | provenance | Config |
|
| passwords.go:44:6:44:13 | password | passwords.go:43:10:45:2 | struct literal | provenance | Config |
|
||||||
| passwords.go:42:6:42:13 | password | passwords.go:48:11:48:18 | password | provenance | |
|
| passwords.go:44:6:44:13 | password | passwords.go:50:11:50:18 | password | provenance | |
|
||||||
| passwords.go:48:11:48:18 | password | passwords.go:92:23:92:28 | secret | provenance | |
|
| passwords.go:50:11:50:18 | password | passwords.go:94:23:94:28 | secret | provenance | |
|
||||||
| passwords.go:48:11:48:18 | password | passwords.go:102:33:102:40 | password | provenance | |
|
| passwords.go:50:11:50:18 | password | passwords.go:104:33:104:40 | password | provenance | |
|
||||||
| passwords.go:48:11:48:18 | password | passwords.go:108:34:108:41 | password | provenance | |
|
| passwords.go:50:11:50:18 | password | passwords.go:110:34:110:41 | password | provenance | |
|
||||||
| passwords.go:48:11:48:18 | password | passwords.go:113:33:113:40 | password | provenance | |
|
| passwords.go:50:11:50:18 | password | passwords.go:115:33:115:40 | password | provenance | |
|
||||||
| passwords.go:48:11:48:18 | password | passwords.go:123:13:123:20 | password | provenance | |
|
| passwords.go:50:11:50:18 | password | passwords.go:125:13:125:20 | password | provenance | |
|
||||||
| passwords.go:50:2:50:15 | definition of fixed_password | passwords.go:51:14:51:27 | fixed_password | provenance | |
|
| passwords.go:52:2:52:15 | definition of fixed_password | passwords.go:53:14:53:27 | fixed_password | provenance | |
|
||||||
| passwords.go:86:19:88:2 | struct literal | passwords.go:89:14:89:26 | utilityObject | provenance | |
|
| passwords.go:88:19:90:2 | struct literal | passwords.go:91:14:91:26 | utilityObject | provenance | |
|
||||||
| passwords.go:87:16:87:36 | call to make | passwords.go:86:19:88:2 | struct literal | provenance | Config |
|
| passwords.go:89:16:89:36 | call to make | passwords.go:88:19:90:2 | struct literal | provenance | Config |
|
||||||
| passwords.go:102:33:102:40 | password | passwords.go:102:15:102:40 | ...+... | provenance | Config |
|
| passwords.go:104:33:104:40 | password | passwords.go:104:15:104:40 | ...+... | provenance | Config |
|
||||||
| passwords.go:102:33:102:40 | password | passwords.go:108:34:108:41 | password | provenance | |
|
| passwords.go:104:33:104:40 | password | passwords.go:110:34:110:41 | password | provenance | |
|
||||||
| passwords.go:102:33:102:40 | password | passwords.go:113:33:113:40 | password | provenance | |
|
| passwords.go:104:33:104:40 | password | passwords.go:115:33:115:40 | password | provenance | |
|
||||||
| passwords.go:102:33:102:40 | password | passwords.go:123:13:123:20 | password | provenance | |
|
| passwords.go:104:33:104:40 | password | passwords.go:125:13:125:20 | password | provenance | |
|
||||||
| passwords.go:108:34:108:41 | password | passwords.go:108:16:108:41 | ...+... | provenance | Config |
|
| passwords.go:110:34:110:41 | password | passwords.go:110:16:110:41 | ...+... | provenance | Config |
|
||||||
| passwords.go:108:34:108:41 | password | passwords.go:113:33:113:40 | password | provenance | |
|
| passwords.go:110:34:110:41 | password | passwords.go:115:33:115:40 | password | provenance | |
|
||||||
| passwords.go:108:34:108:41 | password | passwords.go:123:13:123:20 | password | provenance | |
|
| passwords.go:110:34:110:41 | password | passwords.go:125:13:125:20 | password | provenance | |
|
||||||
| passwords.go:113:33:113:40 | password | passwords.go:113:15:113:40 | ...+... | provenance | Config |
|
| passwords.go:115:33:115:40 | password | passwords.go:115:15:115:40 | ...+... | provenance | Config |
|
||||||
| passwords.go:113:33:113:40 | password | passwords.go:123:13:123:20 | password | provenance | |
|
| passwords.go:115:33:115:40 | password | passwords.go:125:13:125:20 | password | provenance | |
|
||||||
| passwords.go:116:6:116:14 | definition of password1 | passwords.go:117:28:117:36 | password1 | provenance | |
|
| passwords.go:118:6:118:14 | definition of password1 | passwords.go:119:28:119:36 | password1 | provenance | |
|
||||||
| passwords.go:117:28:117:36 | password1 | passwords.go:117:28:117:45 | call to String | provenance | Config |
|
| passwords.go:119:28:119:36 | password1 | passwords.go:119:28:119:45 | call to String | provenance | Config |
|
||||||
| passwords.go:117:28:117:45 | call to String | passwords.go:117:14:117:45 | ...+... | provenance | Config |
|
| passwords.go:119:28:119:45 | call to String | passwords.go:119:14:119:45 | ...+... | provenance | Config |
|
||||||
| passwords.go:120:12:125:2 | struct literal | passwords.go:127:14:127:19 | config | provenance | |
|
| passwords.go:122:12:127:2 | struct literal | passwords.go:129:14:129:19 | config | provenance | |
|
||||||
| passwords.go:120:12:125:2 | struct literal [x] | passwords.go:128:14:128:19 | config [x] | provenance | |
|
| passwords.go:122:12:127:2 | struct literal [x] | passwords.go:130:14:130:19 | config [x] | provenance | |
|
||||||
| passwords.go:120:12:125:2 | struct literal [y] | passwords.go:129:14:129:19 | config [y] | provenance | |
|
| passwords.go:122:12:127:2 | struct literal [y] | passwords.go:131:14:131:19 | config [y] | provenance | |
|
||||||
| passwords.go:121:13:121:14 | x3 | passwords.go:120:12:125:2 | struct literal | provenance | Config |
|
| passwords.go:123:13:123:14 | x3 | passwords.go:122:12:127:2 | struct literal | provenance | Config |
|
||||||
| passwords.go:123:13:123:20 | password | passwords.go:120:12:125:2 | struct literal | provenance | Config |
|
| passwords.go:125:13:125:20 | password | passwords.go:122:12:127:2 | struct literal | provenance | Config |
|
||||||
| passwords.go:123:13:123:20 | password | passwords.go:120:12:125:2 | struct literal [x] | provenance | |
|
| passwords.go:125:13:125:20 | password | passwords.go:122:12:127:2 | struct literal [x] | provenance | |
|
||||||
| passwords.go:124:13:124:25 | call to getPassword | passwords.go:120:12:125:2 | struct literal | provenance | Config |
|
| passwords.go:126:13:126:25 | call to getPassword | passwords.go:122:12:127:2 | struct literal | provenance | Config |
|
||||||
| passwords.go:124:13:124:25 | call to getPassword | passwords.go:120:12:125:2 | struct literal [y] | provenance | |
|
| passwords.go:126:13:126:25 | call to getPassword | passwords.go:122:12:127:2 | struct literal [y] | provenance | |
|
||||||
| passwords.go:128:14:128:19 | config [x] | passwords.go:128:14:128:21 | selection of x | provenance | |
|
| passwords.go:130:14:130:19 | config [x] | passwords.go:130:14:130:21 | selection of x | provenance | |
|
||||||
| passwords.go:129:14:129:19 | config [y] | passwords.go:129:14:129:21 | selection of y | provenance | |
|
| passwords.go:131:14:131:19 | config [y] | passwords.go:131:14:131:21 | selection of y | provenance | |
|
||||||
| protobuf.go:9:2:9:9 | definition of password | protobuf.go:12:22:12:29 | password | provenance | |
|
| protobuf.go:9:2:9:9 | definition of password | protobuf.go:12:22:12:29 | password | provenance | |
|
||||||
| protobuf.go:12:2:12:6 | implicit dereference [postupdate] [Description] | protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | provenance | |
|
| protobuf.go:12:2:12:6 | implicit dereference [postupdate] [Description] | protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | provenance | |
|
||||||
| protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | protobuf.go:14:14:14:18 | query [pointer, Description] | provenance | |
|
| protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | protobuf.go:14:14:14:18 | query [pointer, Description] | provenance | |
|
||||||
@@ -274,20 +194,12 @@ nodes
|
|||||||
| main.go:54:12:54:19 | password | semmle.label | password |
|
| main.go:54:12:54:19 | password | semmle.label | password |
|
||||||
| main.go:54:12:54:19 | password | semmle.label | password |
|
| main.go:54:12:54:19 | password | semmle.label | password |
|
||||||
| main.go:56:11:56:18 | password | semmle.label | password |
|
| main.go:56:11:56:18 | password | semmle.label | password |
|
||||||
| main.go:56:11:56:18 | password | semmle.label | password |
|
|
||||||
| main.go:59:18:59:25 | password | semmle.label | password |
|
|
||||||
| main.go:59:18:59:25 | password | semmle.label | password |
|
| main.go:59:18:59:25 | password | semmle.label | password |
|
||||||
| main.go:62:12:62:19 | password | semmle.label | password |
|
| main.go:62:12:62:19 | password | semmle.label | password |
|
||||||
| main.go:62:12:62:19 | password | semmle.label | password |
|
|
||||||
| main.go:65:13:65:20 | password | semmle.label | password |
|
|
||||||
| main.go:65:13:65:20 | password | semmle.label | password |
|
| main.go:65:13:65:20 | password | semmle.label | password |
|
||||||
| main.go:68:11:68:18 | password | semmle.label | password |
|
| main.go:68:11:68:18 | password | semmle.label | password |
|
||||||
| main.go:68:11:68:18 | password | semmle.label | password |
|
|
||||||
| main.go:71:18:71:25 | password | semmle.label | password |
|
|
||||||
| main.go:71:18:71:25 | password | semmle.label | password |
|
| main.go:71:18:71:25 | password | semmle.label | password |
|
||||||
| main.go:74:12:74:19 | password | semmle.label | password |
|
| main.go:74:12:74:19 | password | semmle.label | password |
|
||||||
| main.go:74:12:74:19 | password | semmle.label | password |
|
|
||||||
| main.go:77:13:77:20 | password | semmle.label | password |
|
|
||||||
| main.go:77:13:77:20 | password | semmle.label | password |
|
| main.go:77:13:77:20 | password | semmle.label | password |
|
||||||
| main.go:79:14:79:21 | password | semmle.label | password |
|
| main.go:79:14:79:21 | password | semmle.label | password |
|
||||||
| main.go:80:17:80:24 | password | semmle.label | password |
|
| main.go:80:17:80:24 | password | semmle.label | password |
|
||||||
@@ -308,43 +220,43 @@ nodes
|
|||||||
| passwords.go:27:14:27:26 | call to getPassword | semmle.label | call to getPassword |
|
| passwords.go:27:14:27:26 | call to getPassword | semmle.label | call to getPassword |
|
||||||
| passwords.go:28:14:28:28 | call to getPassword | semmle.label | call to getPassword |
|
| passwords.go:28:14:28:28 | call to getPassword | semmle.label | call to getPassword |
|
||||||
| passwords.go:30:8:30:15 | password | semmle.label | password |
|
| passwords.go:30:8:30:15 | password | semmle.label | password |
|
||||||
| passwords.go:32:12:32:19 | password | semmle.label | password |
|
| passwords.go:33:13:33:20 | password | semmle.label | password |
|
||||||
| passwords.go:34:14:34:35 | ...+... | semmle.label | ...+... |
|
| passwords.go:36:14:36:35 | ...+... | semmle.label | ...+... |
|
||||||
| passwords.go:34:28:34:35 | password | semmle.label | password |
|
| passwords.go:36:28:36:35 | password | semmle.label | password |
|
||||||
| passwords.go:36:10:38:2 | struct literal | semmle.label | struct literal |
|
| passwords.go:38:10:40:2 | struct literal | semmle.label | struct literal |
|
||||||
| passwords.go:37:13:37:13 | x | semmle.label | x |
|
| passwords.go:39:13:39:13 | x | semmle.label | x |
|
||||||
| passwords.go:39:14:39:17 | obj1 | semmle.label | obj1 |
|
| passwords.go:41:14:41:17 | obj1 | semmle.label | obj1 |
|
||||||
| passwords.go:41:10:43:2 | struct literal | semmle.label | struct literal |
|
| passwords.go:43:10:45:2 | struct literal | semmle.label | struct literal |
|
||||||
| passwords.go:42:6:42:13 | password | semmle.label | password |
|
| passwords.go:44:6:44:13 | password | semmle.label | password |
|
||||||
| passwords.go:44:14:44:17 | obj2 | semmle.label | obj2 |
|
| passwords.go:46:14:46:17 | obj2 | semmle.label | obj2 |
|
||||||
| passwords.go:48:11:48:18 | password | semmle.label | password |
|
| passwords.go:50:11:50:18 | password | semmle.label | password |
|
||||||
| passwords.go:50:2:50:15 | definition of fixed_password | semmle.label | definition of fixed_password |
|
| passwords.go:52:2:52:15 | definition of fixed_password | semmle.label | definition of fixed_password |
|
||||||
| passwords.go:51:14:51:27 | fixed_password | semmle.label | fixed_password |
|
| passwords.go:53:14:53:27 | fixed_password | semmle.label | fixed_password |
|
||||||
| passwords.go:86:19:88:2 | struct literal | semmle.label | struct literal |
|
| passwords.go:88:19:90:2 | struct literal | semmle.label | struct literal |
|
||||||
| passwords.go:87:16:87:36 | call to make | semmle.label | call to make |
|
| passwords.go:89:16:89:36 | call to make | semmle.label | call to make |
|
||||||
| passwords.go:89:14:89:26 | utilityObject | semmle.label | utilityObject |
|
| passwords.go:91:14:91:26 | utilityObject | semmle.label | utilityObject |
|
||||||
| passwords.go:92:23:92:28 | secret | semmle.label | secret |
|
| passwords.go:94:23:94:28 | secret | semmle.label | secret |
|
||||||
| passwords.go:102:15:102:40 | ...+... | semmle.label | ...+... |
|
| passwords.go:104:15:104:40 | ...+... | semmle.label | ...+... |
|
||||||
| passwords.go:102:33:102:40 | password | semmle.label | password |
|
| passwords.go:104:33:104:40 | password | semmle.label | password |
|
||||||
| passwords.go:108:16:108:41 | ...+... | semmle.label | ...+... |
|
| passwords.go:110:16:110:41 | ...+... | semmle.label | ...+... |
|
||||||
| passwords.go:108:34:108:41 | password | semmle.label | password |
|
| passwords.go:110:34:110:41 | password | semmle.label | password |
|
||||||
| passwords.go:113:15:113:40 | ...+... | semmle.label | ...+... |
|
| passwords.go:115:15:115:40 | ...+... | semmle.label | ...+... |
|
||||||
| passwords.go:113:33:113:40 | password | semmle.label | password |
|
| passwords.go:115:33:115:40 | password | semmle.label | password |
|
||||||
| passwords.go:116:6:116:14 | definition of password1 | semmle.label | definition of password1 |
|
| passwords.go:118:6:118:14 | definition of password1 | semmle.label | definition of password1 |
|
||||||
| passwords.go:117:14:117:45 | ...+... | semmle.label | ...+... |
|
| passwords.go:119:14:119:45 | ...+... | semmle.label | ...+... |
|
||||||
| passwords.go:117:28:117:36 | password1 | semmle.label | password1 |
|
| passwords.go:119:28:119:36 | password1 | semmle.label | password1 |
|
||||||
| passwords.go:117:28:117:45 | call to String | semmle.label | call to String |
|
| passwords.go:119:28:119:45 | call to String | semmle.label | call to String |
|
||||||
| passwords.go:120:12:125:2 | struct literal | semmle.label | struct literal |
|
| passwords.go:122:12:127:2 | struct literal | semmle.label | struct literal |
|
||||||
| passwords.go:120:12:125:2 | struct literal [x] | semmle.label | struct literal [x] |
|
| passwords.go:122:12:127:2 | struct literal [x] | semmle.label | struct literal [x] |
|
||||||
| passwords.go:120:12:125:2 | struct literal [y] | semmle.label | struct literal [y] |
|
| passwords.go:122:12:127:2 | struct literal [y] | semmle.label | struct literal [y] |
|
||||||
| passwords.go:121:13:121:14 | x3 | semmle.label | x3 |
|
| passwords.go:123:13:123:14 | x3 | semmle.label | x3 |
|
||||||
| passwords.go:123:13:123:20 | password | semmle.label | password |
|
| passwords.go:125:13:125:20 | password | semmle.label | password |
|
||||||
| passwords.go:124:13:124:25 | call to getPassword | semmle.label | call to getPassword |
|
| passwords.go:126:13:126:25 | call to getPassword | semmle.label | call to getPassword |
|
||||||
| passwords.go:127:14:127:19 | config | semmle.label | config |
|
| passwords.go:129:14:129:19 | config | semmle.label | config |
|
||||||
| passwords.go:128:14:128:19 | config [x] | semmle.label | config [x] |
|
| passwords.go:130:14:130:19 | config [x] | semmle.label | config [x] |
|
||||||
| passwords.go:128:14:128:21 | selection of x | semmle.label | selection of x |
|
| passwords.go:130:14:130:21 | selection of x | semmle.label | selection of x |
|
||||||
| passwords.go:129:14:129:19 | config [y] | semmle.label | config [y] |
|
| passwords.go:131:14:131:19 | config [y] | semmle.label | config [y] |
|
||||||
| passwords.go:129:14:129:21 | selection of y | semmle.label | selection of y |
|
| passwords.go:131:14:131:21 | selection of y | semmle.label | selection of y |
|
||||||
| protobuf.go:9:2:9:9 | definition of password | semmle.label | definition of password |
|
| protobuf.go:9:2:9:9 | definition of password | semmle.label | definition of password |
|
||||||
| protobuf.go:12:2:12:6 | implicit dereference [postupdate] [Description] | semmle.label | implicit dereference [postupdate] [Description] |
|
| protobuf.go:12:2:12:6 | implicit dereference [postupdate] [Description] | semmle.label | implicit dereference [postupdate] [Description] |
|
||||||
| protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | semmle.label | query [postupdate] [pointer, Description] |
|
| protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | semmle.label | query [postupdate] [pointer, Description] |
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ func redact(kind, value string) string {
|
|||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
func test() {
|
func test(selector int) {
|
||||||
name := "user"
|
name := "user"
|
||||||
password := "P@ssw0rd" // $ Source
|
password := "P@ssw0rd" // $ Source
|
||||||
x := "horsebatterystapleincorrect"
|
x := "horsebatterystapleincorrect"
|
||||||
@@ -29,7 +29,9 @@ func test() {
|
|||||||
|
|
||||||
myLog(password)
|
myLog(password)
|
||||||
|
|
||||||
|
if selector == 1 {
|
||||||
log.Panic(password) // $ Alert
|
log.Panic(password) // $ Alert
|
||||||
|
}
|
||||||
|
|
||||||
log.Println(name + ", " + password) // $ Alert
|
log.Println(name + ", " + password) // $ Alert
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/java-all
|
name: codeql/java-all
|
||||||
version: 9.1.2
|
version: 9.1.3-dev
|
||||||
groups: java
|
groups: java
|
||||||
dbscheme: config/semmlecode.dbscheme
|
dbscheme: config/semmlecode.dbscheme
|
||||||
extractor: java
|
extractor: java
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/java-queries
|
name: codeql/java-queries
|
||||||
version: 1.11.4
|
version: 1.11.5-dev
|
||||||
groups:
|
groups:
|
||||||
- java
|
- java
|
||||||
- queries
|
- queries
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/javascript-all
|
name: codeql/javascript-all
|
||||||
version: 2.7.2
|
version: 2.7.3-dev
|
||||||
groups: javascript
|
groups: javascript
|
||||||
dbscheme: semmlecode.javascript.dbscheme
|
dbscheme: semmlecode.javascript.dbscheme
|
||||||
extractor: javascript
|
extractor: javascript
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/javascript-queries
|
name: codeql/javascript-queries
|
||||||
version: 2.3.11
|
version: 2.3.12-dev
|
||||||
groups:
|
groups:
|
||||||
- javascript
|
- javascript
|
||||||
- queries
|
- queries
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
name: codeql/suite-helpers
|
name: codeql/suite-helpers
|
||||||
version: 1.0.51
|
version: 1.0.52-dev
|
||||||
groups: shared
|
groups: shared
|
||||||
warnOnImplicitThis: true
|
warnOnImplicitThis: true
|
||||||
|
|||||||
2
python/ql/consistency-queries/CfgConsistency.ql
Normal file
2
python/ql/consistency-queries/CfgConsistency.ql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import semmle.python.controlflow.internal.AstNodeImpl
|
||||||
|
import ControlFlow::Consistency
|
||||||
@@ -9,6 +9,7 @@ private import semmle.python.dataflow.new.internal.DataFlowImplSpecific
|
|||||||
private import semmle.python.dataflow.new.internal.DataFlowDispatch
|
private import semmle.python.dataflow.new.internal.DataFlowDispatch
|
||||||
private import semmle.python.dataflow.new.internal.TaintTrackingImplSpecific
|
private import semmle.python.dataflow.new.internal.TaintTrackingImplSpecific
|
||||||
private import codeql.dataflow.internal.DataFlowImplConsistency
|
private import codeql.dataflow.internal.DataFlowImplConsistency
|
||||||
|
private import semmle.python.controlflow.internal.Cfg as Cfg
|
||||||
|
|
||||||
private module Input implements InputSig<Location, PythonDataFlow> {
|
private module Input implements InputSig<Location, PythonDataFlow> {
|
||||||
private import Private
|
private import Private
|
||||||
@@ -72,7 +73,7 @@ private module Input implements InputSig<Location, PythonDataFlow> {
|
|||||||
// resolve to multiple functions), but we only make _one_ ArgumentNode for each
|
// resolve to multiple functions), but we only make _one_ ArgumentNode for each
|
||||||
// argument in the CallNode, we end up violating this consistency check in those
|
// argument in the CallNode, we end up violating this consistency check in those
|
||||||
// cases. (see `getCallArg` in DataFlowDispatch.qll)
|
// cases. (see `getCallArg` in DataFlowDispatch.qll)
|
||||||
exists(DataFlowCall other, CallNode cfgCall | other != call |
|
exists(DataFlowCall other, Cfg::CallNode cfgCall | other != call |
|
||||||
call.getNode() = cfgCall and
|
call.getNode() = cfgCall and
|
||||||
other.getNode() = cfgCall and
|
other.getNode() = cfgCall and
|
||||||
isArgumentNode(arg, call, _) and
|
isArgumentNode(arg, call, _) and
|
||||||
@@ -88,16 +89,16 @@ private module Input implements InputSig<Location, PythonDataFlow> {
|
|||||||
// allow it instead.
|
// allow it instead.
|
||||||
(
|
(
|
||||||
call.getScope() = attr.getScope() and
|
call.getScope() = attr.getScope() and
|
||||||
any(CfgNode n | n.asCfgNode() = call.getNode().(CallNode).getFunction()).getALocalSource() =
|
any(CfgNode n | n.asCfgNode() = call.getNode().(Cfg::CallNode).getFunction())
|
||||||
attr
|
.getALocalSource() = attr
|
||||||
or
|
or
|
||||||
not exists(call.getScope().(Function).getDefinition()) and
|
not exists(call.getScope().(Function).getDefinition()) and
|
||||||
call.getScope().getScope+() = attr.getScope()
|
call.getScope().getScope+() = attr.getScope()
|
||||||
) and
|
) and
|
||||||
(
|
(
|
||||||
other.getScope() = attr.getScope() and
|
other.getScope() = attr.getScope() and
|
||||||
any(CfgNode n | n.asCfgNode() = other.getNode().(CallNode).getFunction()).getALocalSource() =
|
any(CfgNode n | n.asCfgNode() = other.getNode().(Cfg::CallNode).getFunction())
|
||||||
attr
|
.getALocalSource() = attr
|
||||||
or
|
or
|
||||||
not exists(other.getScope().(Function).getDefinition()) and
|
not exists(other.getScope().(Function).getDefinition()) and
|
||||||
other.getScope().getScope+() = attr.getScope()
|
other.getScope().getScope+() = attr.getScope()
|
||||||
|
|||||||
@@ -213,9 +213,11 @@ class ExprWithPointsTo extends Expr {
|
|||||||
* Gets what this expression might "refer-to" in the given `context`.
|
* Gets what this expression might "refer-to" in the given `context`.
|
||||||
*/
|
*/
|
||||||
predicate refersTo(Context context, Object obj, ClassObject cls, AstNode origin) {
|
predicate refersTo(Context context, Object obj, ClassObject cls, AstNode origin) {
|
||||||
this.getAFlowNode()
|
exists(ControlFlowNode this_, ControlFlowNode origin_ |
|
||||||
.(ControlFlowNodeWithPointsTo)
|
this_.getNode() = this and origin_.getNode() = origin
|
||||||
.refersTo(context, obj, cls, origin.getAFlowNode())
|
|
|
||||||
|
this_.(ControlFlowNodeWithPointsTo).refersTo(context, obj, cls, origin_)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -226,7 +228,11 @@ class ExprWithPointsTo extends Expr {
|
|||||||
*/
|
*/
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
predicate refersTo(Object obj, AstNode origin) {
|
predicate refersTo(Object obj, AstNode origin) {
|
||||||
this.getAFlowNode().(ControlFlowNodeWithPointsTo).refersTo(obj, origin.getAFlowNode())
|
exists(ControlFlowNode this_, ControlFlowNode origin_ |
|
||||||
|
this_.getNode() = this and origin_.getNode() = origin
|
||||||
|
|
|
||||||
|
this_.(ControlFlowNodeWithPointsTo).refersTo(obj, origin_)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -240,16 +246,22 @@ class ExprWithPointsTo extends Expr {
|
|||||||
* in the given `context`.
|
* in the given `context`.
|
||||||
*/
|
*/
|
||||||
predicate pointsTo(Context context, Value value, AstNode origin) {
|
predicate pointsTo(Context context, Value value, AstNode origin) {
|
||||||
this.getAFlowNode()
|
exists(ControlFlowNode this_, ControlFlowNode origin_ |
|
||||||
.(ControlFlowNodeWithPointsTo)
|
this_.getNode() = this and origin_.getNode() = origin
|
||||||
.pointsTo(context, value, origin.getAFlowNode())
|
|
|
||||||
|
this_.(ControlFlowNodeWithPointsTo).pointsTo(context, value, origin_)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if this expression might "point-to" to `value` which is from `origin`.
|
* Holds if this expression might "point-to" to `value` which is from `origin`.
|
||||||
*/
|
*/
|
||||||
predicate pointsTo(Value value, AstNode origin) {
|
predicate pointsTo(Value value, AstNode origin) {
|
||||||
this.getAFlowNode().(ControlFlowNodeWithPointsTo).pointsTo(value, origin.getAFlowNode())
|
exists(ControlFlowNode this_, ControlFlowNode origin_ |
|
||||||
|
this_.getNode() = this and origin_.getNode() = origin
|
||||||
|
|
|
||||||
|
this_.(ControlFlowNodeWithPointsTo).pointsTo(value, origin_)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -475,7 +487,10 @@ class FunctionMetricsWithPointsTo extends FunctionMetrics {
|
|||||||
not non_coupling_method(result) and
|
not non_coupling_method(result) and
|
||||||
exists(Call call | call.getScope() = this |
|
exists(Call call | call.getScope() = this |
|
||||||
exists(FunctionObject callee | callee.getFunction() = result |
|
exists(FunctionObject callee | callee.getFunction() = result |
|
||||||
call.getAFlowNode().getFunction().(ControlFlowNodeWithPointsTo).refersTo(callee)
|
exists(CallNode call_ |
|
||||||
|
call_.getNode() = call and
|
||||||
|
call_.getFunction().(ControlFlowNodeWithPointsTo).refersTo(callee)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(Attribute a | call.getFunc() = a |
|
exists(Attribute a | call.getFunc() = a |
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ private predicate jump_to_defn(ControlFlowNode use, Definition defn) {
|
|||||||
private predicate preferred_jump_to_defn(Expr use, Definition def) {
|
private predicate preferred_jump_to_defn(Expr use, Definition def) {
|
||||||
not use instanceof ClassExpr and
|
not use instanceof ClassExpr and
|
||||||
not use instanceof FunctionExpr and
|
not use instanceof FunctionExpr and
|
||||||
jump_to_defn(use.getAFlowNode(), def)
|
exists(ControlFlowNode useNode | useNode.getNode() = use | jump_to_defn(useNode, def))
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate unique_jump_to_defn(Expr use, Definition def) {
|
private predicate unique_jump_to_defn(Expr use, Definition def) {
|
||||||
@@ -452,7 +452,7 @@ private predicate self_parameter_jump_to_defn_attribute(
|
|||||||
* This exists primarily for testing use `getPreferredDefinition()` instead.
|
* This exists primarily for testing use `getPreferredDefinition()` instead.
|
||||||
*/
|
*/
|
||||||
Definition getADefinition(Expr use) {
|
Definition getADefinition(Expr use) {
|
||||||
jump_to_defn(use.getAFlowNode(), result) and
|
exists(ControlFlowNode useNode | useNode.getNode() = use | jump_to_defn(useNode, result)) and
|
||||||
not use instanceof Call and
|
not use instanceof Call and
|
||||||
not use.isArtificial() and
|
not use.isArtificial() and
|
||||||
// Not the use itself
|
// Not the use itself
|
||||||
|
|||||||
4
python/ql/lib/change-notes/2026-05-19-add-shared-cfg.md
Normal file
4
python/ql/lib/change-notes/2026-05-19-add-shared-cfg.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* A new Python control flow graph implementation has been added under `semmle.python.controlflow.internal.Cfg` (backed by `AstNodeImpl.qll`), built on the shared `codeql.controlflow.ControlFlowGraph` library. It is not yet used by the dataflow library or any production query; the legacy CFG in `semmle/python/Flow.qll` remains the default. The new library is exposed for tests and for upcoming migrations.
|
||||||
4
python/ql/lib/change-notes/2026-05-19-add-shared-ssa.md
Normal file
4
python/ql/lib/change-notes/2026-05-19-add-shared-ssa.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* A new SSA adapter has been added under `semmle.python.dataflow.new.internal.SsaImpl`, built on the shared `codeql.ssa.Ssa` library and the new shared CFG (`semmle.python.controlflow.internal.Cfg`). It is not yet used by the dataflow library or any production query; the legacy ESSA SSA in `semmle/python/essa/*` remains the default. The new SSA adapter is exposed for tests and for the upcoming dataflow migration.
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
category: deprecated
|
||||||
|
---
|
||||||
|
* The `AstNode.getAFlowNode()` predicate has been deprecated. Use `ControlFlowNode.getNode()` from the other direction instead: replace `e.getAFlowNode() = n` with `n.getNode() = e`. This is a preparatory step towards migrating the dataflow library off the legacy CFG; it has no semantic effect.
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* Simplified the internal predicates that detect `@staticmethod`, `@classmethod` and `@property` decorators to match the decorator's AST `Name` directly, rather than going through the CFG and requiring the name to resolve globally. Code that shadows these three builtin decorators at the module-scope will now be classified by the decorator name alone; in practice, shadowing these names is extremely rare and the call-graph results are unchanged.
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: deprecated
|
||||||
|
---
|
||||||
|
* The `Function.getAReturnValueFlowNode()` predicate has been deprecated. Bind a `Return` node explicitly instead — `exists(Return ret | ret.getScope() = f and n.getNode() = ret.getValue())`. This is a preparatory step towards migrating the dataflow library off the legacy CFG; it has no semantic effect.
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: breaking
|
||||||
|
---
|
||||||
|
* The deprecated `AstNode.getAFlowNode()` and `Function.getAReturnValueFlowNode()` predicates now return nodes from the new shared CFG (`Cfg::ControlFlowNode`) rather than from the legacy CFG (`ControlFlowNode`). Callers that still rely on these deprecated APIs and feed the result into legacy-CFG-aware predicates will no longer type-check; migrate to `n.getNode() = e` (or, for return values, the explicit `Return` pattern shown in the deprecation message) to get nodes from the dataflow library's current CFG.
|
||||||
45
python/ql/lib/printCfgNew.ql
Normal file
45
python/ql/lib/printCfgNew.ql
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
* @name Print CFG (New)
|
||||||
|
* @description Produces a representation of a file's Control Flow Graph
|
||||||
|
* using the new shared control flow library.
|
||||||
|
* This query is used by the VS Code extension.
|
||||||
|
* @id python/print-cfg
|
||||||
|
* @kind graph
|
||||||
|
* @tags ide-contextual-queries/print-cfg
|
||||||
|
*/
|
||||||
|
|
||||||
|
private import python as Py
|
||||||
|
import semmle.python.controlflow.internal.AstNodeImpl
|
||||||
|
|
||||||
|
external string selectedSourceFile();
|
||||||
|
|
||||||
|
private predicate selectedSourceFileAlias = selectedSourceFile/0;
|
||||||
|
|
||||||
|
external int selectedSourceLine();
|
||||||
|
|
||||||
|
private predicate selectedSourceLineAlias = selectedSourceLine/0;
|
||||||
|
|
||||||
|
external int selectedSourceColumn();
|
||||||
|
|
||||||
|
private predicate selectedSourceColumnAlias = selectedSourceColumn/0;
|
||||||
|
|
||||||
|
module ViewCfgQueryInput implements ControlFlow::ViewCfgQueryInputSig<Py::File> {
|
||||||
|
predicate selectedSourceFile = selectedSourceFileAlias/0;
|
||||||
|
|
||||||
|
predicate selectedSourceLine = selectedSourceLineAlias/0;
|
||||||
|
|
||||||
|
predicate selectedSourceColumn = selectedSourceColumnAlias/0;
|
||||||
|
|
||||||
|
predicate cfgScopeSpan(
|
||||||
|
Ast::Callable callable, Py::File file, int startLine, int startColumn, int endLine,
|
||||||
|
int endColumn
|
||||||
|
) {
|
||||||
|
exists(Py::Scope scope |
|
||||||
|
scope = callable.asScope() and
|
||||||
|
file = scope.getLocation().getFile() and
|
||||||
|
scope.getLocation().hasLocationInfo(_, startLine, startColumn, endLine, endColumn)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
import ControlFlow::ViewCfgQuery<Py::File, ViewCfgQueryInput>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/python-all
|
name: codeql/python-all
|
||||||
version: 7.1.2
|
version: 7.1.3-dev
|
||||||
groups: python
|
groups: python
|
||||||
dbscheme: semmlecode.python.dbscheme
|
dbscheme: semmlecode.python.dbscheme
|
||||||
extractor: python
|
extractor: python
|
||||||
|
|||||||
@@ -6,8 +6,9 @@
|
|||||||
* directed and labeled; they specify how the components represented by nodes relate to each other.
|
* directed and labeled; they specify how the components represented by nodes relate to each other.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Importing python under the `py` namespace to avoid importing `CallNode` from `Flow.qll` and thereby having a naming conflict with `API::CallNode`.
|
// Importing python under the `PY` namespace to avoid pulling in `CallNode` from `Flow.qll` (via `import python`) and thereby having a naming conflict with `API::CallNode`.
|
||||||
private import python as PY
|
private import python as PY
|
||||||
|
private import semmle.python.controlflow.internal.Cfg as Cfg
|
||||||
import semmle.python.dataflow.new.DataFlow
|
import semmle.python.dataflow.new.DataFlow
|
||||||
private import semmle.python.internal.CachedStages
|
private import semmle.python.internal.CachedStages
|
||||||
|
|
||||||
@@ -282,7 +283,7 @@ module API {
|
|||||||
index = this.getIndex() and
|
index = this.getIndex() and
|
||||||
(
|
(
|
||||||
// subscripting
|
// subscripting
|
||||||
exists(PY::SubscriptNode subscript |
|
exists(Cfg::SubscriptNode subscript |
|
||||||
subscript.getObject() = this.getAValueReachableFromSource().asCfgNode() and
|
subscript.getObject() = this.getAValueReachableFromSource().asCfgNode() and
|
||||||
subscript.getIndex() = index.asSink().asCfgNode()
|
subscript.getIndex() = index.asSink().asCfgNode()
|
||||||
|
|
|
|
||||||
@@ -290,7 +291,7 @@ module API {
|
|||||||
subscript = result.asSource().asCfgNode()
|
subscript = result.asSource().asCfgNode()
|
||||||
or
|
or
|
||||||
// writing
|
// writing
|
||||||
subscript.(PY::DefinitionNode).getValue() = result.asSink().asCfgNode()
|
subscript.(Cfg::DefinitionNode).getValue() = result.asSink().asCfgNode()
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
// dictionary literals
|
// dictionary literals
|
||||||
@@ -684,7 +685,7 @@ module API {
|
|||||||
* Ignores relative imports, such as `from ..foo.bar import baz`.
|
* Ignores relative imports, such as `from ..foo.bar import baz`.
|
||||||
*/
|
*/
|
||||||
private predicate imports(DataFlow::CfgNode imp, string name) {
|
private predicate imports(DataFlow::CfgNode imp, string name) {
|
||||||
exists(PY::ImportExprNode iexpr |
|
exists(Cfg::ImportExprNode iexpr |
|
||||||
imp.getNode() = iexpr and
|
imp.getNode() = iexpr and
|
||||||
not iexpr.getNode().isRelative() and
|
not iexpr.getNode().isRelative() and
|
||||||
name = iexpr.getNode().getImportedModuleName()
|
name = iexpr.getNode().getImportedModuleName()
|
||||||
@@ -775,7 +776,7 @@ module API {
|
|||||||
// list literals, from `x` to `[x]`
|
// list literals, from `x` to `[x]`
|
||||||
// TODO: once convenient, this should be done at a higher level than the AST,
|
// TODO: once convenient, this should be done at a higher level than the AST,
|
||||||
// at least at the CFG layer, to take splitting into account.
|
// at least at the CFG layer, to take splitting into account.
|
||||||
// Also consider `SequenceNode for generality.
|
// Also consider `Cfg::SequenceNode` for generality.
|
||||||
exists(PY::List list | list = pred.(DataFlow::ExprNode).getNode().getNode() |
|
exists(PY::List list | list = pred.(DataFlow::ExprNode).getNode().getNode() |
|
||||||
rhs.(DataFlow::ExprNode).getNode().getNode() = list.getAnElt() and
|
rhs.(DataFlow::ExprNode).getNode().getNode() = list.getAnElt() and
|
||||||
lbl = Label::subscript()
|
lbl = Label::subscript()
|
||||||
@@ -805,7 +806,7 @@ module API {
|
|||||||
subscript = trackUseNode(src).getSubscript(index)
|
subscript = trackUseNode(src).getSubscript(index)
|
||||||
|
|
|
|
||||||
// from `x` to a definition of `x[...]`
|
// from `x` to a definition of `x[...]`
|
||||||
rhs.asCfgNode() = subscript.asCfgNode().(PY::DefinitionNode).getValue() and
|
rhs.asCfgNode() = subscript.asCfgNode().(Cfg::DefinitionNode).getValue() and
|
||||||
lbl = Label::subscript()
|
lbl = Label::subscript()
|
||||||
or
|
or
|
||||||
// from `x` to `"key"` in `x["key"]`
|
// from `x` to `"key"` in `x["key"]`
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ module;
|
|||||||
|
|
||||||
import python
|
import python
|
||||||
private import semmle.python.internal.CachedStages
|
private import semmle.python.internal.CachedStages
|
||||||
|
private import semmle.python.controlflow.internal.Cfg as Cfg
|
||||||
|
|
||||||
/** A syntactic node (Class, Function, Module, Expr, Stmt or Comprehension) corresponding to a flow node */
|
/** A syntactic node (Class, Function, Module, Expr, Stmt or Comprehension) corresponding to a flow node */
|
||||||
abstract class AstNode extends AstNode_ {
|
abstract class AstNode extends AstNode_ {
|
||||||
@@ -16,21 +17,25 @@ abstract class AstNode extends AstNode_ {
|
|||||||
/** Gets the scope that this node occurs in */
|
/** Gets the scope that this node occurs in */
|
||||||
abstract Scope getScope();
|
abstract Scope getScope();
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a flow node corresponding directly to this node.
|
|
||||||
* NOTE: For some statements and other purely syntactic elements,
|
|
||||||
* there may not be a `ControlFlowNode`
|
|
||||||
*/
|
|
||||||
cached
|
|
||||||
ControlFlowNode getAFlowNode() {
|
|
||||||
Stages::AST::ref() and
|
|
||||||
py_flow_bb_node(result, this, _, _)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the location for this AST node */
|
/** Gets the location for this AST node */
|
||||||
cached
|
cached
|
||||||
Location getLocation() { none() }
|
Location getLocation() { none() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DEPRECATED: use `ControlFlowNode.getNode()` from the other direction instead;
|
||||||
|
* that is, replace `e.getAFlowNode() = n` with `n.getNode() = e`. This API is
|
||||||
|
* being removed to untangle the AST and CFG hierarchies.
|
||||||
|
*
|
||||||
|
* Gets a flow node corresponding directly to this node, from the new
|
||||||
|
* (shared) CFG. NOTE: For some statements and other purely syntactic
|
||||||
|
* elements, there may not be a `ControlFlowNode`.
|
||||||
|
*/
|
||||||
|
cached
|
||||||
|
deprecated Cfg::ControlFlowNode getAFlowNode() {
|
||||||
|
Stages::AST::ref() and
|
||||||
|
result.getNode() = this
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this syntactic element is artificial, that is it is generated
|
* Whether this syntactic element is artificial, that is it is generated
|
||||||
* by the compiler and is not present in the source
|
* by the compiler and is not present in the source
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
private import python
|
private import python
|
||||||
|
private import semmle.python.controlflow.internal.Cfg as Cfg
|
||||||
private import semmle.python.dataflow.new.DataFlow
|
private import semmle.python.dataflow.new.DataFlow
|
||||||
private import semmle.python.dataflow.new.internal.DataFlowImplSpecific
|
private import semmle.python.dataflow.new.internal.DataFlowImplSpecific
|
||||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
private import semmle.python.dataflow.new.RemoteFlowSources
|
||||||
@@ -214,7 +215,7 @@ module Path {
|
|||||||
SafeAccessCheck() { this = DataFlow::BarrierGuard<safeAccessCheck/3>::getABarrierNode() }
|
SafeAccessCheck() { this = DataFlow::BarrierGuard<safeAccessCheck/3>::getABarrierNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate safeAccessCheck(DataFlow::GuardNode g, ControlFlowNode node, boolean branch) {
|
private predicate safeAccessCheck(DataFlow::GuardNode g, Cfg::ControlFlowNode node, boolean branch) {
|
||||||
g.(SafeAccessCheck::Range).checks(node, branch)
|
g.(SafeAccessCheck::Range).checks(node, branch)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,7 +224,7 @@ module Path {
|
|||||||
/** A data-flow node that checks that a path is safe to access in some way, for example by having a controlled prefix. */
|
/** A data-flow node that checks that a path is safe to access in some way, for example by having a controlled prefix. */
|
||||||
abstract class Range extends DataFlow::GuardNode {
|
abstract class Range extends DataFlow::GuardNode {
|
||||||
/** Holds if this guard validates `node` upon evaluating to `branch`. */
|
/** Holds if this guard validates `node` upon evaluating to `branch`. */
|
||||||
abstract predicate checks(ControlFlowNode node, boolean branch);
|
abstract predicate checks(Cfg::ControlFlowNode node, boolean branch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ class Expr extends Expr_, AstNode {
|
|||||||
/** Whether this expression may have a side effect (as determined purely from its syntax) */
|
/** Whether this expression may have a side effect (as determined purely from its syntax) */
|
||||||
predicate hasSideEffects() {
|
predicate hasSideEffects() {
|
||||||
/* If an exception raised by this expression handled, count that as a side effect */
|
/* If an exception raised by this expression handled, count that as a side effect */
|
||||||
this.getAFlowNode().getASuccessor().getNode() instanceof ExceptStmt
|
exists(ControlFlowNode n | n.getNode() = this |
|
||||||
|
n.getASuccessor().getNode() instanceof ExceptStmt
|
||||||
|
)
|
||||||
or
|
or
|
||||||
this.getASubExpression().hasSideEffects()
|
this.getASubExpression().hasSideEffects()
|
||||||
}
|
}
|
||||||
@@ -68,8 +70,6 @@ class Attribute extends Attribute_ {
|
|||||||
/* syntax: Expr.name */
|
/* syntax: Expr.name */
|
||||||
override Expr getASubExpression() { result = this.getObject() }
|
override Expr getASubExpression() { result = this.getObject() }
|
||||||
|
|
||||||
override AttrNode getAFlowNode() { result = super.getAFlowNode() }
|
|
||||||
|
|
||||||
/** Gets the name of this attribute. That is the `name` in `obj.name` */
|
/** Gets the name of this attribute. That is the `name` in `obj.name` */
|
||||||
string getName() { result = Attribute_.super.getAttr() }
|
string getName() { result = Attribute_.super.getAttr() }
|
||||||
|
|
||||||
@@ -96,8 +96,6 @@ class Subscript extends Subscript_ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Expr getObject() { result = Subscript_.super.getValue() }
|
Expr getObject() { result = Subscript_.super.getValue() }
|
||||||
|
|
||||||
override SubscriptNode getAFlowNode() { result = super.getAFlowNode() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A call expression, such as `func(...)` */
|
/** A call expression, such as `func(...)` */
|
||||||
@@ -113,8 +111,6 @@ class Call extends Call_ {
|
|||||||
|
|
||||||
override string toString() { result = this.getFunc().toString() + "()" }
|
override string toString() { result = this.getFunc().toString() + "()" }
|
||||||
|
|
||||||
override CallNode getAFlowNode() { result = super.getAFlowNode() }
|
|
||||||
|
|
||||||
/** Gets a tuple (*) argument of this call. */
|
/** Gets a tuple (*) argument of this call. */
|
||||||
Expr getStarargs() { result = this.getAPositionalArg().(Starred).getValue() }
|
Expr getStarargs() { result = this.getAPositionalArg().(Starred).getValue() }
|
||||||
|
|
||||||
@@ -200,8 +196,6 @@ class IfExp extends IfExp_ {
|
|||||||
override Expr getASubExpression() {
|
override Expr getASubExpression() {
|
||||||
result = this.getTest() or result = this.getBody() or result = this.getOrelse()
|
result = this.getTest() or result = this.getBody() or result = this.getOrelse()
|
||||||
}
|
}
|
||||||
|
|
||||||
override IfExprNode getAFlowNode() { result = super.getAFlowNode() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A starred expression, such as the `*rest` in the assignment `first, *rest = seq` */
|
/** A starred expression, such as the `*rest` in the assignment `first, *rest = seq` */
|
||||||
@@ -410,8 +404,6 @@ class PlaceHolder extends PlaceHolder_ {
|
|||||||
override Expr getASubExpression() { none() }
|
override Expr getASubExpression() { none() }
|
||||||
|
|
||||||
override string toString() { result = "$" + this.getId() }
|
override string toString() { result = "$" + this.getId() }
|
||||||
|
|
||||||
override NameNode getAFlowNode() { result = super.getAFlowNode() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A tuple expression such as `( 1, 3, 5, 7, 9 )` */
|
/** A tuple expression such as `( 1, 3, 5, 7, 9 )` */
|
||||||
@@ -478,8 +470,6 @@ class Name extends Name_ {
|
|||||||
|
|
||||||
override string toString() { result = this.getId() }
|
override string toString() { result = this.getId() }
|
||||||
|
|
||||||
override NameNode getAFlowNode() { result = super.getAFlowNode() }
|
|
||||||
|
|
||||||
override predicate isArtificial() {
|
override predicate isArtificial() {
|
||||||
/* Artificial variable names in comprehensions all start with "." */
|
/* Artificial variable names in comprehensions all start with "." */
|
||||||
this.getId().charAt(0) = "."
|
this.getId().charAt(0) = "."
|
||||||
@@ -585,8 +575,6 @@ abstract class NameConstant extends Name, ImmutableLiteral {
|
|||||||
|
|
||||||
override predicate isConstant() { any() }
|
override predicate isConstant() { any() }
|
||||||
|
|
||||||
override NameConstantNode getAFlowNode() { result = Name.super.getAFlowNode() }
|
|
||||||
|
|
||||||
override predicate isArtificial() { none() }
|
override predicate isArtificial() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
overlay[local]
|
overlay[local]
|
||||||
module;
|
module;
|
||||||
|
|
||||||
import python
|
import python as Py
|
||||||
private import semmle.python.internal.CachedStages
|
private import semmle.python.internal.CachedStages
|
||||||
private import codeql.controlflow.BasicBlock as BB
|
private import codeql.controlflow.BasicBlock as BB
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ private import codeql.controlflow.BasicBlock as BB
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
private predicate augstore(ControlFlowNode load, ControlFlowNode store) {
|
private predicate augstore(ControlFlowNode load, ControlFlowNode store) {
|
||||||
exists(Expr load_store | exists(AugAssign aa | aa.getTarget() = load_store) |
|
exists(Py::Expr load_store | exists(Py::AugAssign aa | aa.getTarget() = load_store) |
|
||||||
toAst(load) = load_store and
|
toAst(load) = load_store and
|
||||||
toAst(store) = load_store and
|
toAst(store) = load_store and
|
||||||
load.strictlyDominates(store)
|
load.strictlyDominates(store)
|
||||||
@@ -25,7 +25,7 @@ private predicate augstore(ControlFlowNode load, ControlFlowNode store) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** A non-dispatched getNode() to avoid negative recursion issues */
|
/** A non-dispatched getNode() to avoid negative recursion issues */
|
||||||
private AstNode toAst(ControlFlowNode n) { py_flow_bb_node(n, result, _, _) }
|
private Py::AstNode toAst(ControlFlowNode n) { py_flow_bb_node(n, result, _, _) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A control flow node. Control flow nodes have a many-to-one relation with syntactic nodes,
|
* A control flow node. Control flow nodes have a many-to-one relation with syntactic nodes,
|
||||||
@@ -35,19 +35,19 @@ private AstNode toAst(ControlFlowNode n) { py_flow_bb_node(n, result, _, _) }
|
|||||||
class ControlFlowNode extends @py_flow_node {
|
class ControlFlowNode extends @py_flow_node {
|
||||||
/** Whether this control flow node is a load (including those in augmented assignments) */
|
/** Whether this control flow node is a load (including those in augmented assignments) */
|
||||||
predicate isLoad() {
|
predicate isLoad() {
|
||||||
exists(Expr e | e = toAst(this) | py_expr_contexts(_, 3, e) and not augstore(_, this))
|
exists(Py::Expr e | e = toAst(this) | py_expr_contexts(_, 3, e) and not augstore(_, this))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether this control flow node is a store (including those in augmented assignments) */
|
/** Whether this control flow node is a store (including those in augmented assignments) */
|
||||||
predicate isStore() {
|
predicate isStore() {
|
||||||
exists(Expr e | e = toAst(this) | py_expr_contexts(_, 5, e) or augstore(_, this))
|
exists(Py::Expr e | e = toAst(this) | py_expr_contexts(_, 5, e) or augstore(_, this))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether this control flow node is a delete */
|
/** Whether this control flow node is a delete */
|
||||||
predicate isDelete() { exists(Expr e | e = toAst(this) | py_expr_contexts(_, 2, e)) }
|
predicate isDelete() { exists(Py::Expr e | e = toAst(this) | py_expr_contexts(_, 2, e)) }
|
||||||
|
|
||||||
/** Whether this control flow node is a parameter */
|
/** Whether this control flow node is a parameter */
|
||||||
predicate isParameter() { exists(Expr e | e = toAst(this) | py_expr_contexts(_, 4, e)) }
|
predicate isParameter() { exists(Py::Expr e | e = toAst(this) | py_expr_contexts(_, 4, e)) }
|
||||||
|
|
||||||
/** Whether this control flow node is a store in an augmented assignment */
|
/** Whether this control flow node is a store in an augmented assignment */
|
||||||
predicate isAugStore() { augstore(_, this) }
|
predicate isAugStore() { augstore(_, this) }
|
||||||
@@ -57,61 +57,61 @@ class ControlFlowNode extends @py_flow_node {
|
|||||||
|
|
||||||
/** Whether this flow node corresponds to a literal */
|
/** Whether this flow node corresponds to a literal */
|
||||||
predicate isLiteral() {
|
predicate isLiteral() {
|
||||||
toAst(this) instanceof Bytes
|
toAst(this) instanceof Py::Bytes
|
||||||
or
|
or
|
||||||
toAst(this) instanceof Dict
|
toAst(this) instanceof Py::Dict
|
||||||
or
|
or
|
||||||
toAst(this) instanceof DictComp
|
toAst(this) instanceof Py::DictComp
|
||||||
or
|
or
|
||||||
toAst(this) instanceof Set
|
toAst(this) instanceof Py::Set
|
||||||
or
|
or
|
||||||
toAst(this) instanceof SetComp
|
toAst(this) instanceof Py::SetComp
|
||||||
or
|
or
|
||||||
toAst(this) instanceof Ellipsis
|
toAst(this) instanceof Py::Ellipsis
|
||||||
or
|
or
|
||||||
toAst(this) instanceof GeneratorExp
|
toAst(this) instanceof Py::GeneratorExp
|
||||||
or
|
or
|
||||||
toAst(this) instanceof Lambda
|
toAst(this) instanceof Py::Lambda
|
||||||
or
|
or
|
||||||
toAst(this) instanceof ListComp
|
toAst(this) instanceof Py::ListComp
|
||||||
or
|
or
|
||||||
toAst(this) instanceof List
|
toAst(this) instanceof Py::List
|
||||||
or
|
or
|
||||||
toAst(this) instanceof Num
|
toAst(this) instanceof Py::Num
|
||||||
or
|
or
|
||||||
toAst(this) instanceof Tuple
|
toAst(this) instanceof Py::Tuple
|
||||||
or
|
or
|
||||||
toAst(this) instanceof Unicode
|
toAst(this) instanceof Py::Unicode
|
||||||
or
|
or
|
||||||
toAst(this) instanceof NameConstant
|
toAst(this) instanceof Py::NameConstant
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether this flow node corresponds to an attribute expression */
|
/** Whether this flow node corresponds to an attribute expression */
|
||||||
predicate isAttribute() { toAst(this) instanceof Attribute }
|
predicate isAttribute() { toAst(this) instanceof Py::Attribute }
|
||||||
|
|
||||||
/** Whether this flow node corresponds to an subscript expression */
|
/** Whether this flow node corresponds to an subscript expression */
|
||||||
predicate isSubscript() { toAst(this) instanceof Subscript }
|
predicate isSubscript() { toAst(this) instanceof Py::Subscript }
|
||||||
|
|
||||||
/** Whether this flow node corresponds to an import member */
|
/** Whether this flow node corresponds to an import member */
|
||||||
predicate isImportMember() { toAst(this) instanceof ImportMember }
|
predicate isImportMember() { toAst(this) instanceof Py::ImportMember }
|
||||||
|
|
||||||
/** Whether this flow node corresponds to a call */
|
/** Whether this flow node corresponds to a call */
|
||||||
predicate isCall() { toAst(this) instanceof Call }
|
predicate isCall() { toAst(this) instanceof Py::Call }
|
||||||
|
|
||||||
/** Whether this flow node is the first in a module */
|
/** Whether this flow node is the first in a module */
|
||||||
predicate isModuleEntry() { this.isEntryNode() and toAst(this) instanceof Module }
|
predicate isModuleEntry() { this.isEntryNode() and toAst(this) instanceof Py::Module }
|
||||||
|
|
||||||
/** Whether this flow node corresponds to an import */
|
/** Whether this flow node corresponds to an import */
|
||||||
predicate isImport() { toAst(this) instanceof ImportExpr }
|
predicate isImport() { toAst(this) instanceof Py::ImportExpr }
|
||||||
|
|
||||||
/** Whether this flow node corresponds to a conditional expression */
|
/** Whether this flow node corresponds to a conditional expression */
|
||||||
predicate isIfExp() { toAst(this) instanceof IfExp }
|
predicate isIfExp() { toAst(this) instanceof Py::IfExp }
|
||||||
|
|
||||||
/** Whether this flow node corresponds to a function definition expression */
|
/** Whether this flow node corresponds to a function definition expression */
|
||||||
predicate isFunction() { toAst(this) instanceof FunctionExpr }
|
predicate isFunction() { toAst(this) instanceof Py::FunctionExpr }
|
||||||
|
|
||||||
/** Whether this flow node corresponds to a class definition expression */
|
/** Whether this flow node corresponds to a class definition expression */
|
||||||
predicate isClass() { toAst(this) instanceof ClassExpr }
|
predicate isClass() { toAst(this) instanceof Py::ClassExpr }
|
||||||
|
|
||||||
/** Gets a predecessor of this flow node */
|
/** Gets a predecessor of this flow node */
|
||||||
ControlFlowNode getAPredecessor() { this = result.getASuccessor() }
|
ControlFlowNode getAPredecessor() { this = result.getASuccessor() }
|
||||||
@@ -123,25 +123,25 @@ class ControlFlowNode extends @py_flow_node {
|
|||||||
ControlFlowNode getImmediateDominator() { py_idoms(this, result) }
|
ControlFlowNode getImmediateDominator() { py_idoms(this, result) }
|
||||||
|
|
||||||
/** Gets the syntactic element corresponding to this flow node */
|
/** Gets the syntactic element corresponding to this flow node */
|
||||||
AstNode getNode() { py_flow_bb_node(this, result, _, _) }
|
Py::AstNode getNode() { py_flow_bb_node(this, result, _, _) }
|
||||||
|
|
||||||
/** Gets a textual representation of this element. */
|
/** Gets a textual representation of this element. */
|
||||||
cached
|
cached
|
||||||
string toString() {
|
string toString() {
|
||||||
Stages::AST::ref() and
|
Stages::AST::ref() and
|
||||||
// Since modules can have ambigous names, entry nodes can too, if we do not collate them.
|
// Since modules can have ambigous names, entry nodes can too, if we do not collate them.
|
||||||
exists(Scope s | s.getEntryNode() = this |
|
exists(Py::Scope s | s.getEntryNode() = this |
|
||||||
result = "Entry node for " + concat( | | s.toString(), ",")
|
result = "Entry node for " + concat( | | s.toString(), ",")
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(Scope s | s.getANormalExit() = this | result = "Exit node for " + s.toString())
|
exists(Py::Scope s | s.getANormalExit() = this | result = "Exit node for " + s.toString())
|
||||||
or
|
or
|
||||||
not exists(Scope s | s.getEntryNode() = this or s.getANormalExit() = this) and
|
not exists(Py::Scope s | s.getEntryNode() = this or s.getANormalExit() = this) and
|
||||||
result = "ControlFlowNode for " + this.getNode().toString()
|
result = "ControlFlowNode for " + this.getNode().toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the location of this ControlFlowNode */
|
/** Gets the location of this ControlFlowNode */
|
||||||
Location getLocation() { result = this.getNode().getLocation() }
|
Py::Location getLocation() { result = this.getNode().getLocation() }
|
||||||
|
|
||||||
/** Whether this flow node is the first in its scope */
|
/** Whether this flow node is the first in its scope */
|
||||||
predicate isEntryNode() { py_scope_flow(this, _, -1) }
|
predicate isEntryNode() { py_scope_flow(this, _, -1) }
|
||||||
@@ -151,9 +151,9 @@ class ControlFlowNode extends @py_flow_node {
|
|||||||
|
|
||||||
/** Gets the scope containing this flow node */
|
/** Gets the scope containing this flow node */
|
||||||
cached
|
cached
|
||||||
Scope getScope() {
|
Py::Scope getScope() {
|
||||||
Stages::AST::ref() and
|
Stages::AST::ref() and
|
||||||
if this.getNode() instanceof Scope
|
if this.getNode() instanceof Py::Scope
|
||||||
then
|
then
|
||||||
/* Entry or exit node */
|
/* Entry or exit node */
|
||||||
result = this.getNode()
|
result = this.getNode()
|
||||||
@@ -161,7 +161,7 @@ class ControlFlowNode extends @py_flow_node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the enclosing module */
|
/** Gets the enclosing module */
|
||||||
Module getEnclosingModule() { result = this.getScope().getEnclosingModule() }
|
Py::Module getEnclosingModule() { result = this.getScope().getEnclosingModule() }
|
||||||
|
|
||||||
/** Gets a successor for this node if the relevant condition is True. */
|
/** Gets a successor for this node if the relevant condition is True. */
|
||||||
ControlFlowNode getATrueSuccessor() {
|
ControlFlowNode getATrueSuccessor() {
|
||||||
@@ -188,7 +188,7 @@ class ControlFlowNode extends @py_flow_node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Whether the scope may be exited as a result of this node raising an exception */
|
/** Whether the scope may be exited as a result of this node raising an exception */
|
||||||
predicate isExceptionalExit(Scope s) { py_scope_flow(this, s, 1) }
|
predicate isExceptionalExit(Py::Scope s) { py_scope_flow(this, s, 1) }
|
||||||
|
|
||||||
/** Whether this node is a normal (non-exceptional) exit */
|
/** Whether this node is a normal (non-exceptional) exit */
|
||||||
predicate isNormalExit() { py_scope_flow(this, _, 0) or py_scope_flow(this, _, 2) }
|
predicate isNormalExit() { py_scope_flow(this, _, 0) or py_scope_flow(this, _, 2) }
|
||||||
@@ -236,7 +236,7 @@ class ControlFlowNode extends @py_flow_node {
|
|||||||
/* join-ordering helper for `getAChild() */
|
/* join-ordering helper for `getAChild() */
|
||||||
pragma[noinline]
|
pragma[noinline]
|
||||||
private ControlFlowNode getExprChild(BasicBlock dom) {
|
private ControlFlowNode getExprChild(BasicBlock dom) {
|
||||||
this.getNode().(Expr).getAChildNode() = result.getNode() and
|
this.getNode().(Py::Expr).getAChildNode() = result.getNode() and
|
||||||
result.getBasicBlock().dominates(dom) and
|
result.getBasicBlock().dominates(dom) and
|
||||||
not this instanceof UnaryExprNode
|
not this instanceof UnaryExprNode
|
||||||
}
|
}
|
||||||
@@ -249,16 +249,16 @@ class ControlFlowNode extends @py_flow_node {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
private class AnyNode extends ControlFlowNode {
|
private class AnyNode extends ControlFlowNode {
|
||||||
override AstNode getNode() { result = super.getNode() }
|
override Py::AstNode getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a call expression, such as `func(...)` */
|
/** A control flow node corresponding to a call expression, such as `func(...)` */
|
||||||
class CallNode extends ControlFlowNode {
|
class CallNode extends ControlFlowNode {
|
||||||
CallNode() { toAst(this) instanceof Call }
|
CallNode() { toAst(this) instanceof Py::Call }
|
||||||
|
|
||||||
/** Gets the flow node corresponding to the function expression for the call corresponding to this flow node */
|
/** Gets the flow node corresponding to the function expression for the call corresponding to this flow node */
|
||||||
ControlFlowNode getFunction() {
|
ControlFlowNode getFunction() {
|
||||||
exists(Call c |
|
exists(Py::Call c |
|
||||||
this.getNode() = c and
|
this.getNode() = c and
|
||||||
c.getFunc() = result.getNode() and
|
c.getFunc() = result.getNode() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
@@ -267,7 +267,7 @@ class CallNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** Gets the flow node corresponding to the n'th positional argument of the call corresponding to this flow node */
|
/** Gets the flow node corresponding to the n'th positional argument of the call corresponding to this flow node */
|
||||||
ControlFlowNode getArg(int n) {
|
ControlFlowNode getArg(int n) {
|
||||||
exists(Call c |
|
exists(Py::Call c |
|
||||||
this.getNode() = c and
|
this.getNode() = c and
|
||||||
c.getArg(n) = result.getNode() and
|
c.getArg(n) = result.getNode() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
@@ -276,7 +276,7 @@ class CallNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** Gets the flow node corresponding to the named argument of the call corresponding to this flow node */
|
/** Gets the flow node corresponding to the named argument of the call corresponding to this flow node */
|
||||||
ControlFlowNode getArgByName(string name) {
|
ControlFlowNode getArgByName(string name) {
|
||||||
exists(Call c, Keyword k |
|
exists(Py::Call c, Py::Keyword k |
|
||||||
this.getNode() = c and
|
this.getNode() = c and
|
||||||
k = c.getANamedArg() and
|
k = c.getANamedArg() and
|
||||||
k.getValue() = result.getNode() and
|
k.getValue() = result.getNode() and
|
||||||
@@ -292,7 +292,7 @@ class CallNode extends ControlFlowNode {
|
|||||||
result = this.getArgByName(_)
|
result = this.getArgByName(_)
|
||||||
}
|
}
|
||||||
|
|
||||||
override Call getNode() { result = super.getNode() }
|
override Py::Call getNode() { result = super.getNode() }
|
||||||
|
|
||||||
predicate isDecoratorCall() {
|
predicate isDecoratorCall() {
|
||||||
this.isClassDecoratorCall()
|
this.isClassDecoratorCall()
|
||||||
@@ -301,11 +301,11 @@ class CallNode extends ControlFlowNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
predicate isClassDecoratorCall() {
|
predicate isClassDecoratorCall() {
|
||||||
exists(ClassExpr cls | this.getNode() = cls.getADecoratorCall())
|
exists(Py::ClassExpr cls | this.getNode() = cls.getADecoratorCall())
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate isFunctionDecoratorCall() {
|
predicate isFunctionDecoratorCall() {
|
||||||
exists(FunctionExpr func | this.getNode() = func.getADecoratorCall())
|
exists(Py::FunctionExpr func | this.getNode() = func.getADecoratorCall())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the first tuple (*) argument of this call, if any. */
|
/** Gets the first tuple (*) argument of this call, if any. */
|
||||||
@@ -323,11 +323,11 @@ class CallNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** A control flow corresponding to an attribute expression, such as `value.attr` */
|
/** A control flow corresponding to an attribute expression, such as `value.attr` */
|
||||||
class AttrNode extends ControlFlowNode {
|
class AttrNode extends ControlFlowNode {
|
||||||
AttrNode() { toAst(this) instanceof Attribute }
|
AttrNode() { toAst(this) instanceof Py::Attribute }
|
||||||
|
|
||||||
/** Gets the flow node corresponding to the object of the attribute expression corresponding to this flow node */
|
/** Gets the flow node corresponding to the object of the attribute expression corresponding to this flow node */
|
||||||
ControlFlowNode getObject() {
|
ControlFlowNode getObject() {
|
||||||
exists(Attribute a |
|
exists(Py::Attribute a |
|
||||||
this.getNode() = a and
|
this.getNode() = a and
|
||||||
a.getObject() = result.getNode() and
|
a.getObject() = result.getNode() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
@@ -339,7 +339,7 @@ class AttrNode extends ControlFlowNode {
|
|||||||
* with the matching name
|
* with the matching name
|
||||||
*/
|
*/
|
||||||
ControlFlowNode getObject(string name) {
|
ControlFlowNode getObject(string name) {
|
||||||
exists(Attribute a |
|
exists(Py::Attribute a |
|
||||||
this.getNode() = a and
|
this.getNode() = a and
|
||||||
a.getObject() = result.getNode() and
|
a.getObject() = result.getNode() and
|
||||||
a.getName() = name and
|
a.getName() = name and
|
||||||
@@ -348,57 +348,57 @@ class AttrNode extends ControlFlowNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the attribute name of the attribute expression corresponding to this flow node */
|
/** Gets the attribute name of the attribute expression corresponding to this flow node */
|
||||||
string getName() { exists(Attribute a | this.getNode() = a and a.getName() = result) }
|
string getName() { exists(Py::Attribute a | this.getNode() = a and a.getName() = result) }
|
||||||
|
|
||||||
override Attribute getNode() { result = super.getNode() }
|
override Py::Attribute getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a `from ... import ...` expression */
|
/** A control flow node corresponding to a `from ... import ...` expression */
|
||||||
class ImportMemberNode extends ControlFlowNode {
|
class ImportMemberNode extends ControlFlowNode {
|
||||||
ImportMemberNode() { toAst(this) instanceof ImportMember }
|
ImportMemberNode() { toAst(this) instanceof Py::ImportMember }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the flow node corresponding to the module in the import-member expression corresponding to this flow node,
|
* Gets the flow node corresponding to the module in the import-member expression corresponding to this flow node,
|
||||||
* with the matching name
|
* with the matching name
|
||||||
*/
|
*/
|
||||||
ControlFlowNode getModule(string name) {
|
ControlFlowNode getModule(string name) {
|
||||||
exists(ImportMember i | this.getNode() = i and i.getModule() = result.getNode() |
|
exists(Py::ImportMember i | this.getNode() = i and i.getModule() = result.getNode() |
|
||||||
i.getName() = name and
|
i.getName() = name and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override ImportMember getNode() { result = super.getNode() }
|
override Py::ImportMember getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to an artificial expression representing an import */
|
/** A control flow node corresponding to an artificial expression representing an import */
|
||||||
class ImportExprNode extends ControlFlowNode {
|
class ImportExprNode extends ControlFlowNode {
|
||||||
ImportExprNode() { toAst(this) instanceof ImportExpr }
|
ImportExprNode() { toAst(this) instanceof Py::ImportExpr }
|
||||||
|
|
||||||
override ImportExpr getNode() { result = super.getNode() }
|
override Py::ImportExpr getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a `from ... import *` statement */
|
/** A control flow node corresponding to a `from ... import *` statement */
|
||||||
class ImportStarNode extends ControlFlowNode {
|
class ImportStarNode extends ControlFlowNode {
|
||||||
ImportStarNode() { toAst(this) instanceof ImportStar }
|
ImportStarNode() { toAst(this) instanceof Py::ImportStar }
|
||||||
|
|
||||||
/** Gets the flow node corresponding to the module in the import-star corresponding to this flow node */
|
/** Gets the flow node corresponding to the module in the import-star corresponding to this flow node */
|
||||||
ControlFlowNode getModule() {
|
ControlFlowNode getModule() {
|
||||||
exists(ImportStar i | this.getNode() = i and i.getModuleExpr() = result.getNode() |
|
exists(Py::ImportStar i | this.getNode() = i and i.getModuleExpr() = result.getNode() |
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override ImportStar getNode() { result = super.getNode() }
|
override Py::ImportStar getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a subscript expression, such as `value[slice]` */
|
/** A control flow node corresponding to a subscript expression, such as `value[slice]` */
|
||||||
class SubscriptNode extends ControlFlowNode {
|
class SubscriptNode extends ControlFlowNode {
|
||||||
SubscriptNode() { toAst(this) instanceof Subscript }
|
SubscriptNode() { toAst(this) instanceof Py::Subscript }
|
||||||
|
|
||||||
/** flow node corresponding to the value of the sequence in a subscript operation */
|
/** flow node corresponding to the value of the sequence in a subscript operation */
|
||||||
ControlFlowNode getObject() {
|
ControlFlowNode getObject() {
|
||||||
exists(Subscript s |
|
exists(Py::Subscript s |
|
||||||
this.getNode() = s and
|
this.getNode() = s and
|
||||||
s.getObject() = result.getNode() and
|
s.getObject() = result.getNode() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
@@ -407,23 +407,23 @@ class SubscriptNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** flow node corresponding to the index in a subscript operation */
|
/** flow node corresponding to the index in a subscript operation */
|
||||||
ControlFlowNode getIndex() {
|
ControlFlowNode getIndex() {
|
||||||
exists(Subscript s |
|
exists(Py::Subscript s |
|
||||||
this.getNode() = s and
|
this.getNode() = s and
|
||||||
s.getIndex() = result.getNode() and
|
s.getIndex() = result.getNode() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override Subscript getNode() { result = super.getNode() }
|
override Py::Subscript getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a comparison operation, such as `x<y` */
|
/** A control flow node corresponding to a comparison operation, such as `x<y` */
|
||||||
class CompareNode extends ControlFlowNode {
|
class CompareNode extends ControlFlowNode {
|
||||||
CompareNode() { toAst(this) instanceof Compare }
|
CompareNode() { toAst(this) instanceof Py::Compare }
|
||||||
|
|
||||||
/** Whether left and right are a pair of operands for this comparison */
|
/** Whether left and right are a pair of operands for this comparison */
|
||||||
predicate operands(ControlFlowNode left, Cmpop op, ControlFlowNode right) {
|
predicate operands(ControlFlowNode left, Py::Cmpop op, ControlFlowNode right) {
|
||||||
exists(Compare c, Expr eleft, Expr eright |
|
exists(Py::Compare c, Py::Expr eleft, Py::Expr eright |
|
||||||
this.getNode() = c and left.getNode() = eleft and right.getNode() = eright
|
this.getNode() = c and left.getNode() = eleft and right.getNode() = eright
|
||||||
|
|
|
|
||||||
eleft = c.getLeft() and eright = c.getComparator(0) and op = c.getOp(0)
|
eleft = c.getLeft() and eright = c.getComparator(0) and op = c.getOp(0)
|
||||||
@@ -436,26 +436,26 @@ class CompareNode extends ControlFlowNode {
|
|||||||
right.getBasicBlock().dominates(this.getBasicBlock())
|
right.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
}
|
}
|
||||||
|
|
||||||
override Compare getNode() { result = super.getNode() }
|
override Py::Compare getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a conditional expression such as, `body if test else orelse` */
|
/** A control flow node corresponding to a conditional expression such as, `body if test else orelse` */
|
||||||
class IfExprNode extends ControlFlowNode {
|
class IfExprNode extends ControlFlowNode {
|
||||||
IfExprNode() { toAst(this) instanceof IfExp }
|
IfExprNode() { toAst(this) instanceof Py::IfExp }
|
||||||
|
|
||||||
/** flow node corresponding to one of the operands of an if-expression */
|
/** flow node corresponding to one of the operands of an if-expression */
|
||||||
ControlFlowNode getAnOperand() { result = this.getAPredecessor() }
|
ControlFlowNode getAnOperand() { result = this.getAPredecessor() }
|
||||||
|
|
||||||
override IfExp getNode() { result = super.getNode() }
|
override Py::IfExp getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to an assignment expression such as `lhs := rhs`. */
|
/** A control flow node corresponding to an assignment expression such as `lhs := rhs`. */
|
||||||
class AssignmentExprNode extends ControlFlowNode {
|
class AssignmentExprNode extends ControlFlowNode {
|
||||||
AssignmentExprNode() { toAst(this) instanceof AssignExpr }
|
AssignmentExprNode() { toAst(this) instanceof Py::AssignExpr }
|
||||||
|
|
||||||
/** Gets the flow node corresponding to the left-hand side of the assignment expression */
|
/** Gets the flow node corresponding to the left-hand side of the assignment expression */
|
||||||
ControlFlowNode getTarget() {
|
ControlFlowNode getTarget() {
|
||||||
exists(AssignExpr a |
|
exists(Py::AssignExpr a |
|
||||||
this.getNode() = a and
|
this.getNode() = a and
|
||||||
a.getTarget() = result.getNode() and
|
a.getTarget() = result.getNode() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
@@ -464,27 +464,27 @@ class AssignmentExprNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** Gets the flow node corresponding to the right-hand side of the assignment expression */
|
/** Gets the flow node corresponding to the right-hand side of the assignment expression */
|
||||||
ControlFlowNode getValue() {
|
ControlFlowNode getValue() {
|
||||||
exists(AssignExpr a |
|
exists(Py::AssignExpr a |
|
||||||
this.getNode() = a and
|
this.getNode() = a and
|
||||||
a.getValue() = result.getNode() and
|
a.getValue() = result.getNode() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override AssignExpr getNode() { result = super.getNode() }
|
override Py::AssignExpr getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a binary expression, such as `x + y` */
|
/** A control flow node corresponding to a binary expression, such as `x + y` */
|
||||||
class BinaryExprNode extends ControlFlowNode {
|
class BinaryExprNode extends ControlFlowNode {
|
||||||
BinaryExprNode() { toAst(this) instanceof BinaryExpr }
|
BinaryExprNode() { toAst(this) instanceof Py::BinaryExpr }
|
||||||
|
|
||||||
/** flow node corresponding to one of the operands of a binary expression */
|
/** flow node corresponding to one of the operands of a binary expression */
|
||||||
ControlFlowNode getAnOperand() { result = this.getLeft() or result = this.getRight() }
|
ControlFlowNode getAnOperand() { result = this.getLeft() or result = this.getRight() }
|
||||||
|
|
||||||
override BinaryExpr getNode() { result = super.getNode() }
|
override Py::BinaryExpr getNode() { result = super.getNode() }
|
||||||
|
|
||||||
ControlFlowNode getLeft() {
|
ControlFlowNode getLeft() {
|
||||||
exists(BinaryExpr b |
|
exists(Py::BinaryExpr b |
|
||||||
this.getNode() = b and
|
this.getNode() = b and
|
||||||
result.getNode() = b.getLeft() and
|
result.getNode() = b.getLeft() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
@@ -492,7 +492,7 @@ class BinaryExprNode extends ControlFlowNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ControlFlowNode getRight() {
|
ControlFlowNode getRight() {
|
||||||
exists(BinaryExpr b |
|
exists(Py::BinaryExpr b |
|
||||||
this.getNode() = b and
|
this.getNode() = b and
|
||||||
result.getNode() = b.getRight() and
|
result.getNode() = b.getRight() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
@@ -500,11 +500,11 @@ class BinaryExprNode extends ControlFlowNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the operator of this binary expression node. */
|
/** Gets the operator of this binary expression node. */
|
||||||
Operator getOp() { result = this.getNode().getOp() }
|
Py::Operator getOp() { result = this.getNode().getOp() }
|
||||||
|
|
||||||
/** Whether left and right are a pair of operands for this binary expression */
|
/** Whether left and right are a pair of operands for this binary expression */
|
||||||
predicate operands(ControlFlowNode left, Operator op, ControlFlowNode right) {
|
predicate operands(ControlFlowNode left, Py::Operator op, ControlFlowNode right) {
|
||||||
exists(BinaryExpr b, Expr eleft, Expr eright |
|
exists(Py::BinaryExpr b, Py::Expr eleft, Py::Expr eright |
|
||||||
this.getNode() = b and left.getNode() = eleft and right.getNode() = eright
|
this.getNode() = b and left.getNode() = eleft and right.getNode() = eright
|
||||||
|
|
|
|
||||||
eleft = b.getLeft() and eright = b.getRight() and op = b.getOp()
|
eleft = b.getLeft() and eright = b.getRight() and op = b.getOp()
|
||||||
@@ -516,20 +516,20 @@ class BinaryExprNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** A control flow node corresponding to a boolean shortcut (and/or) operation */
|
/** A control flow node corresponding to a boolean shortcut (and/or) operation */
|
||||||
class BoolExprNode extends ControlFlowNode {
|
class BoolExprNode extends ControlFlowNode {
|
||||||
BoolExprNode() { toAst(this) instanceof BoolExpr }
|
BoolExprNode() { toAst(this) instanceof Py::BoolExpr }
|
||||||
|
|
||||||
/** flow node corresponding to one of the operands of a boolean expression */
|
/** flow node corresponding to one of the operands of a boolean expression */
|
||||||
ControlFlowNode getAnOperand() {
|
ControlFlowNode getAnOperand() {
|
||||||
exists(BoolExpr b | this.getNode() = b and result.getNode() = b.getAValue()) and
|
exists(Py::BoolExpr b | this.getNode() = b and result.getNode() = b.getAValue()) and
|
||||||
this.getBasicBlock().dominates(result.getBasicBlock())
|
this.getBasicBlock().dominates(result.getBasicBlock())
|
||||||
}
|
}
|
||||||
|
|
||||||
override BoolExpr getNode() { result = super.getNode() }
|
override Py::BoolExpr getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a unary expression: (`+x`), (`-x`) or (`~x`) */
|
/** A control flow node corresponding to a unary expression: (`+x`), (`-x`) or (`~x`) */
|
||||||
class UnaryExprNode extends ControlFlowNode {
|
class UnaryExprNode extends ControlFlowNode {
|
||||||
UnaryExprNode() { toAst(this) instanceof UnaryExpr }
|
UnaryExprNode() { toAst(this) instanceof Py::UnaryExpr }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets flow node corresponding to the operand of a unary expression.
|
* Gets flow node corresponding to the operand of a unary expression.
|
||||||
@@ -540,7 +540,7 @@ class UnaryExprNode extends ControlFlowNode {
|
|||||||
*/
|
*/
|
||||||
ControlFlowNode getOperand() { result = this.getAPredecessor() }
|
ControlFlowNode getOperand() { result = this.getAPredecessor() }
|
||||||
|
|
||||||
override UnaryExpr getNode() { result = super.getNode() }
|
override Py::UnaryExpr getNode() { result = super.getNode() }
|
||||||
|
|
||||||
override ControlFlowNode getAChild() { result = this.getAPredecessor() }
|
override ControlFlowNode getAChild() { result = this.getAPredecessor() }
|
||||||
}
|
}
|
||||||
@@ -555,27 +555,27 @@ class DefinitionNode extends ControlFlowNode {
|
|||||||
cached
|
cached
|
||||||
DefinitionNode() {
|
DefinitionNode() {
|
||||||
Stages::AST::ref() and
|
Stages::AST::ref() and
|
||||||
exists(Assign a | a.getATarget().getAFlowNode() = this)
|
exists(Py::Assign a | this.getNode() = a.getATarget())
|
||||||
or
|
or
|
||||||
exists(AssignExpr a | a.getTarget().getAFlowNode() = this)
|
exists(Py::AssignExpr a | this.getNode() = a.getTarget())
|
||||||
or
|
or
|
||||||
exists(AnnAssign a | a.getTarget().getAFlowNode() = this and exists(a.getValue()))
|
exists(Py::AnnAssign a | this.getNode() = a.getTarget() and exists(a.getValue()))
|
||||||
or
|
or
|
||||||
exists(Alias a | a.getAsname().getAFlowNode() = this)
|
exists(Py::Alias a | this.getNode() = a.getAsname())
|
||||||
or
|
or
|
||||||
augstore(_, this)
|
augstore(_, this)
|
||||||
or
|
or
|
||||||
// `x, y = 1, 2` where LHS is a combination of list or tuples
|
// `x, y = 1, 2` where LHS is a combination of list or tuples
|
||||||
exists(Assign a | list_or_tuple_nested_element(a.getATarget()).getAFlowNode() = this)
|
exists(Py::Assign a | this.getNode() = list_or_tuple_nested_element(a.getATarget()))
|
||||||
or
|
or
|
||||||
exists(For for | for.getTarget().getAFlowNode() = this)
|
exists(Py::For for | this.getNode() = for.getTarget())
|
||||||
or
|
or
|
||||||
exists(Parameter param | this = param.asName().getAFlowNode() and exists(param.getDefault()))
|
exists(Py::Parameter param | this.getNode() = param.asName() and exists(param.getDefault()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** flow node corresponding to the value assigned for the definition corresponding to this flow node */
|
/** flow node corresponding to the value assigned for the definition corresponding to this flow node */
|
||||||
ControlFlowNode getValue() {
|
ControlFlowNode getValue() {
|
||||||
result = assigned_value(this.getNode()).getAFlowNode() and
|
result.getNode() = assigned_value(this.getNode()) and
|
||||||
(
|
(
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
or
|
or
|
||||||
@@ -584,16 +584,16 @@ class DefinitionNode extends ControlFlowNode {
|
|||||||
// since the default value for a parameter is evaluated in the same basic block as
|
// since the default value for a parameter is evaluated in the same basic block as
|
||||||
// the function definition, but the parameter belongs to the basic block of the function,
|
// the function definition, but the parameter belongs to the basic block of the function,
|
||||||
// there is no dominance relationship between the two.
|
// there is no dominance relationship between the two.
|
||||||
exists(Parameter param | this = param.asName().getAFlowNode())
|
exists(Py::Parameter param | this.getNode() = param.asName())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expr list_or_tuple_nested_element(Expr list_or_tuple) {
|
private Py::Expr list_or_tuple_nested_element(Py::Expr list_or_tuple) {
|
||||||
exists(Expr elt |
|
exists(Py::Expr elt |
|
||||||
elt = list_or_tuple.(Tuple).getAnElt()
|
elt = list_or_tuple.(Py::Tuple).getAnElt()
|
||||||
or
|
or
|
||||||
elt = list_or_tuple.(List).getAnElt()
|
elt = list_or_tuple.(Py::List).getAnElt()
|
||||||
|
|
|
|
||||||
result = elt
|
result = elt
|
||||||
or
|
or
|
||||||
@@ -603,12 +603,12 @@ private Expr list_or_tuple_nested_element(Expr list_or_tuple) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A control flow node corresponding to a deletion statement, such as `del x`.
|
* A control flow node corresponding to a deletion statement, such as `del x`.
|
||||||
* There can be multiple `DeletionNode`s for each `Delete` such that each
|
* There can be multiple `DeletionNode`s for each `Py::Delete` such that each
|
||||||
* target has own `DeletionNode`. The CFG for `del a, x.y` looks like:
|
* target has own `DeletionNode`. The CFG for `del a, x.y` looks like:
|
||||||
* `NameNode('a') -> DeletionNode -> NameNode('b') -> AttrNode('y') -> DeletionNode`.
|
* `NameNode('a') -> DeletionNode -> NameNode('b') -> AttrNode('y') -> DeletionNode`.
|
||||||
*/
|
*/
|
||||||
class DeletionNode extends ControlFlowNode {
|
class DeletionNode extends ControlFlowNode {
|
||||||
DeletionNode() { toAst(this) instanceof Delete }
|
DeletionNode() { toAst(this) instanceof Py::Delete }
|
||||||
|
|
||||||
/** Gets the unique target of this deletion node. */
|
/** Gets the unique target of this deletion node. */
|
||||||
ControlFlowNode getTarget() { result.getASuccessor() = this }
|
ControlFlowNode getTarget() { result.getASuccessor() = this }
|
||||||
@@ -617,9 +617,9 @@ class DeletionNode extends ControlFlowNode {
|
|||||||
/** A control flow node corresponding to a sequence (tuple or list) literal */
|
/** A control flow node corresponding to a sequence (tuple or list) literal */
|
||||||
abstract class SequenceNode extends ControlFlowNode {
|
abstract class SequenceNode extends ControlFlowNode {
|
||||||
SequenceNode() {
|
SequenceNode() {
|
||||||
toAst(this) instanceof Tuple
|
toAst(this) instanceof Py::Tuple
|
||||||
or
|
or
|
||||||
toAst(this) instanceof List
|
toAst(this) instanceof Py::List
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the control flow node for an element of this sequence */
|
/** Gets the control flow node for an element of this sequence */
|
||||||
@@ -632,11 +632,11 @@ abstract class SequenceNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** A control flow node corresponding to a tuple expression such as `( 1, 3, 5, 7, 9 )` */
|
/** A control flow node corresponding to a tuple expression such as `( 1, 3, 5, 7, 9 )` */
|
||||||
class TupleNode extends SequenceNode {
|
class TupleNode extends SequenceNode {
|
||||||
TupleNode() { toAst(this) instanceof Tuple }
|
TupleNode() { toAst(this) instanceof Py::Tuple }
|
||||||
|
|
||||||
override ControlFlowNode getElement(int n) {
|
override ControlFlowNode getElement(int n) {
|
||||||
Stages::AST::ref() and
|
Stages::AST::ref() and
|
||||||
exists(Tuple t | this.getNode() = t and result.getNode() = t.getElt(n)) and
|
exists(Py::Tuple t | this.getNode() = t and result.getNode() = t.getElt(n)) and
|
||||||
(
|
(
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
or
|
or
|
||||||
@@ -647,10 +647,10 @@ class TupleNode extends SequenceNode {
|
|||||||
|
|
||||||
/** A control flow node corresponding to a list expression, such as `[ 1, 3, 5, 7, 9 ]` */
|
/** A control flow node corresponding to a list expression, such as `[ 1, 3, 5, 7, 9 ]` */
|
||||||
class ListNode extends SequenceNode {
|
class ListNode extends SequenceNode {
|
||||||
ListNode() { toAst(this) instanceof List }
|
ListNode() { toAst(this) instanceof Py::List }
|
||||||
|
|
||||||
override ControlFlowNode getElement(int n) {
|
override ControlFlowNode getElement(int n) {
|
||||||
exists(List l | this.getNode() = l and result.getNode() = l.getElt(n)) and
|
exists(Py::List l | this.getNode() = l and result.getNode() = l.getElt(n)) and
|
||||||
(
|
(
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
or
|
or
|
||||||
@@ -661,10 +661,10 @@ class ListNode extends SequenceNode {
|
|||||||
|
|
||||||
/** A control flow node corresponding to a set expression, such as `{ 1, 3, 5, 7, 9 }` */
|
/** A control flow node corresponding to a set expression, such as `{ 1, 3, 5, 7, 9 }` */
|
||||||
class SetNode extends ControlFlowNode {
|
class SetNode extends ControlFlowNode {
|
||||||
SetNode() { toAst(this) instanceof Set }
|
SetNode() { toAst(this) instanceof Py::Set }
|
||||||
|
|
||||||
ControlFlowNode getAnElement() {
|
ControlFlowNode getAnElement() {
|
||||||
exists(Set s | this.getNode() = s and result.getNode() = s.getElt(_)) and
|
exists(Py::Set s | this.getNode() = s and result.getNode() = s.getElt(_)) and
|
||||||
(
|
(
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
or
|
or
|
||||||
@@ -675,20 +675,20 @@ class SetNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** A control flow node corresponding to a dictionary literal, such as `{ 'a': 1, 'b': 2 }` */
|
/** A control flow node corresponding to a dictionary literal, such as `{ 'a': 1, 'b': 2 }` */
|
||||||
class DictNode extends ControlFlowNode {
|
class DictNode extends ControlFlowNode {
|
||||||
DictNode() { toAst(this) instanceof Dict }
|
DictNode() { toAst(this) instanceof Py::Dict }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a key of this dictionary literal node, for those items that have keys
|
* Gets a key of this dictionary literal node, for those items that have keys
|
||||||
* E.g, in {'a':1, **b} this returns only 'a'
|
* E.g, in {'a':1, **b} this returns only 'a'
|
||||||
*/
|
*/
|
||||||
ControlFlowNode getAKey() {
|
ControlFlowNode getAKey() {
|
||||||
exists(Dict d | this.getNode() = d and result.getNode() = d.getAKey()) and
|
exists(Py::Dict d | this.getNode() = d and result.getNode() = d.getAKey()) and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets a value of this dictionary literal node */
|
/** Gets a value of this dictionary literal node */
|
||||||
ControlFlowNode getAValue() {
|
ControlFlowNode getAValue() {
|
||||||
exists(Dict d | this.getNode() = d and result.getNode() = d.getAValue()) and
|
exists(Py::Dict d | this.getNode() = d and result.getNode() = d.getAValue()) and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -712,21 +712,23 @@ class IterableNode extends ControlFlowNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private AstNode assigned_value(Expr lhs) {
|
private Py::AstNode assigned_value(Py::Expr lhs) {
|
||||||
/* lhs = result */
|
/* lhs = result */
|
||||||
exists(Assign a | a.getATarget() = lhs and result = a.getValue())
|
exists(Py::Assign a | a.getATarget() = lhs and result = a.getValue())
|
||||||
or
|
or
|
||||||
/* lhs := result */
|
/* lhs := result */
|
||||||
exists(AssignExpr a | a.getTarget() = lhs and result = a.getValue())
|
exists(Py::AssignExpr a | a.getTarget() = lhs and result = a.getValue())
|
||||||
or
|
or
|
||||||
/* lhs : annotation = result */
|
/* lhs : annotation = result */
|
||||||
exists(AnnAssign a | a.getTarget() = lhs and result = a.getValue())
|
exists(Py::AnnAssign a | a.getTarget() = lhs and result = a.getValue())
|
||||||
or
|
or
|
||||||
/* import result as lhs */
|
/* import result as lhs */
|
||||||
exists(Alias a | a.getAsname() = lhs and result = a.getValue())
|
exists(Py::Alias a | a.getAsname() = lhs and result = a.getValue())
|
||||||
or
|
or
|
||||||
/* lhs += x => result = (lhs + x) */
|
/* lhs += x => result = (lhs + x) */
|
||||||
exists(AugAssign a, BinaryExpr b | b = a.getOperation() and result = b and lhs = b.getLeft())
|
exists(Py::AugAssign a, Py::BinaryExpr b |
|
||||||
|
b = a.getOperation() and result = b and lhs = b.getLeft()
|
||||||
|
)
|
||||||
or
|
or
|
||||||
/*
|
/*
|
||||||
* ..., lhs, ... = ..., result, ...
|
* ..., lhs, ... = ..., result, ...
|
||||||
@@ -734,31 +736,31 @@ private AstNode assigned_value(Expr lhs) {
|
|||||||
* ..., (..., lhs, ...), ... = ..., (..., result, ...), ...
|
* ..., (..., lhs, ...), ... = ..., (..., result, ...), ...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exists(Assign a | nested_sequence_assign(a.getATarget(), a.getValue(), lhs, result))
|
exists(Py::Assign a | nested_sequence_assign(a.getATarget(), a.getValue(), lhs, result))
|
||||||
or
|
or
|
||||||
/* for lhs in seq: => `result` is the `for` node, representing the `iter(next(seq))` operation. */
|
/* for lhs in seq: => `result` is the `for` node, representing the `iter(next(seq))` operation. */
|
||||||
result.(For).getTarget() = lhs
|
result.(Py::For).getTarget() = lhs
|
||||||
or
|
or
|
||||||
exists(Parameter param | lhs = param.asName() and result = param.getDefault())
|
exists(Py::Parameter param | lhs = param.asName() and result = param.getDefault())
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate nested_sequence_assign(
|
predicate nested_sequence_assign(
|
||||||
Expr left_parent, Expr right_parent, Expr left_result, Expr right_result
|
Py::Expr left_parent, Py::Expr right_parent, Py::Expr left_result, Py::Expr right_result
|
||||||
) {
|
) {
|
||||||
exists(Assign a |
|
exists(Py::Assign a |
|
||||||
a.getATarget().getASubExpression*() = left_parent and
|
a.getATarget().getASubExpression*() = left_parent and
|
||||||
a.getValue().getASubExpression*() = right_parent
|
a.getValue().getASubExpression*() = right_parent
|
||||||
) and
|
) and
|
||||||
exists(int i, Expr left_elem, Expr right_elem |
|
exists(int i, Py::Expr left_elem, Py::Expr right_elem |
|
||||||
(
|
(
|
||||||
left_elem = left_parent.(Tuple).getElt(i)
|
left_elem = left_parent.(Py::Tuple).getElt(i)
|
||||||
or
|
or
|
||||||
left_elem = left_parent.(List).getElt(i)
|
left_elem = left_parent.(Py::List).getElt(i)
|
||||||
) and
|
) and
|
||||||
(
|
(
|
||||||
right_elem = right_parent.(Tuple).getElt(i)
|
right_elem = right_parent.(Py::Tuple).getElt(i)
|
||||||
or
|
or
|
||||||
right_elem = right_parent.(List).getElt(i)
|
right_elem = right_parent.(Py::List).getElt(i)
|
||||||
)
|
)
|
||||||
|
|
|
|
||||||
left_result = left_elem and right_result = right_elem
|
left_result = left_elem and right_result = right_elem
|
||||||
@@ -769,9 +771,9 @@ predicate nested_sequence_assign(
|
|||||||
|
|
||||||
/** A flow node for a `for` statement. */
|
/** A flow node for a `for` statement. */
|
||||||
class ForNode extends ControlFlowNode {
|
class ForNode extends ControlFlowNode {
|
||||||
ForNode() { toAst(this) instanceof For }
|
ForNode() { toAst(this) instanceof Py::For }
|
||||||
|
|
||||||
override For getNode() { result = super.getNode() }
|
override Py::For getNode() { result = super.getNode() }
|
||||||
|
|
||||||
/** Holds if this `for` statement causes iteration over `sequence` storing each step of the iteration in `target` */
|
/** Holds if this `for` statement causes iteration over `sequence` storing each step of the iteration in `target` */
|
||||||
predicate iterates(ControlFlowNode target, ControlFlowNode sequence) {
|
predicate iterates(ControlFlowNode target, ControlFlowNode sequence) {
|
||||||
@@ -782,7 +784,7 @@ class ForNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** Gets the sequence node for this `for` statement. */
|
/** Gets the sequence node for this `for` statement. */
|
||||||
ControlFlowNode getSequence() {
|
ControlFlowNode getSequence() {
|
||||||
exists(For for |
|
exists(Py::For for |
|
||||||
toAst(this) = for and
|
toAst(this) = for and
|
||||||
for.getIter() = result.getNode()
|
for.getIter() = result.getNode()
|
||||||
|
|
|
|
||||||
@@ -792,7 +794,7 @@ class ForNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** A possible `target` for this `for` statement, not accounting for loop unrolling */
|
/** A possible `target` for this `for` statement, not accounting for loop unrolling */
|
||||||
private ControlFlowNode possibleTarget() {
|
private ControlFlowNode possibleTarget() {
|
||||||
exists(For for |
|
exists(Py::For for |
|
||||||
toAst(this) = for and
|
toAst(this) = for and
|
||||||
for.getTarget() = result.getNode() and
|
for.getTarget() = result.getNode() and
|
||||||
this.getBasicBlock().dominates(result.getBasicBlock())
|
this.getBasicBlock().dominates(result.getBasicBlock())
|
||||||
@@ -809,11 +811,11 @@ class ForNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** A flow node for a `raise` statement */
|
/** A flow node for a `raise` statement */
|
||||||
class RaiseStmtNode extends ControlFlowNode {
|
class RaiseStmtNode extends ControlFlowNode {
|
||||||
RaiseStmtNode() { toAst(this) instanceof Raise }
|
RaiseStmtNode() { toAst(this) instanceof Py::Raise }
|
||||||
|
|
||||||
/** Gets the control flow node for the exception raised by this raise statement */
|
/** Gets the control flow node for the exception raised by this raise statement */
|
||||||
ControlFlowNode getException() {
|
ControlFlowNode getException() {
|
||||||
exists(Raise r |
|
exists(Py::Raise r |
|
||||||
r = toAst(this) and
|
r = toAst(this) and
|
||||||
r.getException() = toAst(result) and
|
r.getException() = toAst(result) and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
@@ -827,36 +829,36 @@ class RaiseStmtNode extends ControlFlowNode {
|
|||||||
*/
|
*/
|
||||||
class NameNode extends ControlFlowNode {
|
class NameNode extends ControlFlowNode {
|
||||||
NameNode() {
|
NameNode() {
|
||||||
exists(Name n | py_flow_bb_node(this, n, _, _))
|
exists(Py::Name n | py_flow_bb_node(this, n, _, _))
|
||||||
or
|
or
|
||||||
exists(PlaceHolder p | py_flow_bb_node(this, p, _, _))
|
exists(Py::PlaceHolder p | py_flow_bb_node(this, p, _, _))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether this flow node defines the variable `v`. */
|
/** Whether this flow node defines the variable `v`. */
|
||||||
predicate defines(Variable v) {
|
predicate defines(Py::Variable v) {
|
||||||
exists(Name d | this.getNode() = d and d.defines(v)) and
|
exists(Py::Name d | this.getNode() = d and d.defines(v)) and
|
||||||
not this.isLoad()
|
not this.isLoad()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether this flow node deletes the variable `v`. */
|
/** Whether this flow node deletes the variable `v`. */
|
||||||
predicate deletes(Variable v) { exists(Name d | this.getNode() = d and d.deletes(v)) }
|
predicate deletes(Py::Variable v) { exists(Py::Name d | this.getNode() = d and d.deletes(v)) }
|
||||||
|
|
||||||
/** Whether this flow node uses the variable `v`. */
|
/** Whether this flow node uses the variable `v`. */
|
||||||
predicate uses(Variable v) {
|
predicate uses(Py::Variable v) {
|
||||||
this.isLoad() and
|
this.isLoad() and
|
||||||
exists(Name u | this.getNode() = u and u.uses(v))
|
exists(Py::Name u | this.getNode() = u and u.uses(v))
|
||||||
or
|
or
|
||||||
exists(PlaceHolder u |
|
exists(Py::PlaceHolder u |
|
||||||
this.getNode() = u and u.getVariable() = v and u.getCtx() instanceof Load
|
this.getNode() = u and u.getVariable() = v and u.getCtx() instanceof Py::Load
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
Scopes::use_of_global_variable(this, v.getScope(), v.getId())
|
Scopes::use_of_global_variable(this, v.getScope(), v.getId())
|
||||||
}
|
}
|
||||||
|
|
||||||
string getId() {
|
string getId() {
|
||||||
result = this.getNode().(Name).getId()
|
result = this.getNode().(Py::Name).getId()
|
||||||
or
|
or
|
||||||
result = this.getNode().(PlaceHolder).getId()
|
result = this.getNode().(Py::PlaceHolder).getId()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether this is a use of a local variable. */
|
/** Whether this is a use of a local variable. */
|
||||||
@@ -868,82 +870,84 @@ class NameNode extends ControlFlowNode {
|
|||||||
/** Whether this is a use of a global (including builtin) variable. */
|
/** Whether this is a use of a global (including builtin) variable. */
|
||||||
predicate isGlobal() { Scopes::use_of_global_variable(this, _, _) }
|
predicate isGlobal() { Scopes::use_of_global_variable(this, _, _) }
|
||||||
|
|
||||||
predicate isSelf() { exists(SsaVariable selfvar | selfvar.isSelf() and selfvar.getAUse() = this) }
|
predicate isSelf() {
|
||||||
|
exists(Py::SsaVariable selfvar | selfvar.isSelf() and selfvar.getAUse() = this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a named constant, one of `None`, `True` or `False`. */
|
/** A control flow node corresponding to a named constant, one of `None`, `True` or `False`. */
|
||||||
class NameConstantNode extends NameNode {
|
class NameConstantNode extends NameNode {
|
||||||
NameConstantNode() { exists(NameConstant n | py_flow_bb_node(this, n, _, _)) }
|
NameConstantNode() { exists(Py::NameConstant n | py_flow_bb_node(this, n, _, _)) }
|
||||||
/*
|
/*
|
||||||
* We ought to override uses as well, but that has
|
* We ought to override uses as well, but that has
|
||||||
* a serious performance impact.
|
* a serious performance impact.
|
||||||
* deprecated predicate uses(Variable v) { none() }
|
* deprecated predicate uses(Py::Variable v) { none() }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a starred expression, `*a`. */
|
/** A control flow node corresponding to a starred expression, `*a`. */
|
||||||
class StarredNode extends ControlFlowNode {
|
class StarredNode extends ControlFlowNode {
|
||||||
StarredNode() { toAst(this) instanceof Starred }
|
StarredNode() { toAst(this) instanceof Py::Starred }
|
||||||
|
|
||||||
ControlFlowNode getValue() { toAst(result) = toAst(this).(Starred).getValue() }
|
ControlFlowNode getValue() { toAst(result) = toAst(this).(Py::Starred).getValue() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The ControlFlowNode for an 'except' statement. */
|
/** The ControlFlowNode for an 'except' statement. */
|
||||||
class ExceptFlowNode extends ControlFlowNode {
|
class ExceptFlowNode extends ControlFlowNode {
|
||||||
ExceptFlowNode() { this.getNode() instanceof ExceptStmt }
|
ExceptFlowNode() { this.getNode() instanceof Py::ExceptStmt }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the type handled by this exception handler.
|
* Gets the type handled by this exception handler.
|
||||||
* `ExceptionType` in `except ExceptionType as e:`
|
* `Py::ExceptionType` in `except Py::ExceptionType as e:`
|
||||||
*/
|
*/
|
||||||
ControlFlowNode getType() {
|
ControlFlowNode getType() {
|
||||||
exists(ExceptStmt ex |
|
exists(Py::ExceptStmt ex |
|
||||||
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
||||||
ex = this.getNode() and
|
ex = this.getNode() and
|
||||||
result = ex.getType().getAFlowNode()
|
result.getNode() = ex.getType()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the name assigned to the handled exception, if any.
|
* Gets the name assigned to the handled exception, if any.
|
||||||
* `e` in `except ExceptionType as e:`
|
* `e` in `except Py::ExceptionType as e:`
|
||||||
*/
|
*/
|
||||||
ControlFlowNode getName() {
|
ControlFlowNode getName() {
|
||||||
exists(ExceptStmt ex |
|
exists(Py::ExceptStmt ex |
|
||||||
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
||||||
ex = this.getNode() and
|
ex = this.getNode() and
|
||||||
result = ex.getName().getAFlowNode()
|
result.getNode() = ex.getName()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The ControlFlowNode for an 'except*' statement. */
|
/** The ControlFlowNode for an 'except*' statement. */
|
||||||
class ExceptGroupFlowNode extends ControlFlowNode {
|
class ExceptGroupFlowNode extends ControlFlowNode {
|
||||||
ExceptGroupFlowNode() { this.getNode() instanceof ExceptGroupStmt }
|
ExceptGroupFlowNode() { this.getNode() instanceof Py::ExceptGroupStmt }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the type handled by this exception handler.
|
* Gets the type handled by this exception handler.
|
||||||
* `ExceptionType` in `except* ExceptionType as e:`
|
* `Py::ExceptionType` in `except* Py::ExceptionType as e:`
|
||||||
*/
|
*/
|
||||||
ControlFlowNode getType() {
|
ControlFlowNode getType() {
|
||||||
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
||||||
result = this.getNode().(ExceptGroupStmt).getType().getAFlowNode()
|
result.getNode() = this.getNode().(Py::ExceptGroupStmt).getType()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the name assigned to the handled exception, if any.
|
* Gets the name assigned to the handled exception, if any.
|
||||||
* `e` in `except* ExceptionType as e:`
|
* `e` in `except* Py::ExceptionType as e:`
|
||||||
*/
|
*/
|
||||||
ControlFlowNode getName() {
|
ControlFlowNode getName() {
|
||||||
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
||||||
result = this.getNode().(ExceptGroupStmt).getName().getAFlowNode()
|
result.getNode() = this.getNode().(Py::ExceptGroupStmt).getName()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private module Scopes {
|
private module Scopes {
|
||||||
private predicate fast_local(NameNode n) {
|
private predicate fast_local(NameNode n) {
|
||||||
exists(FastLocalVariable v |
|
exists(Py::FastLocalVariable v |
|
||||||
n.uses(v) and
|
n.uses(v) and
|
||||||
v.getScope() = n.getScope()
|
v.getScope() = n.getScope()
|
||||||
)
|
)
|
||||||
@@ -952,15 +956,15 @@ private module Scopes {
|
|||||||
predicate local(NameNode n) {
|
predicate local(NameNode n) {
|
||||||
fast_local(n)
|
fast_local(n)
|
||||||
or
|
or
|
||||||
exists(SsaVariable var |
|
exists(Py::SsaVariable var |
|
||||||
var.getAUse() = n and
|
var.getAUse() = n and
|
||||||
n.getScope() instanceof Class and
|
n.getScope() instanceof Py::Class and
|
||||||
exists(var.getDefinition())
|
exists(var.getDefinition())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate non_local(NameNode n) {
|
predicate non_local(NameNode n) {
|
||||||
exists(FastLocalVariable flv |
|
exists(Py::FastLocalVariable flv |
|
||||||
flv.getALoad() = n.getNode() and
|
flv.getALoad() = n.getNode() and
|
||||||
not flv.getScope() = n.getScope()
|
not flv.getScope() = n.getScope()
|
||||||
)
|
)
|
||||||
@@ -968,20 +972,20 @@ private module Scopes {
|
|||||||
|
|
||||||
// magic is fine, but we get questionable join-ordering of it
|
// magic is fine, but we get questionable join-ordering of it
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
predicate use_of_global_variable(NameNode n, Module scope, string name) {
|
predicate use_of_global_variable(NameNode n, Py::Module scope, string name) {
|
||||||
n.isLoad() and
|
n.isLoad() and
|
||||||
not non_local(n) and
|
not non_local(n) and
|
||||||
not exists(SsaVariable var | var.getAUse() = n |
|
not exists(Py::SsaVariable var | var.getAUse() = n |
|
||||||
var.getVariable() instanceof FastLocalVariable
|
var.getVariable() instanceof Py::FastLocalVariable
|
||||||
or
|
or
|
||||||
n.getScope() instanceof Class and
|
n.getScope() instanceof Py::Class and
|
||||||
not maybe_undefined(var)
|
not maybe_undefined(var)
|
||||||
) and
|
) and
|
||||||
name = n.getId() and
|
name = n.getId() and
|
||||||
scope = n.getEnclosingModule()
|
scope = n.getEnclosingModule()
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate maybe_undefined(SsaVariable var) {
|
private predicate maybe_undefined(Py::SsaVariable var) {
|
||||||
not exists(var.getDefinition()) and not py_ssa_phi(var, _)
|
not exists(var.getDefinition()) and not py_ssa_phi(var, _)
|
||||||
or
|
or
|
||||||
var.getDefinition().isDelete()
|
var.getDefinition().isDelete()
|
||||||
@@ -1058,13 +1062,13 @@ class BasicBlock extends @py_flow_node {
|
|||||||
private predicate oneNodeBlock() { this.firstNode() = this.getLastNode() }
|
private predicate oneNodeBlock() { this.firstNode() = this.getLastNode() }
|
||||||
|
|
||||||
private predicate startLocationInfo(string file, int line, int col) {
|
private predicate startLocationInfo(string file, int line, int col) {
|
||||||
if this.firstNode().getNode() instanceof Scope
|
if this.firstNode().getNode() instanceof Py::Scope
|
||||||
then this.firstNode().getASuccessor().getLocation().hasLocationInfo(file, line, col, _, _)
|
then this.firstNode().getASuccessor().getLocation().hasLocationInfo(file, line, col, _, _)
|
||||||
else this.firstNode().getLocation().hasLocationInfo(file, line, col, _, _)
|
else this.firstNode().getLocation().hasLocationInfo(file, line, col, _, _)
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate endLocationInfo(int endl, int endc) {
|
private predicate endLocationInfo(int endl, int endc) {
|
||||||
if this.getLastNode().getNode() instanceof Scope and not this.oneNodeBlock()
|
if this.getLastNode().getNode() instanceof Py::Scope and not this.oneNodeBlock()
|
||||||
then this.getLastNode().getAPredecessor().getLocation().hasLocationInfo(_, _, _, endl, endc)
|
then this.getLastNode().getAPredecessor().getLocation().hasLocationInfo(_, _, _, endl, endc)
|
||||||
else this.getLastNode().getLocation().hasLocationInfo(_, _, _, endl, endc)
|
else this.getLastNode().getLocation().hasLocationInfo(_, _, _, endl, endc)
|
||||||
}
|
}
|
||||||
@@ -1081,7 +1085,7 @@ class BasicBlock extends @py_flow_node {
|
|||||||
|
|
||||||
/** Whether flow from this basic block reaches a normal exit from its scope */
|
/** Whether flow from this basic block reaches a normal exit from its scope */
|
||||||
predicate reachesExit() {
|
predicate reachesExit() {
|
||||||
exists(Scope s | s.getANormalExit().getBasicBlock() = this)
|
exists(Py::Scope s | s.getANormalExit().getBasicBlock() = this)
|
||||||
or
|
or
|
||||||
this.getASuccessor().reachesExit()
|
this.getASuccessor().reachesExit()
|
||||||
}
|
}
|
||||||
@@ -1122,7 +1126,7 @@ class BasicBlock extends @py_flow_node {
|
|||||||
|
|
||||||
/** Gets the scope of this block */
|
/** Gets the scope of this block */
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
Scope getScope() {
|
Py::Scope getScope() {
|
||||||
exists(ControlFlowNode n | n.getBasicBlock() = this |
|
exists(ControlFlowNode n | n.getBasicBlock() = this |
|
||||||
/* Take care not to use an entry or exit node as that node's scope will be the outer scope */
|
/* Take care not to use an entry or exit node as that node's scope will be the outer scope */
|
||||||
not py_scope_flow(n, _, -1) and
|
not py_scope_flow(n, _, -1) and
|
||||||
@@ -1145,17 +1149,17 @@ class BasicBlock extends @py_flow_node {
|
|||||||
predicate reaches(BasicBlock other) { this = other or this.strictlyReaches(other) }
|
predicate reaches(BasicBlock other) { this = other or this.strictlyReaches(other) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the `ConditionBlock`, if any, that controls this block and
|
* Gets the `Py::ConditionBlock`, if any, that controls this block and
|
||||||
* does not control any other `ConditionBlock`s that control this block.
|
* does not control any other `Py::ConditionBlock`s that control this block.
|
||||||
* That is the `ConditionBlock` that is closest dominator.
|
* That is the `Py::ConditionBlock` that is closest dominator.
|
||||||
*/
|
*/
|
||||||
ConditionBlock getImmediatelyControllingBlock() {
|
Py::ConditionBlock getImmediatelyControllingBlock() {
|
||||||
result = this.nonControllingImmediateDominator*().getImmediateDominator()
|
result = this.nonControllingImmediateDominator*().getImmediateDominator()
|
||||||
}
|
}
|
||||||
|
|
||||||
private BasicBlock nonControllingImmediateDominator() {
|
private BasicBlock nonControllingImmediateDominator() {
|
||||||
result = this.getImmediateDominator() and
|
result = this.getImmediateDominator() and
|
||||||
not result.(ConditionBlock).controls(this, _)
|
not result.(Py::ConditionBlock).controls(this, _)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1175,7 +1179,7 @@ private class ControlFlowNodeAlias = ControlFlowNode;
|
|||||||
|
|
||||||
final private class FinalBasicBlock = BasicBlock;
|
final private class FinalBasicBlock = BasicBlock;
|
||||||
|
|
||||||
module Cfg implements BB::CfgSig<Location> {
|
module Cfg implements BB::CfgSig<Py::Location> {
|
||||||
private import codeql.controlflow.SuccessorType
|
private import codeql.controlflow.SuccessorType
|
||||||
|
|
||||||
class ControlFlowNode = ControlFlowNodeAlias;
|
class ControlFlowNode = ControlFlowNodeAlias;
|
||||||
@@ -1186,7 +1190,7 @@ module Cfg implements BB::CfgSig<Location> {
|
|||||||
// Using the location of the first node is simple
|
// Using the location of the first node is simple
|
||||||
// and we just need a way to identify the basic block
|
// and we just need a way to identify the basic block
|
||||||
// during debugging, so this will be serviceable.
|
// during debugging, so this will be serviceable.
|
||||||
Location getLocation() { result = super.getNode(0).getLocation() }
|
Py::Location getLocation() { result = super.getNode(0).getLocation() }
|
||||||
|
|
||||||
int length() { result = count(int i | exists(this.getNode(i))) }
|
int length() { result = count(int i | exists(this.getNode(i))) }
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ overlay[local]
|
|||||||
module;
|
module;
|
||||||
|
|
||||||
import python
|
import python
|
||||||
|
private import semmle.python.controlflow.internal.Cfg as Cfg
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A function, independent of defaults and binding.
|
* A function, independent of defaults and binding.
|
||||||
@@ -153,8 +154,16 @@ class Function extends Function_, Scope, AstNode {
|
|||||||
|
|
||||||
override predicate contains(AstNode inner) { Scope.super.contains(inner) }
|
override predicate contains(AstNode inner) { Scope.super.contains(inner) }
|
||||||
|
|
||||||
/** Gets a control flow node for a return value of this function */
|
/**
|
||||||
ControlFlowNode getAReturnValueFlowNode() {
|
* DEPRECATED: bind a `Return` node explicitly instead, e.g.
|
||||||
|
* `exists(Return ret | ret.getScope() = this and n.getNode() = ret.getValue())`.
|
||||||
|
* This API is being phased out together with `AstNode.getAFlowNode()` to
|
||||||
|
* untangle the AST and CFG hierarchies.
|
||||||
|
*
|
||||||
|
* Gets a control flow node for a return value of this function, from the
|
||||||
|
* new (shared) CFG.
|
||||||
|
*/
|
||||||
|
deprecated Cfg::ControlFlowNode getAReturnValueFlowNode() {
|
||||||
exists(Return ret |
|
exists(Return ret |
|
||||||
ret.getScope() = this and
|
ret.getScope() = this and
|
||||||
ret.getValue() = result.getNode()
|
ret.getValue() = result.getNode()
|
||||||
|
|||||||
@@ -162,8 +162,6 @@ class ImportMember extends ImportMember_ {
|
|||||||
string getImportedModuleName() {
|
string getImportedModuleName() {
|
||||||
result = this.getModule().(ImportExpr).getImportedModuleName() + "." + this.getName()
|
result = this.getModule().(ImportExpr).getImportedModuleName() + "." + this.getName()
|
||||||
}
|
}
|
||||||
|
|
||||||
override ImportMemberNode getAFlowNode() { result = super.getAFlowNode() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An import statement */
|
/** An import statement */
|
||||||
|
|||||||
@@ -46,20 +46,23 @@ class SelfAttributeRead extends SelfAttribute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
predicate guardedByHasattr() {
|
predicate guardedByHasattr() {
|
||||||
exists(Variable var, ControlFlowNode n |
|
exists(Variable var, ControlFlowNode n, ControlFlowNode this_, ControlFlowNode obj_ |
|
||||||
var.getAUse() = this.getObject().getAFlowNode() and
|
this_.getNode() = this and obj_.getNode() = this.getObject()
|
||||||
|
|
|
||||||
|
var.getAUse() = obj_ and
|
||||||
hasattr(n, var.getAUse(), this.getName()) and
|
hasattr(n, var.getAUse(), this.getName()) and
|
||||||
n.strictlyDominates(this.getAFlowNode())
|
n.strictlyDominates(this_)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma[noinline]
|
pragma[noinline]
|
||||||
predicate locallyDefined() {
|
predicate locallyDefined() {
|
||||||
exists(SelfAttributeStore store |
|
exists(SelfAttributeStore store, ControlFlowNode store_, ControlFlowNode this_ |
|
||||||
this.getName() = store.getName() and
|
store_.getNode() = store and this_.getNode() = this
|
||||||
this.getScope() = store.getScope()
|
|
||||||
|
|
|
|
||||||
store.getAFlowNode().strictlyDominates(this.getAFlowNode())
|
this.getName() = store.getName() and
|
||||||
|
this.getScope() = store.getScope() and
|
||||||
|
store_.strictlyDominates(this_)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1688
python/ql/lib/semmle/python/controlflow/internal/AstNodeImpl.qll
Normal file
1688
python/ql/lib/semmle/python/controlflow/internal/AstNodeImpl.qll
Normal file
File diff suppressed because it is too large
Load Diff
1163
python/ql/lib/semmle/python/controlflow/internal/Cfg.qll
Normal file
1163
python/ql/lib/semmle/python/controlflow/internal/Cfg.qll
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,36 +1,43 @@
|
|||||||
/** Provides commonly used BarrierGuards. */
|
/** Provides commonly used BarrierGuards. */
|
||||||
|
|
||||||
private import python
|
private import python
|
||||||
|
private import semmle.python.controlflow.internal.Cfg as Cfg
|
||||||
private import semmle.python.dataflow.new.DataFlow
|
private import semmle.python.dataflow.new.DataFlow
|
||||||
|
|
||||||
private predicate constCompare(DataFlow::GuardNode g, ControlFlowNode node, boolean branch) {
|
private predicate constCompare(DataFlow::GuardNode g, Cfg::ControlFlowNode node, boolean branch) {
|
||||||
exists(CompareNode cn | cn = g |
|
exists(Cfg::CompareNode cn | cn = g |
|
||||||
exists(ImmutableLiteral const, Cmpop op |
|
exists(ImmutableLiteral const, Cmpop op, Cfg::ControlFlowNode c |
|
||||||
|
c.getNode() = const and
|
||||||
|
(
|
||||||
op = any(Eq eq) and branch = true
|
op = any(Eq eq) and branch = true
|
||||||
or
|
or
|
||||||
op = any(NotEq ne) and branch = false
|
op = any(NotEq ne) and branch = false
|
||||||
|
)
|
||||||
|
|
|
|
||||||
cn.operands(const.getAFlowNode(), op, node)
|
cn.operands(c, op, node)
|
||||||
or
|
or
|
||||||
cn.operands(node, op, const.getAFlowNode())
|
cn.operands(node, op, c)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(NameConstant const, Cmpop op |
|
exists(NameConstant const, Cmpop op, Cfg::ControlFlowNode c |
|
||||||
|
c.getNode() = const and
|
||||||
|
(
|
||||||
op = any(Is is_) and branch = true
|
op = any(Is is_) and branch = true
|
||||||
or
|
or
|
||||||
op = any(IsNot isn) and branch = false
|
op = any(IsNot isn) and branch = false
|
||||||
|
)
|
||||||
|
|
|
|
||||||
cn.operands(const.getAFlowNode(), op, node)
|
cn.operands(c, op, node)
|
||||||
or
|
or
|
||||||
cn.operands(node, op, const.getAFlowNode())
|
cn.operands(node, op, c)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(IterableNode const_iterable, Cmpop op |
|
exists(Cfg::IterableNode const_iterable, Cmpop op |
|
||||||
op = any(In in_) and branch = true
|
op = any(In in_) and branch = true
|
||||||
or
|
or
|
||||||
op = any(NotIn ni) and branch = false
|
op = any(NotIn ni) and branch = false
|
||||||
|
|
|
|
||||||
forall(ControlFlowNode elem | elem = const_iterable.getAnElement() |
|
forall(Cfg::ControlFlowNode elem | elem = const_iterable.getAnElement() |
|
||||||
elem.getNode() instanceof ImmutableLiteral
|
elem.getNode() instanceof ImmutableLiteral
|
||||||
) and
|
) and
|
||||||
cn.operands(node, op, const_iterable)
|
cn.operands(node, op, const_iterable)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
private import python
|
private import python
|
||||||
|
private import semmle.python.controlflow.internal.Cfg as Cfg
|
||||||
private import semmle.python.dataflow.new.DataFlow
|
private import semmle.python.dataflow.new.DataFlow
|
||||||
// Need to import `semmle.python.Frameworks` since frameworks can extend `SensitiveDataSource::Range`
|
// Need to import `semmle.python.Frameworks` since frameworks can extend `SensitiveDataSource::Range`
|
||||||
private import semmle.python.Frameworks
|
private import semmle.python.Frameworks
|
||||||
@@ -105,7 +106,7 @@ private module SensitiveDataModeling {
|
|||||||
or
|
or
|
||||||
// to cover functions that we don't have the definition for, and where the
|
// to cover functions that we don't have the definition for, and where the
|
||||||
// reference to the function has not already been marked as being sensitive
|
// reference to the function has not already been marked as being sensitive
|
||||||
this.getFunction().asCfgNode().(NameNode).getId() = sensitiveString(classification)
|
this.getFunction().asCfgNode().(Cfg::NameNode).getId() = sensitiveString(classification)
|
||||||
}
|
}
|
||||||
|
|
||||||
override SensitiveDataClassification getClassification() { result = classification }
|
override SensitiveDataClassification getClassification() { result = classification }
|
||||||
@@ -251,12 +252,12 @@ private module SensitiveDataModeling {
|
|||||||
SensitiveDataClassification classification;
|
SensitiveDataClassification classification;
|
||||||
|
|
||||||
SensitiveVariableAssignment() {
|
SensitiveVariableAssignment() {
|
||||||
exists(DefinitionNode def |
|
exists(Cfg::DefinitionNode def |
|
||||||
def.(NameNode).getId() = sensitiveString(classification) and
|
def.(Cfg::NameNode).getId() = sensitiveString(classification) and
|
||||||
(
|
(
|
||||||
this.asCfgNode() = def.getValue()
|
this.asCfgNode() = def.getValue()
|
||||||
or
|
or
|
||||||
this.asCfgNode() = def.getValue().(ForNode).getSequence()
|
this.asCfgNode() = def.getValue().(Cfg::ForNode).getSequence()
|
||||||
) and
|
) and
|
||||||
not this.asExpr() instanceof FunctionExpr and
|
not this.asExpr() instanceof FunctionExpr and
|
||||||
not this.asExpr() instanceof ClassExpr
|
not this.asExpr() instanceof ClassExpr
|
||||||
@@ -293,7 +294,7 @@ private module SensitiveDataModeling {
|
|||||||
SensitiveDataClassification classification;
|
SensitiveDataClassification classification;
|
||||||
|
|
||||||
SensitiveSubscript() {
|
SensitiveSubscript() {
|
||||||
this.asCfgNode().(SubscriptNode).getIndex() =
|
this.asCfgNode().(Cfg::SubscriptNode).getIndex() =
|
||||||
sensitiveLookupStringConst(classification).asCfgNode()
|
sensitiveLookupStringConst(classification).asCfgNode()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ overlay[local]
|
|||||||
module;
|
module;
|
||||||
|
|
||||||
private import python
|
private import python
|
||||||
|
private import semmle.python.controlflow.internal.Cfg as Cfg
|
||||||
import DataFlowUtil
|
import DataFlowUtil
|
||||||
import DataFlowPublic
|
import DataFlowPublic
|
||||||
private import DataFlowPrivate
|
private import DataFlowPrivate
|
||||||
@@ -83,9 +84,9 @@ abstract class AttrWrite extends AttrRef {
|
|||||||
* ```python
|
* ```python
|
||||||
* object.attr = value
|
* object.attr = value
|
||||||
* ```
|
* ```
|
||||||
* Also gives access to the `value` being written, by extending `DefinitionNode`.
|
* Also gives access to the `value` being written, by extending `Cfg::DefinitionNode`.
|
||||||
*/
|
*/
|
||||||
private class AttributeAssignmentNode extends DefinitionNode, AttrNode { }
|
private class AttributeAssignmentNode extends Cfg::DefinitionNode, Cfg::AttrNode { }
|
||||||
|
|
||||||
/** A simple attribute assignment: `object.attr = value`. */
|
/** A simple attribute assignment: `object.attr = value`. */
|
||||||
private class AttributeAssignmentAsAttrWrite extends AttrWrite, CfgNode {
|
private class AttributeAssignmentAsAttrWrite extends AttrWrite, CfgNode {
|
||||||
@@ -131,13 +132,13 @@ private class GlobalAttributeAssignmentAsAttrWrite extends AttrWrite, CfgNode {
|
|||||||
override string getAttributeName() { result = node.getName() }
|
override string getAttributeName() { result = node.getName() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Represents `CallNode`s that may refer to calls to built-in functions or classes. */
|
/** Represents `Cfg::CallNode`s that may refer to calls to built-in functions or classes. */
|
||||||
private class BuiltInCallNode extends CallNode {
|
private class BuiltInCallNode extends Cfg::CallNode {
|
||||||
string name;
|
string name;
|
||||||
|
|
||||||
BuiltInCallNode() {
|
BuiltInCallNode() {
|
||||||
// TODO disallow instances where the name of the built-in may refer to an in-scope variable of that name.
|
// TODO disallow instances where the name of the built-in may refer to an in-scope variable of that name.
|
||||||
exists(NameNode id |
|
exists(Cfg::NameNode id |
|
||||||
name = Builtins::getBuiltinName() and
|
name = Builtins::getBuiltinName() and
|
||||||
this.getFunction() = id and
|
this.getFunction() = id and
|
||||||
id.getId() = name and
|
id.getId() = name and
|
||||||
@@ -145,7 +146,7 @@ private class BuiltInCallNode extends CallNode {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the name of the built-in function that is called at this `CallNode` */
|
/** Gets the name of the built-in function that is called at this `Cfg::CallNode` */
|
||||||
string getBuiltinName() { result = name }
|
string getBuiltinName() { result = name }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,20 +158,20 @@ private class BuiltinAttrCallNode extends BuiltInCallNode {
|
|||||||
BuiltinAttrCallNode() { name in ["setattr", "getattr", "hasattr", "delattr"] }
|
BuiltinAttrCallNode() { name in ["setattr", "getattr", "hasattr", "delattr"] }
|
||||||
|
|
||||||
/** Gets the control flow node for object on which the attribute is accessed. */
|
/** Gets the control flow node for object on which the attribute is accessed. */
|
||||||
ControlFlowNode getObject() { result in [this.getArg(0), this.getArgByName("object")] }
|
Cfg::ControlFlowNode getObject() { result in [this.getArg(0), this.getArgByName("object")] }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the control flow node for the value that is being written to the attribute.
|
* Gets the control flow node for the value that is being written to the attribute.
|
||||||
* Only relevant for `setattr` calls.
|
* Only relevant for `setattr` calls.
|
||||||
*/
|
*/
|
||||||
ControlFlowNode getValue() {
|
Cfg::ControlFlowNode getValue() {
|
||||||
// only valid for `setattr`
|
// only valid for `setattr`
|
||||||
name = "setattr" and
|
name = "setattr" and
|
||||||
result in [this.getArg(2), this.getArgByName("value")]
|
result in [this.getArg(2), this.getArgByName("value")]
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the control flow node that defines the name of the attribute being accessed. */
|
/** Gets the control flow node that defines the name of the attribute being accessed. */
|
||||||
ControlFlowNode getName() { result in [this.getArg(1), this.getArgByName("name")] }
|
Cfg::ControlFlowNode getName() { result in [this.getArg(1), this.getArgByName("name")] }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Represents calls to the built-in `setattr`. */
|
/** Represents calls to the built-in `setattr`. */
|
||||||
@@ -205,10 +206,10 @@ private class SetAttrCallAsAttrWrite extends AttrWrite, CfgNode {
|
|||||||
* attr = value
|
* attr = value
|
||||||
* ...
|
* ...
|
||||||
* ```
|
* ```
|
||||||
* Instances of this class correspond to the `NameNode` for `attr`, and also gives access to `value` by
|
* Instances of this class correspond to the `Cfg::NameNode` for `attr`, and also gives access to `value` by
|
||||||
* virtue of being a `DefinitionNode`.
|
* virtue of being a `Cfg::DefinitionNode`.
|
||||||
*/
|
*/
|
||||||
private class ClassAttributeAssignmentNode extends DefinitionNode, NameNode {
|
private class ClassAttributeAssignmentNode extends Cfg::DefinitionNode, Cfg::NameNode {
|
||||||
ClassAttributeAssignmentNode() { this.getScope() = any(ClassExpr c).getInnerScope() }
|
ClassAttributeAssignmentNode() { this.getScope() = any(ClassExpr c).getInnerScope() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,7 +229,7 @@ private class ClassDefinitionAsAttrWrite extends AttrWrite, CfgNode {
|
|||||||
|
|
||||||
override Node getValue() { result.asCfgNode() = node.getValue() }
|
override Node getValue() { result.asCfgNode() = node.getValue() }
|
||||||
|
|
||||||
override Node getObject() { result.asCfgNode() = cls.getAFlowNode() }
|
override Node getObject() { result.asCfgNode().getNode() = cls }
|
||||||
|
|
||||||
override ExprNode getAttributeNameExpr() { none() }
|
override ExprNode getAttributeNameExpr() { none() }
|
||||||
|
|
||||||
@@ -248,7 +249,7 @@ abstract class AttrRead extends AttrRef, Node, LocalSourceNode {
|
|||||||
|
|
||||||
/** A simple attribute read, e.g. `object.attr` */
|
/** A simple attribute read, e.g. `object.attr` */
|
||||||
private class AttributeReadAsAttrRead extends AttrRead, CfgNode {
|
private class AttributeReadAsAttrRead extends AttrRead, CfgNode {
|
||||||
override AttrNode node;
|
override Cfg::AttrNode node;
|
||||||
|
|
||||||
AttributeReadAsAttrRead() { node.isLoad() }
|
AttributeReadAsAttrRead() { node.isLoad() }
|
||||||
|
|
||||||
@@ -285,7 +286,7 @@ private class GetAttrCallAsAttrRead extends AttrRead, CfgNode {
|
|||||||
* is treated as if it is a read of the attribute `module.attr`, even if `module` is not imported directly.
|
* is treated as if it is a read of the attribute `module.attr`, even if `module` is not imported directly.
|
||||||
*/
|
*/
|
||||||
private class ModuleAttributeImportAsAttrRead extends AttrRead, CfgNode {
|
private class ModuleAttributeImportAsAttrRead extends AttrRead, CfgNode {
|
||||||
override ImportMemberNode node;
|
override Cfg::ImportMemberNode node;
|
||||||
|
|
||||||
override Node getObject() { result.asCfgNode() = node.getModule(_) }
|
override Node getObject() { result.asCfgNode() = node.getModule(_) }
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ overlay[local]
|
|||||||
module;
|
module;
|
||||||
|
|
||||||
private import python
|
private import python
|
||||||
|
private import semmle.python.controlflow.internal.Cfg as Cfg
|
||||||
private import semmle.python.dataflow.new.DataFlow
|
private import semmle.python.dataflow.new.DataFlow
|
||||||
private import semmle.python.dataflow.new.internal.ImportStar
|
private import semmle.python.dataflow.new.internal.ImportStar
|
||||||
|
|
||||||
@@ -67,7 +68,7 @@ module Builtins {
|
|||||||
DataFlow::CfgNode likelyBuiltin(string name) {
|
DataFlow::CfgNode likelyBuiltin(string name) {
|
||||||
exists(Module m |
|
exists(Module m |
|
||||||
result.getNode() =
|
result.getNode() =
|
||||||
any(NameNode n |
|
any(Cfg::NameNode n |
|
||||||
possible_builtin_accessed_in_module(n, name, m) and
|
possible_builtin_accessed_in_module(n, name, m) and
|
||||||
not possible_builtin_defined_in_module(name, m)
|
not possible_builtin_defined_in_module(name, m)
|
||||||
)
|
)
|
||||||
@@ -87,7 +88,7 @@ module Builtins {
|
|||||||
* Holds if `n` is an access of a global variable called `name` (which is also the name of a
|
* Holds if `n` is an access of a global variable called `name` (which is also the name of a
|
||||||
* built-in) inside the module `m`.
|
* built-in) inside the module `m`.
|
||||||
*/
|
*/
|
||||||
private predicate possible_builtin_accessed_in_module(NameNode n, string name, Module m) {
|
private predicate possible_builtin_accessed_in_module(Cfg::NameNode n, string name, Module m) {
|
||||||
n.isGlobal() and
|
n.isGlobal() and
|
||||||
n.isLoad() and
|
n.isLoad() and
|
||||||
name = n.getId() and
|
name = n.getId() and
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
* what callable this call might end up targeting.
|
* what callable this call might end up targeting.
|
||||||
*
|
*
|
||||||
* Specifically this means that we cannot use type-backtrackers from the function of a
|
* Specifically this means that we cannot use type-backtrackers from the function of a
|
||||||
* `CallNode`, since there is no `CallNode` to backtrack from for `func` in the example
|
* `Cfg::CallNode`, since there is no `Cfg::CallNode` to backtrack from for `func` in the example
|
||||||
* above.
|
* above.
|
||||||
*
|
*
|
||||||
* Note: This hasn't been 100% realized yet, so we don't currently expose a predicate to
|
* Note: This hasn't been 100% realized yet, so we don't currently expose a predicate to
|
||||||
@@ -35,6 +35,7 @@ overlay[local?]
|
|||||||
module;
|
module;
|
||||||
|
|
||||||
private import python
|
private import python
|
||||||
|
private import semmle.python.controlflow.internal.Cfg as Cfg
|
||||||
private import DataFlowPublic
|
private import DataFlowPublic
|
||||||
private import DataFlowPrivate
|
private import DataFlowPrivate
|
||||||
private import FlowSummaryImpl as FlowSummaryImpl
|
private import FlowSummaryImpl as FlowSummaryImpl
|
||||||
@@ -162,7 +163,7 @@ newtype TArgumentPosition =
|
|||||||
*/
|
*/
|
||||||
TLambdaSelfArgumentPosition() or
|
TLambdaSelfArgumentPosition() or
|
||||||
TPositionalArgumentPosition(int index) {
|
TPositionalArgumentPosition(int index) {
|
||||||
exists(any(CallNode c).getArg(index))
|
exists(any(Cfg::CallNode c).getArg(index))
|
||||||
or
|
or
|
||||||
// since synthetic calls within a summarized callable could use a unique argument
|
// since synthetic calls within a summarized callable could use a unique argument
|
||||||
// position, we need to ensure we make these available (these are specified as
|
// position, we need to ensure we make these available (these are specified as
|
||||||
@@ -174,7 +175,7 @@ newtype TArgumentPosition =
|
|||||||
index = 0
|
index = 0
|
||||||
} or
|
} or
|
||||||
TKeywordArgumentPosition(string name) {
|
TKeywordArgumentPosition(string name) {
|
||||||
exists(any(CallNode c).getArgByName(name))
|
exists(any(Cfg::CallNode c).getArgByName(name))
|
||||||
or
|
or
|
||||||
// see comment for TPositionalArgumentPosition
|
// see comment for TPositionalArgumentPosition
|
||||||
FlowSummaryImpl::ParsePositions::isParsedKeywordParameterPosition(_, name)
|
FlowSummaryImpl::ParsePositions::isParsedKeywordParameterPosition(_, name)
|
||||||
@@ -256,9 +257,12 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) {
|
|||||||
*/
|
*/
|
||||||
overlay[local]
|
overlay[local]
|
||||||
predicate isStaticmethod(Function func) {
|
predicate isStaticmethod(Function func) {
|
||||||
exists(NameNode id | id.getId() = "staticmethod" and id.isGlobal() |
|
// The decorator is *syntactically* a `Name` "staticmethod" — we don't
|
||||||
func.getADecorator() = id.getNode()
|
// care which variable it resolves to. `staticmethod` is a builtin and
|
||||||
)
|
// is almost never shadowed in a module-level scope; even if a class
|
||||||
|
// redefines `staticmethod` in its body, the class body has not started
|
||||||
|
// executing yet at the decorator position, so Python uses the builtin.
|
||||||
|
func.getADecorator().(Name).getId() = "staticmethod"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -268,9 +272,9 @@ predicate isStaticmethod(Function func) {
|
|||||||
*/
|
*/
|
||||||
overlay[local]
|
overlay[local]
|
||||||
predicate isClassmethod(Function func) {
|
predicate isClassmethod(Function func) {
|
||||||
exists(NameNode id | id.getId() = "classmethod" and id.isGlobal() |
|
// See `isStaticmethod` for the rationale for matching on the AST `Name`
|
||||||
func.getADecorator() = id.getNode()
|
// rather than going via the CFG and `isGlobal()`.
|
||||||
)
|
func.getADecorator().(Name).getId() = "classmethod"
|
||||||
or
|
or
|
||||||
exists(Class cls |
|
exists(Class cls |
|
||||||
cls.getAMethod() = func and
|
cls.getAMethod() = func and
|
||||||
@@ -285,9 +289,8 @@ predicate isClassmethod(Function func) {
|
|||||||
/** Holds if the function `func` has a `property` decorator. */
|
/** Holds if the function `func` has a `property` decorator. */
|
||||||
overlay[local]
|
overlay[local]
|
||||||
predicate hasPropertyDecorator(Function func) {
|
predicate hasPropertyDecorator(Function func) {
|
||||||
exists(NameNode id | id.getId() = "property" and id.isGlobal() |
|
// See `isStaticmethod` for the rationale for matching on the AST `Name`.
|
||||||
func.getADecorator() = id.getNode()
|
func.getADecorator().(Name).getId() = "property"
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -295,10 +298,12 @@ predicate hasPropertyDecorator(Function func) {
|
|||||||
*/
|
*/
|
||||||
overlay[local]
|
overlay[local]
|
||||||
predicate hasContextmanagerDecorator(Function func) {
|
predicate hasContextmanagerDecorator(Function func) {
|
||||||
exists(ControlFlowNode contextmanager |
|
exists(Cfg::ControlFlowNode contextmanager |
|
||||||
contextmanager.(NameNode).getId() = "contextmanager" and contextmanager.(NameNode).isGlobal()
|
contextmanager.(Cfg::NameNode).getId() = "contextmanager" and
|
||||||
|
contextmanager.(Cfg::NameNode).isGlobal()
|
||||||
or
|
or
|
||||||
contextmanager.(AttrNode).getObject("contextmanager").(NameNode).getId() = "contextlib"
|
contextmanager.(Cfg::AttrNode).getObject("contextmanager").(Cfg::NameNode).getId() =
|
||||||
|
"contextlib"
|
||||||
|
|
|
|
||||||
func.getADecorator() = contextmanager.getNode()
|
func.getADecorator() = contextmanager.getNode()
|
||||||
)
|
)
|
||||||
@@ -314,10 +319,10 @@ predicate hasContextmanagerDecorator(Function func) {
|
|||||||
*/
|
*/
|
||||||
overlay[local]
|
overlay[local]
|
||||||
private predicate hasOverloadDecorator(Function func) {
|
private predicate hasOverloadDecorator(Function func) {
|
||||||
exists(ControlFlowNode overload |
|
exists(Cfg::ControlFlowNode overload |
|
||||||
overload.(NameNode).getId() = "overload" and overload.(NameNode).isGlobal()
|
overload.(Cfg::NameNode).getId() = "overload" and overload.(Cfg::NameNode).isGlobal()
|
||||||
or
|
or
|
||||||
overload.(AttrNode).getObject("overload").(NameNode).isGlobal()
|
overload.(Cfg::AttrNode).getObject("overload").(Cfg::NameNode).isGlobal()
|
||||||
|
|
|
|
||||||
func.getADecorator() = overload.getNode()
|
func.getADecorator() = overload.getNode()
|
||||||
)
|
)
|
||||||
@@ -536,7 +541,7 @@ class LibraryCallableValue extends DataFlowCallable, TLibraryCallable {
|
|||||||
// =============================================================================
|
// =============================================================================
|
||||||
/** Gets a call to `type`. */
|
/** Gets a call to `type`. */
|
||||||
private CallCfgNode getTypeCall() {
|
private CallCfgNode getTypeCall() {
|
||||||
exists(NameNode id | id.getId() = "type" and id.isGlobal() |
|
exists(Cfg::NameNode id | id.getId() = "type" and id.isGlobal() |
|
||||||
result.getFunction().asCfgNode() = id
|
result.getFunction().asCfgNode() = id
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -548,7 +553,7 @@ private CallCfgNode getSuperCall() {
|
|||||||
// link below), but otherwise only 2 edgecases. Overall it seems ok to ignore this complexity.
|
// link below), but otherwise only 2 edgecases. Overall it seems ok to ignore this complexity.
|
||||||
//
|
//
|
||||||
// https://github.com/python/cpython/blob/18b1782192f85bd26db89f5bc850f8bee4247c1a/Lib/unittest/mock.py#L48-L50
|
// https://github.com/python/cpython/blob/18b1782192f85bd26db89f5bc850f8bee4247c1a/Lib/unittest/mock.py#L48-L50
|
||||||
exists(NameNode id | id.getId() = "super" and id.isGlobal() |
|
exists(Cfg::NameNode id | id.getId() = "super" and id.isGlobal() |
|
||||||
result.getFunction().asCfgNode() = id
|
result.getFunction().asCfgNode() = id
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1034,7 +1039,7 @@ private module MethodCalls {
|
|||||||
*/
|
*/
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate directCall(
|
private predicate directCall(
|
||||||
CallNode call, Function target, string functionName, Class cls, AttrRead attr, Node self
|
Cfg::CallNode call, Function target, string functionName, Class cls, AttrRead attr, Node self
|
||||||
) {
|
) {
|
||||||
target = findFunctionAccordingToMroKnownStartingClass(cls, functionName) and
|
target = findFunctionAccordingToMroKnownStartingClass(cls, functionName) and
|
||||||
directCall_join(call, functionName, cls, attr, self)
|
directCall_join(call, functionName, cls, attr, self)
|
||||||
@@ -1043,7 +1048,7 @@ private module MethodCalls {
|
|||||||
/** Extracted to give good join order */
|
/** Extracted to give good join order */
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate directCall_join(
|
private predicate directCall_join(
|
||||||
CallNode call, string functionName, Class cls, AttrRead attr, Node self
|
Cfg::CallNode call, string functionName, Class cls, AttrRead attr, Node self
|
||||||
) {
|
) {
|
||||||
call.getFunction() = attrReadTracker(attr).asCfgNode() and
|
call.getFunction() = attrReadTracker(attr).asCfgNode() and
|
||||||
attr.accesses(self, functionName) and
|
attr.accesses(self, functionName) and
|
||||||
@@ -1060,7 +1065,7 @@ private module MethodCalls {
|
|||||||
*/
|
*/
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate callWithinMethodImplicitSelfOrCls(
|
private predicate callWithinMethodImplicitSelfOrCls(
|
||||||
CallNode call, Function target, string functionName, Class classWithMethod, AttrRead attr,
|
Cfg::CallNode call, Function target, string functionName, Class classWithMethod, AttrRead attr,
|
||||||
Node self
|
Node self
|
||||||
) {
|
) {
|
||||||
target = findFunctionAccordingToMro(getADirectSubclass*(classWithMethod), functionName) and
|
target = findFunctionAccordingToMro(getADirectSubclass*(classWithMethod), functionName) and
|
||||||
@@ -1070,7 +1075,7 @@ private module MethodCalls {
|
|||||||
/** Extracted to give good join order */
|
/** Extracted to give good join order */
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate callWithinMethodImplicitSelfOrCls_join(
|
private predicate callWithinMethodImplicitSelfOrCls_join(
|
||||||
CallNode call, string functionName, Class classWithMethod, AttrRead attr, Node self
|
Cfg::CallNode call, string functionName, Class classWithMethod, AttrRead attr, Node self
|
||||||
) {
|
) {
|
||||||
call.getFunction() = attrReadTracker(attr).asCfgNode() and
|
call.getFunction() = attrReadTracker(attr).asCfgNode() and
|
||||||
attr.accesses(self, functionName) and
|
attr.accesses(self, functionName) and
|
||||||
@@ -1082,7 +1087,7 @@ private module MethodCalls {
|
|||||||
* resolve the call to a known target (since the only super class might be the
|
* resolve the call to a known target (since the only super class might be the
|
||||||
* builtin `object`, so we never have the implementation of `__new__` in the DB).
|
* builtin `object`, so we never have the implementation of `__new__` in the DB).
|
||||||
*/
|
*/
|
||||||
predicate fromSuperNewCall(CallNode call, Class classUsedInSuper, AttrRead attr, Node self) {
|
predicate fromSuperNewCall(Cfg::CallNode call, Class classUsedInSuper, AttrRead attr, Node self) {
|
||||||
fromSuper_join(call, "__new__", classUsedInSuper, attr, self) and
|
fromSuper_join(call, "__new__", classUsedInSuper, attr, self) and
|
||||||
self in [classTracker(_), clsArgumentTracker(_)]
|
self in [classTracker(_), clsArgumentTracker(_)]
|
||||||
}
|
}
|
||||||
@@ -1104,7 +1109,7 @@ private module MethodCalls {
|
|||||||
*/
|
*/
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
predicate fromSuper(
|
predicate fromSuper(
|
||||||
CallNode call, Function target, string functionName, Class classUsedInSuper, AttrRead attr,
|
Cfg::CallNode call, Function target, string functionName, Class classUsedInSuper, AttrRead attr,
|
||||||
Node self
|
Node self
|
||||||
) {
|
) {
|
||||||
target = findFunctionAccordingToMro(getNextClassInMro(classUsedInSuper), functionName) and
|
target = findFunctionAccordingToMro(getNextClassInMro(classUsedInSuper), functionName) and
|
||||||
@@ -1114,7 +1119,7 @@ private module MethodCalls {
|
|||||||
/** Extracted to give good join order */
|
/** Extracted to give good join order */
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate fromSuper_join(
|
private predicate fromSuper_join(
|
||||||
CallNode call, string functionName, Class classUsedInSuper, AttrRead attr, Node self
|
Cfg::CallNode call, string functionName, Class classUsedInSuper, AttrRead attr, Node self
|
||||||
) {
|
) {
|
||||||
call.getFunction() = attrReadTracker(attr).asCfgNode() and
|
call.getFunction() = attrReadTracker(attr).asCfgNode() and
|
||||||
(
|
(
|
||||||
@@ -1133,7 +1138,7 @@ private module MethodCalls {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate resolveMethodCall(CallNode call, Function target, CallType type, Node self) {
|
predicate resolveMethodCall(Cfg::CallNode call, Function target, CallType type, Node self) {
|
||||||
(
|
(
|
||||||
directCall(call, target, _, _, _, self)
|
directCall(call, target, _, _, _, self)
|
||||||
or
|
or
|
||||||
@@ -1180,7 +1185,7 @@ import MethodCalls
|
|||||||
* NOTE: We have this predicate mostly to be able to compare with old point-to
|
* NOTE: We have this predicate mostly to be able to compare with old point-to
|
||||||
* call-graph resolution. So it could be removed in the future.
|
* call-graph resolution. So it could be removed in the future.
|
||||||
*/
|
*/
|
||||||
predicate resolveClassCall(CallNode call, Class cls) {
|
predicate resolveClassCall(Cfg::CallNode call, Class cls) {
|
||||||
call.getFunction() = classTracker(cls).asCfgNode()
|
call.getFunction() = classTracker(cls).asCfgNode()
|
||||||
or
|
or
|
||||||
// `cls()` inside a classmethod (which also contains `type(self)()` inside a method)
|
// `cls()` inside a classmethod (which also contains `type(self)()` inside a method)
|
||||||
@@ -1210,7 +1215,7 @@ Function invokedFunctionFromClassConstruction(Class cls, string funcName) {
|
|||||||
*
|
*
|
||||||
* See https://docs.python.org/3/reference/datamodel.html#object.__call__
|
* See https://docs.python.org/3/reference/datamodel.html#object.__call__
|
||||||
*/
|
*/
|
||||||
predicate resolveClassInstanceCall(CallNode call, Function target, Node self) {
|
predicate resolveClassInstanceCall(Cfg::CallNode call, Function target, Node self) {
|
||||||
exists(Class cls |
|
exists(Class cls |
|
||||||
call.getFunction() = classInstanceTracker(cls).asCfgNode() and
|
call.getFunction() = classInstanceTracker(cls).asCfgNode() and
|
||||||
target = findFunctionAccordingToMroKnownStartingClass(cls, "__call__")
|
target = findFunctionAccordingToMroKnownStartingClass(cls, "__call__")
|
||||||
@@ -1229,7 +1234,7 @@ predicate resolveClassInstanceCall(CallNode call, Function target, Node self) {
|
|||||||
* Holds if `call` is a call to the `target`, with call-type `type`.
|
* Holds if `call` is a call to the `target`, with call-type `type`.
|
||||||
*/
|
*/
|
||||||
cached
|
cached
|
||||||
predicate resolveCall(CallNode call, Function target, CallType type) {
|
predicate resolveCall(Cfg::CallNode call, Function target, CallType type) {
|
||||||
Stages::DataFlow::ref() and
|
Stages::DataFlow::ref() and
|
||||||
(
|
(
|
||||||
type instanceof CallTypePlainFunction and
|
type instanceof CallTypePlainFunction and
|
||||||
@@ -1254,11 +1259,11 @@ predicate resolveCall(CallNode call, Function target, CallType type) {
|
|||||||
// =============================================================================
|
// =============================================================================
|
||||||
/**
|
/**
|
||||||
* Holds if the argument of `call` at position `apos` is `arg`. This is just a helper
|
* Holds if the argument of `call` at position `apos` is `arg`. This is just a helper
|
||||||
* predicate that maps ArgumentPositions to the arguments of the underlying `CallNode`.
|
* predicate that maps ArgumentPositions to the arguments of the underlying `Cfg::CallNode`.
|
||||||
*/
|
*/
|
||||||
overlay[local]
|
overlay[local]
|
||||||
cached
|
cached
|
||||||
predicate normalCallArg(CallNode call, Node arg, ArgumentPosition apos) {
|
predicate normalCallArg(Cfg::CallNode call, Node arg, ArgumentPosition apos) {
|
||||||
exists(int index |
|
exists(int index |
|
||||||
apos.isPositional(index) and
|
apos.isPositional(index) and
|
||||||
arg.asCfgNode() = call.getArg(index)
|
arg.asCfgNode() = call.getArg(index)
|
||||||
@@ -1273,7 +1278,7 @@ predicate normalCallArg(CallNode call, Node arg, ArgumentPosition apos) {
|
|||||||
exists(int index |
|
exists(int index |
|
||||||
apos.isStarArgs(index) and
|
apos.isStarArgs(index) and
|
||||||
arg.asCfgNode() = call.getStarArg() and
|
arg.asCfgNode() = call.getStarArg() and
|
||||||
// since `CallNode.getArg` doesn't include `*args`, we need to drop to the AST level
|
// since `Cfg::CallNode.getArg` doesn't include `*args`, we need to drop to the AST level
|
||||||
// to get the index. Notice that we only use the AST for getting the index, so we
|
// to get the index. Notice that we only use the AST for getting the index, so we
|
||||||
// don't need to check for dominance in regards to splitting.
|
// don't need to check for dominance in regards to splitting.
|
||||||
call.getStarArg().getNode() = call.getNode().getPositionalArg(index).(Starred).getValue()
|
call.getStarArg().getNode() = call.getNode().getPositionalArg(index).(Starred).getValue()
|
||||||
@@ -1347,7 +1352,9 @@ predicate normalCallArg(CallNode call, Node arg, ArgumentPosition apos) {
|
|||||||
* translated into `l.clear()`, and we can still have use-use flow.
|
* translated into `l.clear()`, and we can still have use-use flow.
|
||||||
*/
|
*/
|
||||||
cached
|
cached
|
||||||
predicate getCallArg(CallNode call, Function target, CallType type, Node arg, ArgumentPosition apos) {
|
predicate getCallArg(
|
||||||
|
Cfg::CallNode call, Function target, CallType type, Node arg, ArgumentPosition apos
|
||||||
|
) {
|
||||||
Stages::DataFlow::ref() and
|
Stages::DataFlow::ref() and
|
||||||
resolveCall(call, target, type) and
|
resolveCall(call, target, type) and
|
||||||
(
|
(
|
||||||
@@ -1440,10 +1447,13 @@ private predicate sameEnclosingCallable(Node node1, Node node2) {
|
|||||||
// DataFlowCall
|
// DataFlowCall
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
newtype TDataFlowCall =
|
newtype TDataFlowCall =
|
||||||
TNormalCall(CallNode call, Function target, CallType type) { resolveCall(call, target, type) } or
|
TNormalCall(Cfg::CallNode call, Function target, CallType type) {
|
||||||
|
resolveCall(call, target, type) and
|
||||||
|
Cfg::isCanonicalAstNodeRepresentative(call)
|
||||||
|
} or
|
||||||
/** A call to the generated function inside a comprehension */
|
/** A call to the generated function inside a comprehension */
|
||||||
TComprehensionCall(Comp c) or
|
TComprehensionCall(Comp c) or
|
||||||
TPotentialLibraryCall(CallNode call) or
|
TPotentialLibraryCall(Cfg::CallNode call) { Cfg::isCanonicalAstNodeRepresentative(call) } or
|
||||||
/** A synthesized call inside a summarized callable */
|
/** A synthesized call inside a summarized callable */
|
||||||
TSummaryCall(
|
TSummaryCall(
|
||||||
FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver
|
FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver
|
||||||
@@ -1463,7 +1473,7 @@ abstract class DataFlowCall extends TDataFlowCall {
|
|||||||
abstract ArgumentNode getArgument(ArgumentPosition apos);
|
abstract ArgumentNode getArgument(ArgumentPosition apos);
|
||||||
|
|
||||||
/** Get the control flow node representing this call, if any. */
|
/** Get the control flow node representing this call, if any. */
|
||||||
abstract ControlFlowNode getNode();
|
abstract Cfg::ControlFlowNode getNode();
|
||||||
|
|
||||||
/** Gets the enclosing callable of this call. */
|
/** Gets the enclosing callable of this call. */
|
||||||
DataFlowCallable getEnclosingCallable() { result = getCallableScope(this.getScope()) }
|
DataFlowCallable getEnclosingCallable() { result = getCallableScope(this.getScope()) }
|
||||||
@@ -1494,28 +1504,28 @@ abstract class ExtractedDataFlowCall extends DataFlowCall {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A resolved call in source code with an underlying `CallNode`.
|
* A resolved call in source code with an underlying `Cfg::CallNode`.
|
||||||
*
|
*
|
||||||
* This is considered normal, compared with special calls such as `obj[0]` calling the
|
* This is considered normal, compared with special calls such as `obj[0]` calling the
|
||||||
* `__getitem__` method on the object. However, this also includes calls that go to the
|
* `__getitem__` method on the object. However, this also includes calls that go to the
|
||||||
* `__call__` special method.
|
* `__call__` special method.
|
||||||
*/
|
*/
|
||||||
class NormalCall extends ExtractedDataFlowCall, TNormalCall {
|
class NormalCall extends ExtractedDataFlowCall, TNormalCall {
|
||||||
CallNode call;
|
Cfg::CallNode call;
|
||||||
Function target;
|
Function target;
|
||||||
CallType type;
|
CallType type;
|
||||||
|
|
||||||
NormalCall() { this = TNormalCall(call, target, type) }
|
NormalCall() { this = TNormalCall(call, target, type) }
|
||||||
|
|
||||||
override string toString() {
|
override string toString() {
|
||||||
// note: if we used toString directly on the CallNode we would get
|
// note: if we used toString directly on the Cfg::CallNode we would get
|
||||||
// `ControlFlowNode for func()`
|
// `Cfg::ControlFlowNode for func()`
|
||||||
// but the `ControlFlowNode` part is just clutter, so we go directly to the AST node
|
// but the `Cfg::ControlFlowNode` part is just clutter, so we go directly to the AST node
|
||||||
// instead.
|
// instead.
|
||||||
result = call.getNode().toString()
|
result = call.getNode().toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
override ControlFlowNode getNode() { result = call }
|
override Cfg::ControlFlowNode getNode() { result = call }
|
||||||
|
|
||||||
override Scope getScope() { result = call.getScope() }
|
override Scope getScope() { result = call.getScope() }
|
||||||
|
|
||||||
@@ -1543,7 +1553,7 @@ class ComprehensionCall extends ExtractedDataFlowCall, TComprehensionCall {
|
|||||||
|
|
||||||
override string toString() { result = "comprehension call" }
|
override string toString() { result = "comprehension call" }
|
||||||
|
|
||||||
override ControlFlowNode getNode() { result.getNode() = c }
|
override Cfg::ControlFlowNode getNode() { result.getNode() = c }
|
||||||
|
|
||||||
override Scope getScope() { result = c.getScope() }
|
override Scope getScope() { result = c.getScope() }
|
||||||
|
|
||||||
@@ -1566,14 +1576,14 @@ class ComprehensionCall extends ExtractedDataFlowCall, TComprehensionCall {
|
|||||||
* in this class.
|
* in this class.
|
||||||
*/
|
*/
|
||||||
class PotentialLibraryCall extends ExtractedDataFlowCall, TPotentialLibraryCall {
|
class PotentialLibraryCall extends ExtractedDataFlowCall, TPotentialLibraryCall {
|
||||||
CallNode call;
|
Cfg::CallNode call;
|
||||||
|
|
||||||
PotentialLibraryCall() { this = TPotentialLibraryCall(call) }
|
PotentialLibraryCall() { this = TPotentialLibraryCall(call) }
|
||||||
|
|
||||||
override string toString() {
|
override string toString() {
|
||||||
// note: if we used toString directly on the CallNode we would get
|
// note: if we used toString directly on the Cfg::CallNode we would get
|
||||||
// `ControlFlowNode for func()`
|
// `Cfg::ControlFlowNode for func()`
|
||||||
// but the `ControlFlowNode` part is just clutter, so we go directly to the AST node
|
// but the `Cfg::ControlFlowNode` part is just clutter, so we go directly to the AST node
|
||||||
// instead.
|
// instead.
|
||||||
result = call.getNode().toString()
|
result = call.getNode().toString()
|
||||||
}
|
}
|
||||||
@@ -1590,10 +1600,10 @@ class PotentialLibraryCall extends ExtractedDataFlowCall, TPotentialLibraryCall
|
|||||||
// potential self argument, from `foo.bar()` -- note that this could also just be a
|
// potential self argument, from `foo.bar()` -- note that this could also just be a
|
||||||
// module reference, but we really don't have a good way of knowing :|
|
// module reference, but we really don't have a good way of knowing :|
|
||||||
apos.isSelf() and
|
apos.isSelf() and
|
||||||
result.asCfgNode() = call.getFunction().(AttrNode).getObject()
|
result.asCfgNode() = call.getFunction().(Cfg::AttrNode).getObject()
|
||||||
}
|
}
|
||||||
|
|
||||||
override ControlFlowNode getNode() { result = call }
|
override Cfg::ControlFlowNode getNode() { result = call }
|
||||||
|
|
||||||
override Scope getScope() { result = call.getScope() }
|
override Scope getScope() { result = call.getScope() }
|
||||||
}
|
}
|
||||||
@@ -1625,7 +1635,7 @@ class SummaryCall extends DataFlowCall, TSummaryCall {
|
|||||||
|
|
||||||
override ArgumentNode getArgument(ArgumentPosition apos) { none() }
|
override ArgumentNode getArgument(ArgumentPosition apos) { none() }
|
||||||
|
|
||||||
override ControlFlowNode getNode() { none() }
|
override Cfg::ControlFlowNode getNode() { none() }
|
||||||
|
|
||||||
override string toString() { result = "[summary] call to " + receiver + " in " + c }
|
override string toString() { result = "[summary] call to " + receiver + " in " + c }
|
||||||
|
|
||||||
@@ -1767,12 +1777,12 @@ private class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNodeImpl
|
|||||||
* This is used for tracking flow through captured variables.
|
* This is used for tracking flow through captured variables.
|
||||||
*/
|
*/
|
||||||
class SynthCapturedVariablesArgumentNode extends Node, TSynthCapturedVariablesArgumentNode {
|
class SynthCapturedVariablesArgumentNode extends Node, TSynthCapturedVariablesArgumentNode {
|
||||||
ControlFlowNode callable;
|
Cfg::ControlFlowNode callable;
|
||||||
|
|
||||||
SynthCapturedVariablesArgumentNode() { this = TSynthCapturedVariablesArgumentNode(callable) }
|
SynthCapturedVariablesArgumentNode() { this = TSynthCapturedVariablesArgumentNode(callable) }
|
||||||
|
|
||||||
/** Gets the `CallNode` corresponding to this captured variables argument node. */
|
/** Gets the `Cfg::CallNode` corresponding to this captured variables argument node. */
|
||||||
CallNode getCallNode() { result.getFunction() = callable }
|
Cfg::CallNode getCallNode() { result.getFunction() = callable }
|
||||||
|
|
||||||
/** Gets the `CfgNode` that corresponds to this synthetic node. */
|
/** Gets the `CfgNode` that corresponds to this synthetic node. */
|
||||||
CfgNode getUnderlyingNode() { result.asCfgNode() = callable }
|
CfgNode getUnderlyingNode() { result.asCfgNode() = callable }
|
||||||
@@ -1790,7 +1800,7 @@ class CapturedVariablesArgumentNodeAsArgumentNode extends ArgumentNode,
|
|||||||
{
|
{
|
||||||
overlay[global]
|
overlay[global]
|
||||||
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
|
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
|
||||||
exists(CallNode callNode | callNode = this.getCallNode() |
|
exists(Cfg::CallNode callNode | callNode = this.getCallNode() |
|
||||||
callNode = call.getNode() and
|
callNode = call.getNode() and
|
||||||
exists(Function target | resolveCall(callNode, target, _) |
|
exists(Function target | resolveCall(callNode, target, _) |
|
||||||
target = any(VariableCapture::CapturedVariable v).getACapturingScope()
|
target = any(VariableCapture::CapturedVariable v).getACapturingScope()
|
||||||
@@ -1804,7 +1814,7 @@ class CapturedVariablesArgumentNodeAsArgumentNode extends ArgumentNode,
|
|||||||
class SynthCapturedVariablesArgumentPostUpdateNode extends PostUpdateNodeImpl,
|
class SynthCapturedVariablesArgumentPostUpdateNode extends PostUpdateNodeImpl,
|
||||||
TSynthCapturedVariablesArgumentPostUpdateNode
|
TSynthCapturedVariablesArgumentPostUpdateNode
|
||||||
{
|
{
|
||||||
ControlFlowNode callable;
|
Cfg::ControlFlowNode callable;
|
||||||
|
|
||||||
SynthCapturedVariablesArgumentPostUpdateNode() {
|
SynthCapturedVariablesArgumentPostUpdateNode() {
|
||||||
this = TSynthCapturedVariablesArgumentPostUpdateNode(callable)
|
this = TSynthCapturedVariablesArgumentPostUpdateNode(callable)
|
||||||
@@ -1911,8 +1921,8 @@ abstract class ReturnNode extends Node {
|
|||||||
class ExtractedReturnNode extends ReturnNode, CfgNode {
|
class ExtractedReturnNode extends ReturnNode, CfgNode {
|
||||||
// See `TaintTrackingImplementation::returnFlowStep`
|
// See `TaintTrackingImplementation::returnFlowStep`
|
||||||
ExtractedReturnNode() {
|
ExtractedReturnNode() {
|
||||||
node = any(Return ret).getValue().getAFlowNode() or
|
node.getNode() = any(Return ret).getValue() or
|
||||||
node = any(Yield yield).getAFlowNode()
|
node.getNode() = any(Yield yield)
|
||||||
}
|
}
|
||||||
|
|
||||||
override ReturnKind getKind() { any() }
|
override ReturnKind getKind() { any() }
|
||||||
@@ -1930,7 +1940,7 @@ class ExtractedReturnNode extends ReturnNode, CfgNode {
|
|||||||
class YieldNodeInContextManagerFunction extends ReturnNode, CfgNode {
|
class YieldNodeInContextManagerFunction extends ReturnNode, CfgNode {
|
||||||
YieldNodeInContextManagerFunction() {
|
YieldNodeInContextManagerFunction() {
|
||||||
hasContextmanagerDecorator(node.getScope()) and
|
hasContextmanagerDecorator(node.getScope()) and
|
||||||
node = any(Yield yield).getValue().getAFlowNode()
|
node.getNode() = any(Yield yield).getValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
override ReturnKind getKind() { any() }
|
override ReturnKind getKind() { any() }
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user