Merge branch 'main' into rb-last-msg

This commit is contained in:
erik-krogh
2022-10-11 10:43:39 +02:00
246 changed files with 3311 additions and 1739 deletions

View File

@@ -52,7 +52,7 @@ jobs:
id: changes id: changes
run: | run: |
(git diff -z --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep -z '.qhelp$' | grep -z -v '.inc.qhelp'; (git diff -z --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep -z '.qhelp$' | grep -z -v '.inc.qhelp';
git diff -z --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep -z '.inc.qhelp$' | xargs --null -rn1 basename | xargs --null -rn1 git grep -z -l) | git diff -z --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep -z '.inc.qhelp$' | xargs --null -rn1 basename -z | xargs --null -rn1 git grep -z -l) |
grep -z '.qhelp$' | grep -z -v '^-' | sort -z -u > "${RUNNER_TEMP}/paths.txt" grep -z '.qhelp$' | grep -z -v '^-' | sort -z -u > "${RUNNER_TEMP}/paths.txt"
- name: QHelp preview - name: QHelp preview

View File

@@ -1,3 +1,7 @@
## 0.4.1
No user-facing changes.
## 0.4.0 ## 0.4.0
### Deprecated APIs ### Deprecated APIs

View File

@@ -0,0 +1,3 @@
## 0.4.1
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.4.0 lastReleaseVersion: 0.4.1

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all name: codeql/cpp-all
version: 0.4.1-dev version: 0.4.2-dev
groups: cpp groups: cpp
dbscheme: semmlecode.cpp.dbscheme dbscheme: semmlecode.cpp.dbscheme
extractor: cpp extractor: cpp

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -35,4 +35,4 @@ from LocalVariableOrParameter lv, GlobalVariable gv
where where
lv.getName() = gv.getName() and lv.getName() = gv.getName() and
lv.getFile() = gv.getFile() lv.getFile() = gv.getFile()
select lv, lv.type() + gv.getName() + " hides $@ with the same name.", gv, "a global variable" select lv, lv.type() + gv.getName() + " hides a $@ with the same name.", gv, "global variable"

View File

@@ -1,3 +1,9 @@
## 0.4.1
### Minor Analysis Improvements
* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages.
## 0.4.0 ## 0.4.0
### New Queries ### New Queries

View File

@@ -48,5 +48,5 @@ where
not coordinatePair(iterationVar, innerVar) not coordinatePair(iterationVar, innerVar)
select iterationVar, select iterationVar,
"Iteration variable " + iterationVar.getName() + "Iteration variable " + iterationVar.getName() +
" for $@ should have a descriptive name, since there is $@.", outer, "this loop", inner, " for $@ should have a descriptive name, since there is a $@.", outer, "this loop", inner,
"a nested loop" "nested loop"

View File

@@ -56,29 +56,26 @@ class VarargsFunction extends Function {
result = strictcount(FunctionCall fc | fc = this.getACallToThisFunction()) result = strictcount(FunctionCall fc | fc = this.getACallToThisFunction())
} }
string normalTerminator(int cnt) { string normalTerminator(int cnt, int totalCount) {
// the terminator is 0 or -1
result = ["0", "-1"] and result = ["0", "-1"] and
// at least 80% of calls have the terminator
cnt = this.trailingArgValueCount(result) and cnt = this.trailingArgValueCount(result) and
2 * cnt > this.totalCount() and totalCount = this.totalCount() and
not exists(FunctionCall fc, int index | 100 * cnt / totalCount >= 80 and
// terminator value is used in a non-terminating position // terminator value is not used in a non-terminating position
this.nonTrailingVarArgValue(fc, index) = result not exists(FunctionCall fc, int index | this.nonTrailingVarArgValue(fc, index) = result)
)
} }
predicate isWhitelisted() { predicate isWhitelisted() { this.hasGlobalName(["open", "fcntl", "ptrace", "mremap"]) }
this.hasGlobalName("open") or
this.hasGlobalName("fcntl") or
this.hasGlobalName("ptrace")
}
} }
from VarargsFunction f, FunctionCall fc, string terminator, int cnt from VarargsFunction f, FunctionCall fc, string terminator, int cnt, int totalCount
where where
terminator = f.normalTerminator(cnt) and terminator = f.normalTerminator(cnt, totalCount) and
fc = f.getACallToThisFunction() and fc = f.getACallToThisFunction() and
not normalisedExprValue(f.trailingArgumentIn(fc)) = terminator and not normalisedExprValue(f.trailingArgumentIn(fc)) = terminator and
not f.isWhitelisted() not f.isWhitelisted()
select fc, select fc,
"Calls to $@ should use the value " + terminator + " as a terminator (" + cnt + " calls do).", f, "Calls to $@ should use the value " + terminator + " as a terminator (" + cnt + " of " +
f.getQualifiedName() totalCount + " calls do).", f, f.getQualifiedName()

View File

@@ -135,5 +135,5 @@ where
sink.getNode().asExpr() = va and sink.getNode().asExpr() = va and
missingGuard(va, effect) missingGuard(va, effect)
select sink.getNode(), source, sink, select sink.getNode(), source, sink,
"Arithmetic expression depends on an $@, potentially causing an " + effect + ".", "This arithmetic expression depends on an $@, potentially causing an " + effect + ".",
getExpr(source.getNode()), "uncontrolled value" getExpr(source.getNode()), "uncontrolled value"

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The "Unterminated variadic call" (`cpp/unterminated-variadic-call`) query has been tuned to produce fewer false positive results.

View File

@@ -1,4 +1,5 @@
--- ## 0.4.1
category: minorAnalysis
--- ### Minor Analysis Improvements
* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. * The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.4.0 lastReleaseVersion: 0.4.1

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries name: codeql/cpp-queries
version: 0.4.1-dev version: 0.4.2-dev
groups: groups:
- cpp - cpp
- queries - queries

View File

@@ -1 +1 @@
| UnintendedDeclaration.cpp:65:14:65:20 | definition of myMutex | Local variable myMutex hides $@ with the same name. | UnintendedDeclaration.cpp:40:7:40:13 | myMutex | a global variable | | UnintendedDeclaration.cpp:65:14:65:20 | definition of myMutex | Local variable myMutex hides a $@ with the same name. | UnintendedDeclaration.cpp:40:7:40:13 | myMutex | global variable |

View File

@@ -1,5 +1,5 @@
| Hiding.c:22:25:22:26 | definition of gi | Local variable gi hides $@ with the same name. | Hiding.c:2:5:2:6 | gi | a global variable | | Hiding.c:22:25:22:26 | definition of gi | Local variable gi hides a $@ with the same name. | Hiding.c:2:5:2:6 | gi | global variable |
| Hiding.c:23:25:23:26 | definition of gj | Local variable gj hides $@ with the same name. | Hiding.c:3:12:3:13 | gj | a global variable | | Hiding.c:23:25:23:26 | definition of gj | Local variable gj hides a $@ with the same name. | Hiding.c:3:12:3:13 | gj | global variable |
| Hiding.c:24:25:24:26 | definition of gk | Local variable gk hides $@ with the same name. | Hiding.c:4:12:4:13 | gk | a global variable | | Hiding.c:24:25:24:26 | definition of gk | Local variable gk hides a $@ with the same name. | Hiding.c:4:12:4:13 | gk | global variable |
| Hiding.c:37:20:37:21 | definition of g3 | Parameter g3 hides $@ with the same name. | Hiding.c:33:13:33:14 | g3 | a global variable | | Hiding.c:37:20:37:21 | definition of g3 | Parameter g3 hides a $@ with the same name. | Hiding.c:33:13:33:14 | g3 | global variable |
| Hiding.c:40:20:40:21 | definition of g5 | Parameter g5 hides $@ with the same name. | Hiding.c:33:21:33:22 | g5 | a global variable | | Hiding.c:40:20:40:21 | definition of g5 | Parameter g5 hides a $@ with the same name. | Hiding.c:33:21:33:22 | g5 | global variable |

View File

@@ -1,4 +1,4 @@
| ShortLoopVarName.cpp:6:6:6:6 | i | Iteration variable i for $@ should have a descriptive name, since there is $@. | ShortLoopVarName.cpp:12:2:18:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:14:3:17:3 | for(...;...;...) ... | a nested loop | | ShortLoopVarName.cpp:6:6:6:6 | i | Iteration variable i for $@ should have a descriptive name, since there is a $@. | ShortLoopVarName.cpp:12:2:18:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:14:3:17:3 | for(...;...;...) ... | nested loop |
| ShortLoopVarName.cpp:30:13:30:13 | a | Iteration variable a for $@ should have a descriptive name, since there is $@. | ShortLoopVarName.cpp:30:2:38:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:34:3:37:3 | for(...;...;...) ... | a nested loop | | ShortLoopVarName.cpp:30:13:30:13 | a | Iteration variable a for $@ should have a descriptive name, since there is a $@. | ShortLoopVarName.cpp:30:2:38:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:34:3:37:3 | for(...;...;...) ... | nested loop |
| ShortLoopVarName.cpp:73:11:73:11 | y | Iteration variable y for $@ should have a descriptive name, since there is $@. | ShortLoopVarName.cpp:73:2:80:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:75:3:79:3 | for(...;...;...) ... | a nested loop | | ShortLoopVarName.cpp:73:11:73:11 | y | Iteration variable y for $@ should have a descriptive name, since there is a $@. | ShortLoopVarName.cpp:73:2:80:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:75:3:79:3 | for(...;...;...) ... | nested loop |
| ShortLoopVarName.cpp:96:12:96:12 | i | Iteration variable i for $@ should have a descriptive name, since there is $@. | ShortLoopVarName.cpp:96:3:102:3 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:98:4:101:4 | for(...;...;...) ... | a nested loop | | ShortLoopVarName.cpp:96:12:96:12 | i | Iteration variable i for $@ should have a descriptive name, since there is a $@. | ShortLoopVarName.cpp:96:3:102:3 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:98:4:101:4 | for(...;...;...) ... | nested loop |

View File

@@ -1,9 +1,9 @@
| more_tests.cpp:23:2:23:12 | call to myFunction2 | Calls to $@ should use the value -1 as a terminator (4 calls do). | more_tests.cpp:5:6:5:16 | myFunction2 | myFunction2 | | more_tests.cpp:25:2:25:12 | call to myFunction2 | Calls to $@ should use the value -1 as a terminator (5 of 6 calls do). | more_tests.cpp:5:6:5:16 | myFunction2 | myFunction2 |
| more_tests.cpp:34:2:34:12 | call to myFunction4 | Calls to $@ should use the value 0 as a terminator (3 calls do). | more_tests.cpp:7:6:7:16 | myFunction4 | myFunction4 | | more_tests.cpp:39:2:39:12 | call to myFunction4 | Calls to $@ should use the value 0 as a terminator (5 of 6 calls do). | more_tests.cpp:7:6:7:16 | myFunction4 | myFunction4 |
| more_tests.cpp:44:2:44:12 | call to myFunction6 | Calls to $@ should use the value 0 as a terminator (3 calls do). | more_tests.cpp:9:6:9:16 | myFunction6 | myFunction6 | | more_tests.cpp:49:2:49:12 | call to myFunction6 | Calls to $@ should use the value 0 as a terminator (5 of 6 calls do). | more_tests.cpp:9:6:9:16 | myFunction6 | myFunction6 |
| more_tests.cpp:55:2:55:12 | call to myFunction7 | Calls to $@ should use the value 0 as a terminator (7 calls do). | more_tests.cpp:10:6:10:16 | myFunction7 | myFunction7 | | more_tests.cpp:64:2:64:12 | call to myFunction7 | Calls to $@ should use the value 0 as a terminator (9 of 11 calls do). | more_tests.cpp:10:6:10:16 | myFunction7 | myFunction7 |
| more_tests.cpp:56:2:56:12 | call to myFunction7 | Calls to $@ should use the value 0 as a terminator (7 calls do). | more_tests.cpp:10:6:10:16 | myFunction7 | myFunction7 | | more_tests.cpp:65:2:65:12 | call to myFunction7 | Calls to $@ should use the value 0 as a terminator (9 of 11 calls do). | more_tests.cpp:10:6:10:16 | myFunction7 | myFunction7 |
| tests.c:34:2:34:3 | call to f1 | Calls to $@ should use the value 0 as a terminator (4 calls do). | tests.c:4:6:4:7 | f1 | f1 | | tests.c:34:2:34:3 | call to f1 | Calls to $@ should use the value 0 as a terminator (4 of 5 calls do). | tests.c:4:6:4:7 | f1 | f1 |
| tests.c:67:2:67:3 | call to f6 | Calls to $@ should use the value -1 as a terminator (3 calls do). | tests.c:24:6:24:7 | f6 | f6 | | tests.c:78:2:78:3 | call to f6 | Calls to $@ should use the value -1 as a terminator (10 of 12 calls do). | tests.c:24:6:24:7 | f6 | f6 |
| tests.c:68:2:68:3 | call to f6 | Calls to $@ should use the value -1 as a terminator (3 calls do). | tests.c:24:6:24:7 | f6 | f6 | | tests.c:79:2:79:3 | call to f6 | Calls to $@ should use the value -1 as a terminator (10 of 12 calls do). | tests.c:24:6:24:7 | f6 | f6 |
| tests.c:73:2:73:3 | call to f7 | Calls to $@ should use the value 0 as a terminator (3 calls do). | tests.c:28:6:28:7 | f7 | f7 | | tests.c:84:2:84:3 | call to f7 | Calls to $@ should use the value 0 as a terminator (12 of 13 calls do). | tests.c:28:6:28:7 | f7 | f7 |

View File

@@ -13,27 +13,32 @@ int main()
{ {
int x; int x;
myFunction1("%i", 0); // not common enough to be assumed a terminator myFunction1("%i", 0); // GOOD: not common enough to be assumed a terminator
myFunction1("%i", 0);
myFunction1("%i", x); myFunction1("%i", x);
myFunction2(-1); myFunction2(-1);
myFunction2(0, -1); myFunction2(0, -1);
myFunction2(0, 1, -1); myFunction2(0, 1, -1);
myFunction2(0, 1, 2, -1); myFunction2(0, 1, 2, -1);
myFunction2(0, 1, 2, 3); // missing terminator myFunction2(0, 1, 2, 3, -1);
myFunction2(0, 1, 2, 3, 4); // BAD: missing terminator
myFunction3(-1); myFunction3(-1);
myFunction3(0, -1); myFunction3(0, -1);
myFunction3(-1, 1, -1); // -1 isn't a terminator because it's used in a non-terminal position myFunction3(-1, 1, -1); // GOOD: -1 isn't a terminator because it's used in a non-terminal position
myFunction3(0, 1, 2, -1); myFunction3(0, 1, 2, -1);
myFunction3(0, 1, 2, 3); myFunction3(0, 1, 2, 3, -1);
myFunction3(0, 1, 2, 3, 4);
myFunction4(x, x, 0); myFunction4(x, x, 0);
myFunction4(0, x, 1, 0); myFunction4(0, x, 1, 0);
myFunction4(0, 0, 1, 1, 0); myFunction4(0, 0, 1, 1, 0);
myFunction4(x, 0, 1, 1, 1); // missing terminator myFunction4(0, x, 1, 1, 1, 0);
myFunction4(0, 0, 1, 1, 1, 1, 0);
myFunction4(x, 0, 1, 1, 1, 1, 1); // BAD: missing terminator
myFunction5('a', 'b', 'c', 0); // ambiguous terminator myFunction5('a', 'b', 'c', 0); // GOOD: ambiguous terminator
myFunction5('a', 'b', 'c', 0); myFunction5('a', 'b', 'c', 0);
myFunction5('a', 'b', 'c', 0); myFunction5('a', 'b', 'c', 0);
myFunction5('a', 'b', 'c', -1); myFunction5('a', 'b', 'c', -1);
@@ -41,19 +46,23 @@ int main()
myFunction5('a', 'b', 'c', -1); myFunction5('a', 'b', 'c', -1);
myFunction6(0.0); myFunction6(0.0);
myFunction6(1.0); // missing terminator myFunction6(1.0); // BAD: missing terminator
myFunction6(1.0, 2.0, 0.0); myFunction6(1.0, 2.0, 0.0);
myFunction6(1.0, 2.0, 3.0, 0.0); myFunction6(1.0, 2.0, 3.0, 0.0);
myFunction6(1.0, 2.0, 3.0, 4.0, 0.0);
myFunction6(1.0, 2.0, 3.0, 4.0, 5.0, 0.0);
myFunction7(NULL); myFunction7(NULL);
myFunction7("hello", "world", NULL); myFunction7("hello", "world", NULL);
myFunction7("apple", "banana", "pear", "mango", NULL); myFunction7("apple", "banana", "pear", "mango", NULL);
myFunction7("dog", "cat", "elephant", "badger", "fish", NULL); myFunction7("dog", "cat", "elephant", "badger", "fish", NULL);
myFunction7("one", "two", "three", 0); myFunction7("one", "two", "three", 0);
myFunction7("four", "five", "six", 0);
myFunction7("seven", "eight", "nine", 0);
myFunction7("alpha", "beta", "gamma", 0); myFunction7("alpha", "beta", "gamma", 0);
myFunction7("", 0); myFunction7("", 0);
myFunction7("yes", "no"); // missing terminator myFunction7("yes", "no"); // BAD: missing terminator
myFunction7(); // missing terminator myFunction7(); // BAD: missing terminator
return 0; return 0;
} }

View File

@@ -42,6 +42,7 @@ int main(int argc, char *argv[])
// GOOD: 0 is not common enough to be sure it's a terminator // GOOD: 0 is not common enough to be sure it's a terminator
f3("", 0); f3("", 0);
f3("", 0);
f3("", 10); f3("", 10);
// GOOD: -1 is not common enough to be sure it's a terminator // GOOD: -1 is not common enough to be sure it's a terminator
@@ -50,6 +51,9 @@ int main(int argc, char *argv[])
f4("", -1); f4("", -1);
f4("", -1); f4("", -1);
f4("", -1); f4("", -1);
f4("", -1);
f4("", -1);
f4("", -1);
f4("", 1); f4("", 1);
// GOOD: no obvious required terminator // GOOD: no obvious required terminator
@@ -61,16 +65,32 @@ int main(int argc, char *argv[])
f5("", 0); f5("", 0);
f5("", 10); f5("", 10);
f6("fsdf", 3, 8, -1); f6("a", 3, 8, -1);
f6("a", 7, 9, 10, -1); f6("b", 7, 9, 10, -1);
f6("a", 1, 22, 6, 17, 2, -1); f6("c", 1, 22, 6, 17, 2, -1);
f6("fgasfgas", 5, 6, argc); // BAD: not (necessarily) terminated with -1 f6("d", 1, -1);
f6("sadfsaf"); // BAD: not terminated with -1 f6("e", 1, 2, -1);
f6("f", 1, 2, 3, -1);
f6("g", 1, 2, 3, 4, -1);
f6("h", 5, -1);
f6("i", 5, 6, -1);
f6("j", 5, 6, 7, -1);
f6("k", 5, 6, argc); // BAD: not (necessarily) terminated with -1
f6("l"); // BAD: not terminated with -1
f7("", 0); f7("", 0);
f7("", 0); f7("", 0);
f7("", 0); f7("", 0);
f7(""); // BAD: not terminated with 0 f7(""); // BAD: not terminated with 0
f7("", 0);
f7("", 0);
f7("", 0);
f7("", 0);
f7("", 0);
f7("", 0);
f7("", 0);
f7("", 0);
f7("", 0);
return 0; return 0;
} }

View File

@@ -52,27 +52,27 @@ nodes
| examples.cpp:38:9:38:12 | data | semmle.label | data | | examples.cpp:38:9:38:12 | data | semmle.label | data |
subpaths subpaths
#select #select
| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | | examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value |
| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | | examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value |
| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | | examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value |
| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | | examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value |
| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | | examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value |
| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | | examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value |
| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | | examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value |
| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | | examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value |
| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | | examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value |
| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | | examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value |
| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | | examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value |
| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | | examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value |
| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | | examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value |
| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | | examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value |
| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | | examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value |
| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | | examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value |
| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | | examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value |
| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | | examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value |
| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | | examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value |
| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | | examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value |
| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | | examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value |
| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | | examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value |
| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | | examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value |
| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | | examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value |

View File

@@ -92,31 +92,31 @@ nodes
| test.cpp:219:8:219:8 | x | semmle.label | x | | test.cpp:219:8:219:8 | x | semmle.label | x |
subpaths subpaths
#select #select
| test.c:21:17:21:17 | r | test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:18:13:18:16 | call to rand | uncontrolled value | | test.c:21:17:21:17 | r | test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:18:13:18:16 | call to rand | uncontrolled value |
| test.c:35:5:35:5 | r | test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:34:13:34:18 | call to rand | uncontrolled value | | test.c:35:5:35:5 | r | test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:34:13:34:18 | call to rand | uncontrolled value |
| test.c:45:5:45:5 | r | test.c:44:13:44:16 | call to rand | test.c:45:5:45:5 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:44:13:44:16 | call to rand | uncontrolled value | | test.c:45:5:45:5 | r | test.c:44:13:44:16 | call to rand | test.c:45:5:45:5 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:44:13:44:16 | call to rand | uncontrolled value |
| test.c:77:9:77:9 | r | test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:75:13:75:19 | call to rand | uncontrolled value | | test.c:77:9:77:9 | r | test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:75:13:75:19 | call to rand | uncontrolled value |
| test.c:77:9:77:9 | r | test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:75:13:75:19 | call to rand | uncontrolled value | | test.c:77:9:77:9 | r | test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:75:13:75:19 | call to rand | uncontrolled value |
| test.c:83:9:83:9 | r | test.c:81:14:81:17 | call to rand | test.c:83:9:83:9 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:81:14:81:17 | call to rand | uncontrolled value | | test.c:83:9:83:9 | r | test.c:81:14:81:17 | call to rand | test.c:83:9:83:9 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:81:14:81:17 | call to rand | uncontrolled value |
| test.c:83:9:83:9 | r | test.c:81:23:81:26 | call to rand | test.c:83:9:83:9 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:81:23:81:26 | call to rand | uncontrolled value | | test.c:83:9:83:9 | r | test.c:81:23:81:26 | call to rand | test.c:83:9:83:9 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:81:23:81:26 | call to rand | uncontrolled value |
| test.c:127:9:127:9 | r | test.c:125:13:125:16 | call to rand | test.c:127:9:127:9 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:125:13:125:16 | call to rand | uncontrolled value | | test.c:127:9:127:9 | r | test.c:125:13:125:16 | call to rand | test.c:127:9:127:9 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:125:13:125:16 | call to rand | uncontrolled value |
| test.c:133:5:133:5 | r | test.c:131:13:131:16 | call to rand | test.c:133:5:133:5 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:131:13:131:16 | call to rand | uncontrolled value | | test.c:133:5:133:5 | r | test.c:131:13:131:16 | call to rand | test.c:133:5:133:5 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:131:13:131:16 | call to rand | uncontrolled value |
| test.c:139:10:139:10 | r | test.c:137:13:137:16 | call to rand | test.c:139:10:139:10 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:137:13:137:16 | call to rand | uncontrolled value | | test.c:139:10:139:10 | r | test.c:137:13:137:16 | call to rand | test.c:139:10:139:10 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:137:13:137:16 | call to rand | uncontrolled value |
| test.c:157:9:157:9 | r | test.c:155:22:155:25 | call to rand | test.c:157:9:157:9 | r | Arithmetic expression depends on an $@, potentially causing an underflow. | test.c:155:22:155:25 | call to rand | uncontrolled value | | test.c:157:9:157:9 | r | test.c:155:22:155:25 | call to rand | test.c:157:9:157:9 | r | This arithmetic expression depends on an $@, potentially causing an underflow. | test.c:155:22:155:25 | call to rand | uncontrolled value |
| test.c:157:9:157:9 | r | test.c:155:22:155:27 | (unsigned int)... | test.c:157:9:157:9 | r | Arithmetic expression depends on an $@, potentially causing an underflow. | test.c:155:22:155:25 | call to rand | uncontrolled value | | test.c:157:9:157:9 | r | test.c:155:22:155:27 | (unsigned int)... | test.c:157:9:157:9 | r | This arithmetic expression depends on an $@, potentially causing an underflow. | test.c:155:22:155:25 | call to rand | uncontrolled value |
| test.cpp:25:7:25:7 | r | test.cpp:8:9:8:12 | call to rand | test.cpp:25:7:25:7 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:8:9:8:12 | call to rand | uncontrolled value | | test.cpp:25:7:25:7 | r | test.cpp:8:9:8:12 | call to rand | test.cpp:25:7:25:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:8:9:8:12 | call to rand | uncontrolled value |
| test.cpp:31:7:31:7 | r | test.cpp:13:10:13:13 | call to rand | test.cpp:31:7:31:7 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:13:10:13:13 | call to rand | uncontrolled value | | test.cpp:31:7:31:7 | r | test.cpp:13:10:13:13 | call to rand | test.cpp:31:7:31:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:13:10:13:13 | call to rand | uncontrolled value |
| test.cpp:37:7:37:7 | r | test.cpp:18:9:18:12 | call to rand | test.cpp:37:7:37:7 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:18:9:18:12 | call to rand | uncontrolled value | | test.cpp:37:7:37:7 | r | test.cpp:18:9:18:12 | call to rand | test.cpp:37:7:37:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:18:9:18:12 | call to rand | uncontrolled value |
| test.cpp:90:10:90:10 | x | test.cpp:86:10:86:13 | call to rand | test.cpp:90:10:90:10 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:86:10:86:13 | call to rand | uncontrolled value | | test.cpp:90:10:90:10 | x | test.cpp:86:10:86:13 | call to rand | test.cpp:90:10:90:10 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:86:10:86:13 | call to rand | uncontrolled value |
| test.cpp:102:10:102:10 | x | test.cpp:98:10:98:13 | call to rand | test.cpp:102:10:102:10 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:98:10:98:13 | call to rand | uncontrolled value | | test.cpp:102:10:102:10 | x | test.cpp:98:10:98:13 | call to rand | test.cpp:102:10:102:10 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:98:10:98:13 | call to rand | uncontrolled value |
| test.cpp:146:9:146:9 | y | test.cpp:137:10:137:13 | call to rand | test.cpp:146:9:146:9 | y | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:137:10:137:13 | call to rand | uncontrolled value | | test.cpp:146:9:146:9 | y | test.cpp:137:10:137:13 | call to rand | test.cpp:146:9:146:9 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:137:10:137:13 | call to rand | uncontrolled value |
| test.cpp:154:10:154:10 | b | test.cpp:151:10:151:13 | call to rand | test.cpp:154:10:154:10 | b | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:151:10:151:13 | call to rand | uncontrolled value | | test.cpp:154:10:154:10 | b | test.cpp:151:10:151:13 | call to rand | test.cpp:154:10:154:10 | b | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:151:10:151:13 | call to rand | uncontrolled value |
| test.cpp:171:11:171:16 | (int)... | test.cpp:169:11:169:14 | call to rand | test.cpp:171:11:171:16 | (int)... | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:169:11:169:14 | call to rand | uncontrolled value | | test.cpp:171:11:171:16 | (int)... | test.cpp:169:11:169:14 | call to rand | test.cpp:171:11:171:16 | (int)... | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:169:11:169:14 | call to rand | uncontrolled value |
| test.cpp:171:16:171:16 | y | test.cpp:169:11:169:14 | call to rand | test.cpp:171:16:171:16 | y | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:169:11:169:14 | call to rand | uncontrolled value | | test.cpp:171:16:171:16 | y | test.cpp:169:11:169:14 | call to rand | test.cpp:171:16:171:16 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:169:11:169:14 | call to rand | uncontrolled value |
| test.cpp:196:7:196:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:196:7:196:7 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value | | test.cpp:196:7:196:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:196:7:196:7 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value |
| test.cpp:198:7:198:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:198:7:198:7 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value | | test.cpp:198:7:198:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:198:7:198:7 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value |
| test.cpp:199:7:199:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:199:7:199:7 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value | | test.cpp:199:7:199:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:199:7:199:7 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value |
| test.cpp:204:7:204:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:204:7:204:7 | y | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value | | test.cpp:204:7:204:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:204:7:204:7 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value |
| test.cpp:205:7:205:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:205:7:205:7 | y | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value | | test.cpp:205:7:205:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:205:7:205:7 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value |
| test.cpp:208:7:208:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:208:7:208:7 | y | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value | | test.cpp:208:7:208:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:208:7:208:7 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value |
| test.cpp:219:8:219:8 | x | test.cpp:215:11:215:14 | call to rand | test.cpp:219:8:219:8 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:215:11:215:14 | call to rand | uncontrolled value | | test.cpp:219:8:219:8 | x | test.cpp:215:11:215:14 | call to rand | test.cpp:219:8:219:8 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:215:11:215:14 | call to rand | uncontrolled value |

View File

@@ -1,3 +1,7 @@
## 1.3.1
No user-facing changes.
## 1.3.0 ## 1.3.0
No user-facing changes. No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 1.3.1
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 1.3.0 lastReleaseVersion: 1.3.1

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-all name: codeql/csharp-solorigate-all
version: 1.3.1-dev version: 1.3.2-dev
groups: groups:
- csharp - csharp
- solorigate - solorigate

View File

@@ -1,3 +1,7 @@
## 1.3.1
No user-facing changes.
## 1.3.0 ## 1.3.0
No user-facing changes. No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 1.3.1
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 1.3.0 lastReleaseVersion: 1.3.1

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-queries name: codeql/csharp-solorigate-queries
version: 1.3.1-dev version: 1.3.2-dev
groups: groups:
- csharp - csharp
- solorigate - solorigate

View File

@@ -1,3 +1,10 @@
## 0.4.1
### Minor Analysis Improvements
* `DateTime` expressions are now considered simple type sanitizers. This affects a wide range of security queries.
* ASP.NET Core controller definition has been made more precise. The amount of introduced taint sources or eliminated false positives should be low though, since the most common pattern is to derive all user defined ASP.NET Core controllers from the standard Controller class, which is not affected.
## 0.4.0 ## 0.4.0
### Deprecated APIs ### Deprecated APIs

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* `DateTime` expressions are now considered simple type sanitizers. This affects a wide range of security queries.

View File

@@ -1,4 +1,6 @@
--- ## 0.4.1
category: minorAnalysis
--- ### Minor Analysis Improvements
* `DateTime` expressions are now considered simple type sanitizers. This affects a wide range of security queries.
* ASP.NET Core controller definition has been made more precise. The amount of introduced taint sources or eliminated false positives should be low though, since the most common pattern is to derive all user defined ASP.NET Core controllers from the standard Controller class, which is not affected. * ASP.NET Core controller definition has been made more precise. The amount of introduced taint sources or eliminated false positives should be low though, since the most common pattern is to derive all user defined ASP.NET Core controllers from the standard Controller class, which is not affected.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.4.0 lastReleaseVersion: 0.4.1

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-all name: codeql/csharp-all
version: 0.4.1-dev version: 0.4.2-dev
groups: csharp groups: csharp
dbscheme: semmlecode.csharp.dbscheme dbscheme: semmlecode.csharp.dbscheme
extractor: csharp extractor: csharp

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -1,3 +1,9 @@
## 0.4.1
### Minor Analysis Improvements
* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages.
## 0.4.0 ## 0.4.0
### Minor Analysis Improvements ### Minor Analysis Improvements

View File

@@ -1,4 +1,5 @@
--- ## 0.4.1
category: minorAnalysis
--- ### Minor Analysis Improvements
* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. * The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.4.0 lastReleaseVersion: 0.4.1

View File

@@ -19,5 +19,5 @@ import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph
from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink
where c.hasFlowPath(source, sink) where c.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "$@ flows to here and is used in a method of WebClient.", select sink.getNode(), source, sink, "A method of WebClient depepends on a $@.", source.getNode(),
source.getNode(), "User-provided value" "user-provided value"

View File

@@ -17,5 +17,6 @@ import JsonWebTokenHandlerLib
from TokenValidationParametersProperty p, CallableAlwaysReturnsTrueHigherPrecision e from TokenValidationParametersProperty p, CallableAlwaysReturnsTrueHigherPrecision e
where e = p.getAnAssignedValue() where e = p.getAnAssignedValue()
select e, "JsonWebTokenHandler security-sensitive property $@ is being delegated to $@.", p, select e,
p.getQualifiedName().toString(), e, "a callable that always returns \"true\"" "JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns \"true\".",
p, p.getQualifiedName().toString()

View File

@@ -50,5 +50,5 @@ predicate isSuspiciousPropertyName(PropertyRead pr) {
from DataFlow::PathNode src, DataFlow::PathNode sink, DataFlowFromMethodToHash conf from DataFlow::PathNode src, DataFlow::PathNode sink, DataFlowFromMethodToHash conf
where conf.hasFlow(src.getNode(), sink.getNode()) where conf.hasFlow(src.getNode(), sink.getNode())
select src.getNode(), src, sink, select src.getNode(), src, sink,
"The hash is calculated on the process name $@, may be related to a backdoor. Please review the code for possible malicious intent.", "The hash is calculated on $@, may be related to a backdoor. Please review the code for possible malicious intent.",
sink.getNode(), "here" sink.getNode(), "this process name"

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-queries name: codeql/csharp-queries
version: 0.4.1-dev version: 0.4.2-dev
groups: groups:
- csharp - csharp
- queries - queries

View File

@@ -1,7 +1,7 @@
| delegation-test.cs:101:63:101:186 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:54:34:54:50 | LifetimeValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.LifetimeValidator | delegation-test.cs:101:63:101:186 | (...) => ... | a callable that always returns "true" | | delegation-test.cs:101:63:101:186 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:54:34:54:50 | LifetimeValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.LifetimeValidator |
| delegation-test.cs:102:63:102:178 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:102:63:102:178 | (...) => ... | a callable that always returns "true" | | delegation-test.cs:102:63:102:178 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator |
| delegation-test.cs:115:63:115:190 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:115:63:115:190 | (...) => ... | a callable that always returns "true" | | delegation-test.cs:115:63:115:190 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator |
| delegation-test.cs:116:63:116:180 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:116:63:116:180 | (...) => ... | a callable that always returns "true" | | delegation-test.cs:116:63:116:180 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator |
| delegation-test.cs:117:63:117:217 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:117:63:117:217 | (...) => ... | a callable that always returns "true" | | delegation-test.cs:117:63:117:217 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator |
| delegation-test.cs:118:63:118:248 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:118:63:118:248 | (...) => ... | a callable that always returns "true" | | delegation-test.cs:118:63:118:248 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator |
| delegation-test.cs:119:63:119:177 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:119:63:119:177 | (...) => ... | a callable that always returns "true" | | delegation-test.cs:119:63:119:177 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator |

View File

@@ -1,3 +1,9 @@
## 0.3.1
### Minor Analysis Improvements
* Added support for `BeegoInput.RequestBody` as a source of untrusted data.
## 0.3.0 ## 0.3.0
### Deprecated APIs ### Deprecated APIs

View File

@@ -1,4 +1,5 @@
--- ## 0.3.1
category: minorAnalysis
--- ### Minor Analysis Improvements
* Added support for `BeegoInput.RequestBody` as a source of untrusted data. * Added support for `BeegoInput.RequestBody` as a source of untrusted data.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.3.0 lastReleaseVersion: 0.3.1

View File

@@ -1,5 +1,5 @@
name: codeql/go-all name: codeql/go-all
version: 0.3.1-dev version: 0.3.2-dev
groups: go groups: go
dbscheme: go.dbscheme dbscheme: go.dbscheme
extractor: go extractor: go

View File

@@ -64,7 +64,7 @@ module InsecureRandomness {
) )
} }
override string getKind() { result = "this cryptographic algorithm" } override string getKind() { result = "This cryptographic algorithm" }
} }
/** /**
@@ -75,7 +75,7 @@ module InsecureRandomness {
this.getRoot().(FuncDef).getName().regexpMatch("(?i).*(gen(erate)?|salt|make|mk)Password.*") this.getRoot().(FuncDef).getName().regexpMatch("(?i).*(gen(erate)?|salt|make|mk)Password.*")
} }
override string getKind() { result = "a password-related function" } override string getKind() { result = "A password-related function" }
} }
/** Gets a package that implements hash algorithms. */ /** Gets a package that implements hash algorithms. */

View File

@@ -1,3 +1,7 @@
## 0.3.1
No user-facing changes.
## 0.3.0 ## 0.3.0
### Query Metadata Changes ### Query Metadata Changes

View File

@@ -61,4 +61,4 @@ where
// } // }
n = DataFlow::BarrierGuard<nilTestGuard/3>::getABarrierNode() n = DataFlow::BarrierGuard<nilTestGuard/3>::getABarrierNode()
) )
select n, "The first argument to 'errors.Wrap' is always nil" select n, "The first argument to 'errors.Wrap' is always nil."

View File

@@ -48,5 +48,5 @@ class Config extends DataFlow::Configuration {
from Config c, DataFlow::PathNode source, DataFlow::PathNode sink, string report from Config c, DataFlow::PathNode source, DataFlow::PathNode sink, string report
where c.hasFlowPath(source, sink) and c.isSource(source.getNode(), report) where c.hasFlowPath(source, sink) and c.isSource(source.getNode(), report)
select source, source, sink, "$@ that is $@ contains " + report, source, "A string literal", sink, select source, source, sink, "This string literal that is $@ contains " + report, sink,
"used as a regular expression" "used as a regular expression"

View File

@@ -17,5 +17,5 @@ import DataFlow::PathGraph
from LogInjection::Configuration c, DataFlow::PathNode source, DataFlow::PathNode sink from LogInjection::Configuration c, DataFlow::PathNode source, DataFlow::PathNode sink
where c.hasFlowPath(source, sink) where c.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Log entry depends on a $@.", source.getNode(), select sink.getNode(), source, sink, "This log entry depends on a $@.", source.getNode(),
"user-provided value" "user-provided value"

View File

@@ -19,7 +19,7 @@ where
cfg.hasFlowPath(source, sink) and cfg.hasFlowPath(source, sink) and
cfg.isSink(sink.getNode(), kind) and cfg.isSink(sink.getNode(), kind) and
( (
kind != "a password-related function" kind != "A password-related function"
or or
sink = sink =
min(DataFlow::PathNode sink2, int line | min(DataFlow::PathNode sink2, int line |
@@ -31,5 +31,5 @@ where
) )
) )
select sink.getNode(), source, sink, select sink.getNode(), source, sink,
"$@ generated with a cryptographically weak RNG is used in $@.", source.getNode(), kind + " depends on a $@ generated with a cryptographically weak RNG.", source.getNode(),
"A random number", sink.getNode(), kind "random number"

View File

@@ -0,0 +1,3 @@
## 0.3.1
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.3.0 lastReleaseVersion: 0.3.1

View File

@@ -54,5 +54,4 @@ class DivideByZeroCheckConfig extends TaintTracking::Configuration {
from DataFlow::PathNode source, DataFlow::PathNode sink, DivideByZeroCheckConfig cfg from DataFlow::PathNode source, DataFlow::PathNode sink, DivideByZeroCheckConfig cfg
where cfg.hasFlowPath(source, sink) where cfg.hasFlowPath(source, sink)
select sink, source, sink, "Variable $@ might be zero leading to a division-by-zero panic.", sink, select sink, source, sink, "This variable might be zero leading to a division-by-zero panic."
sink.getNode().toString()

View File

@@ -66,4 +66,4 @@ query predicate edges(CallGraphNode pred, CallGraphNode succ) {
from LoopStmt loop, DatabaseAccess dbAccess from LoopStmt loop, DatabaseAccess dbAccess
where edges*(loop, dbAccess.asExpr()) where edges*(loop, dbAccess.asExpr())
select dbAccess, loop, dbAccess, "$@ is called in $@", dbAccess, dbAccess.toString(), loop, "a loop" select dbAccess, loop, dbAccess, "This calls " + dbAccess.toString() + " in a $@.", loop, "loop"

View File

@@ -19,4 +19,4 @@ from
where where
cfg.hasFlowPath(source, sink) and cfg.hasFlowPath(source, sink) and
request = sink.getNode().(ServerSideRequestForgery::Sink).getARequest() request = sink.getNode().(ServerSideRequestForgery::Sink).getARequest()
select request, source, sink, "The URL of this request depends on a user-provided value" select request, source, sink, "The URL of this request depends on a user-provided value."

View File

@@ -11,4 +11,4 @@ import RangeAnalysis
from Expr expr from Expr expr
where exprMayOverflow(expr) or exprMayUnderflow(expr) where exprMayOverflow(expr) or exprMayUnderflow(expr)
select expr, "this expression may cause an integer overflow" select expr, "This expression may cause an integer overflow."

View File

@@ -1,5 +1,5 @@
name: codeql/go-queries name: codeql/go-queries
version: 0.3.1-dev version: 0.3.2-dev
groups: groups:
- go - go
- queries - queries

View File

@@ -24,9 +24,9 @@ nodes
| DivideByZero.go:57:17:57:21 | value | semmle.label | value | | DivideByZero.go:57:17:57:21 | value | semmle.label | value |
subpaths subpaths
#select #select
| DivideByZero.go:12:16:12:20 | value | DivideByZero.go:10:12:10:16 | selection of URL : pointer type | DivideByZero.go:12:16:12:20 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:12:16:12:20 | value | value | | DivideByZero.go:12:16:12:20 | value | DivideByZero.go:10:12:10:16 | selection of URL : pointer type | DivideByZero.go:12:16:12:20 | value | This variable might be zero leading to a division-by-zero panic. |
| DivideByZero.go:19:16:19:20 | value | DivideByZero.go:17:12:17:16 | selection of URL : pointer type | DivideByZero.go:19:16:19:20 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:19:16:19:20 | value | value | | DivideByZero.go:19:16:19:20 | value | DivideByZero.go:17:12:17:16 | selection of URL : pointer type | DivideByZero.go:19:16:19:20 | value | This variable might be zero leading to a division-by-zero panic. |
| DivideByZero.go:26:16:26:20 | value | DivideByZero.go:24:12:24:16 | selection of URL : pointer type | DivideByZero.go:26:16:26:20 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:26:16:26:20 | value | value | | DivideByZero.go:26:16:26:20 | value | DivideByZero.go:24:12:24:16 | selection of URL : pointer type | DivideByZero.go:26:16:26:20 | value | This variable might be zero leading to a division-by-zero panic. |
| DivideByZero.go:33:16:33:20 | value | DivideByZero.go:31:12:31:16 | selection of URL : pointer type | DivideByZero.go:33:16:33:20 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:33:16:33:20 | value | value | | DivideByZero.go:33:16:33:20 | value | DivideByZero.go:31:12:31:16 | selection of URL : pointer type | DivideByZero.go:33:16:33:20 | value | This variable might be zero leading to a division-by-zero panic. |
| DivideByZero.go:40:16:40:20 | value | DivideByZero.go:38:12:38:16 | selection of URL : pointer type | DivideByZero.go:40:16:40:20 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:40:16:40:20 | value | value | | DivideByZero.go:40:16:40:20 | value | DivideByZero.go:38:12:38:16 | selection of URL : pointer type | DivideByZero.go:40:16:40:20 | value | This variable might be zero leading to a division-by-zero panic. |
| DivideByZero.go:57:17:57:21 | value | DivideByZero.go:54:12:54:16 | selection of URL : pointer type | DivideByZero.go:57:17:57:21 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:57:17:57:21 | value | value | | DivideByZero.go:57:17:57:21 | value | DivideByZero.go:54:12:54:16 | selection of URL : pointer type | DivideByZero.go:57:17:57:21 | value | This variable might be zero leading to a division-by-zero panic. |

View File

@@ -8,6 +8,6 @@ edges
| test.go:24:2:26:2 | for statement | test.go:25:3:25:17 | call to runRunQuery | | test.go:24:2:26:2 | for statement | test.go:25:3:25:17 | call to runRunQuery |
| test.go:25:3:25:17 | call to runRunQuery | test.go:14:1:16:1 | function declaration | | test.go:25:3:25:17 | call to runRunQuery | test.go:14:1:16:1 | function declaration |
#select #select
| DatabaseCallInLoop.go:9:3:9:41 | call to First | DatabaseCallInLoop.go:7:2:11:2 | range statement | DatabaseCallInLoop.go:9:3:9:41 | call to First | $@ is called in $@ | DatabaseCallInLoop.go:9:3:9:41 | call to First | call to First | DatabaseCallInLoop.go:7:2:11:2 | range statement | a loop | | DatabaseCallInLoop.go:9:3:9:41 | call to First | DatabaseCallInLoop.go:7:2:11:2 | range statement | DatabaseCallInLoop.go:9:3:9:41 | call to First | This calls call to First in a $@. | DatabaseCallInLoop.go:7:2:11:2 | range statement | loop |
| test.go:11:2:11:13 | call to Take | test.go:20:2:22:2 | for statement | test.go:11:2:11:13 | call to Take | $@ is called in $@ | test.go:11:2:11:13 | call to Take | call to Take | test.go:20:2:22:2 | for statement | a loop | | test.go:11:2:11:13 | call to Take | test.go:20:2:22:2 | for statement | test.go:11:2:11:13 | call to Take | This calls call to Take in a $@. | test.go:20:2:22:2 | for statement | loop |
| test.go:11:2:11:13 | call to Take | test.go:24:2:26:2 | for statement | test.go:11:2:11:13 | call to Take | $@ is called in $@ | test.go:11:2:11:13 | call to Take | call to Take | test.go:24:2:26:2 | for statement | a loop | | test.go:11:2:11:13 | call to Take | test.go:24:2:26:2 | for statement | test.go:11:2:11:13 | call to Take | This calls call to Take in a $@. | test.go:24:2:26:2 | for statement | loop |

View File

@@ -55,20 +55,20 @@ nodes
| new-tests.go:96:11:96:46 | ...+... | semmle.label | ...+... | | new-tests.go:96:11:96:46 | ...+... | semmle.label | ...+... |
subpaths subpaths
#select #select
| builtin.go:22:12:22:63 | call to Get | builtin.go:19:12:19:34 | call to FormValue : string | builtin.go:22:21:22:62 | ...+... | The URL of this request depends on a user-provided value | | builtin.go:22:12:22:63 | call to Get | builtin.go:19:12:19:34 | call to FormValue : string | builtin.go:22:21:22:62 | ...+... | The URL of this request depends on a user-provided value. |
| builtin.go:88:12:88:53 | call to Dial | builtin.go:83:21:83:31 | call to Referer : string | builtin.go:88:27:88:40 | untrustedInput | The URL of this request depends on a user-provided value | | builtin.go:88:12:88:53 | call to Dial | builtin.go:83:21:83:31 | call to Referer : string | builtin.go:88:27:88:40 | untrustedInput | The URL of this request depends on a user-provided value. |
| builtin.go:102:13:102:40 | call to DialConfig | builtin.go:97:21:97:31 | call to Referer : string | builtin.go:101:36:101:49 | untrustedInput | The URL of this request depends on a user-provided value | | builtin.go:102:13:102:40 | call to DialConfig | builtin.go:97:21:97:31 | call to Referer : string | builtin.go:101:36:101:49 | untrustedInput | The URL of this request depends on a user-provided value. |
| builtin.go:114:3:114:39 | call to Dial | builtin.go:111:21:111:31 | call to Referer : string | builtin.go:114:15:114:28 | untrustedInput | The URL of this request depends on a user-provided value | | builtin.go:114:3:114:39 | call to Dial | builtin.go:111:21:111:31 | call to Referer : string | builtin.go:114:15:114:28 | untrustedInput | The URL of this request depends on a user-provided value. |
| builtin.go:132:3:132:62 | call to DialContext | builtin.go:129:21:129:31 | call to Referer : string | builtin.go:132:38:132:51 | untrustedInput | The URL of this request depends on a user-provided value | | builtin.go:132:3:132:62 | call to DialContext | builtin.go:129:21:129:31 | call to Referer : string | builtin.go:132:38:132:51 | untrustedInput | The URL of this request depends on a user-provided value. |
| new-tests.go:31:2:31:58 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:31:11:31:57 | call to Sprintf | The URL of this request depends on a user-provided value | | new-tests.go:31:2:31:58 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:31:11:31:57 | call to Sprintf | The URL of this request depends on a user-provided value. |
| new-tests.go:32:2:32:58 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:32:11:32:57 | call to Sprintf | The URL of this request depends on a user-provided value | | new-tests.go:32:2:32:58 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:32:11:32:57 | call to Sprintf | The URL of this request depends on a user-provided value. |
| new-tests.go:35:3:35:59 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:35:12:35:58 | call to Sprintf | The URL of this request depends on a user-provided value | | new-tests.go:35:3:35:59 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:35:12:35:58 | call to Sprintf | The URL of this request depends on a user-provided value. |
| new-tests.go:47:2:47:47 | call to Get | new-tests.go:39:18:39:30 | call to Param : string | new-tests.go:47:11:47:46 | ...+... | The URL of this request depends on a user-provided value | | new-tests.go:47:2:47:47 | call to Get | new-tests.go:39:18:39:30 | call to Param : string | new-tests.go:47:11:47:46 | ...+... | The URL of this request depends on a user-provided value. |
| new-tests.go:50:2:50:47 | call to Get | new-tests.go:49:18:49:30 | call to Query : string | new-tests.go:50:11:50:46 | ...+... | The URL of this request depends on a user-provided value | | new-tests.go:50:2:50:47 | call to Get | new-tests.go:49:18:49:30 | call to Query : string | new-tests.go:50:11:50:46 | ...+... | The URL of this request depends on a user-provided value. |
| new-tests.go:68:2:68:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:68:11:68:57 | call to Sprintf | The URL of this request depends on a user-provided value | | new-tests.go:68:2:68:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:68:11:68:57 | call to Sprintf | The URL of this request depends on a user-provided value. |
| new-tests.go:69:2:69:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:69:11:69:57 | call to Sprintf | The URL of this request depends on a user-provided value | | new-tests.go:69:2:69:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:69:11:69:57 | call to Sprintf | The URL of this request depends on a user-provided value. |
| new-tests.go:74:3:74:59 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:74:12:74:58 | call to Sprintf | The URL of this request depends on a user-provided value | | new-tests.go:74:3:74:59 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:74:12:74:58 | call to Sprintf | The URL of this request depends on a user-provided value. |
| new-tests.go:79:2:79:47 | call to Get | new-tests.go:78:18:78:24 | selection of URL : pointer type | new-tests.go:79:11:79:46 | ...+... | The URL of this request depends on a user-provided value | | new-tests.go:79:2:79:47 | call to Get | new-tests.go:78:18:78:24 | selection of URL : pointer type | new-tests.go:79:11:79:46 | ...+... | The URL of this request depends on a user-provided value. |
| new-tests.go:82:2:82:47 | call to Get | new-tests.go:81:37:81:43 | selection of URL : pointer type | new-tests.go:82:11:82:46 | ...+... | The URL of this request depends on a user-provided value | | new-tests.go:82:2:82:47 | call to Get | new-tests.go:81:37:81:43 | selection of URL : pointer type | new-tests.go:82:11:82:46 | ...+... | The URL of this request depends on a user-provided value. |
| new-tests.go:88:2:88:47 | call to Get | new-tests.go:86:10:86:20 | call to Vars : map type | new-tests.go:88:11:88:46 | ...+... | The URL of this request depends on a user-provided value | | new-tests.go:88:2:88:47 | call to Get | new-tests.go:86:10:86:20 | call to Vars : map type | new-tests.go:88:11:88:46 | ...+... | The URL of this request depends on a user-provided value. |
| new-tests.go:96:2:96:47 | call to Get | new-tests.go:95:18:95:45 | call to URLParam : string | new-tests.go:96:11:96:46 | ...+... | The URL of this request depends on a user-provided value | | new-tests.go:96:2:96:47 | call to Get | new-tests.go:95:18:95:45 | call to URLParam : string | new-tests.go:96:11:96:46 | ...+... | The URL of this request depends on a user-provided value. |

View File

@@ -1,4 +1,4 @@
| WrappedErrorAlwaysNil.go:31:22:31:24 | err | The first argument to 'errors.Wrap' is always nil | | WrappedErrorAlwaysNil.go:31:22:31:24 | err | The first argument to 'errors.Wrap' is always nil. |
| WrappedErrorAlwaysNil.go:41:14:41:16 | nil | The first argument to 'errors.Wrap' is always nil | | WrappedErrorAlwaysNil.go:41:14:41:16 | nil | The first argument to 'errors.Wrap' is always nil. |
| WrappedErrorAlwaysNil.go:45:14:45:16 | err | The first argument to 'errors.Wrap' is always nil | | WrappedErrorAlwaysNil.go:45:14:45:16 | err | The first argument to 'errors.Wrap' is always nil. |
| WrappedErrorAlwaysNil.go:49:14:49:21 | localErr | The first argument to 'errors.Wrap' is always nil | | WrappedErrorAlwaysNil.go:49:14:49:21 | localErr | The first argument to 'errors.Wrap' is always nil. |

View File

@@ -13,14 +13,14 @@ nodes
| test.go:23:21:23:36 | "hello\\\\\\bworld" | semmle.label | "hello\\\\\\bworld" | | test.go:23:21:23:36 | "hello\\\\\\bworld" | semmle.label | "hello\\\\\\bworld" |
subpaths subpaths
#select #select
| SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | $@ that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | A string literal | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | used as a regular expression | | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | This string literal that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | used as a regular expression |
| test.go:7:21:7:24 | "\\a" | test.go:7:21:7:24 | "\\a" | test.go:7:21:7:24 | "\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:7:21:7:24 | "\\a" | A string literal | test.go:7:21:7:24 | "\\a" | used as a regular expression | | test.go:7:21:7:24 | "\\a" | test.go:7:21:7:24 | "\\a" | test.go:7:21:7:24 | "\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:7:21:7:24 | "\\a" | used as a regular expression |
| test.go:9:21:9:26 | "\\\\\\a" | test.go:9:21:9:26 | "\\\\\\a" | test.go:9:21:9:26 | "\\\\\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:9:21:9:26 | "\\\\\\a" | A string literal | test.go:9:21:9:26 | "\\\\\\a" | used as a regular expression | | test.go:9:21:9:26 | "\\\\\\a" | test.go:9:21:9:26 | "\\\\\\a" | test.go:9:21:9:26 | "\\\\\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:9:21:9:26 | "\\\\\\a" | used as a regular expression |
| test.go:10:21:10:27 | "x\\\\\\a" | test.go:10:21:10:27 | "x\\\\\\a" | test.go:10:21:10:27 | "x\\\\\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:10:21:10:27 | "x\\\\\\a" | A string literal | test.go:10:21:10:27 | "x\\\\\\a" | used as a regular expression | | test.go:10:21:10:27 | "x\\\\\\a" | test.go:10:21:10:27 | "x\\\\\\a" | test.go:10:21:10:27 | "x\\\\\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:10:21:10:27 | "x\\\\\\a" | used as a regular expression |
| test.go:12:21:12:28 | "\\\\\\\\\\a" | test.go:12:21:12:28 | "\\\\\\\\\\a" | test.go:12:21:12:28 | "\\\\\\\\\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:12:21:12:28 | "\\\\\\\\\\a" | A string literal | test.go:12:21:12:28 | "\\\\\\\\\\a" | used as a regular expression | | test.go:12:21:12:28 | "\\\\\\\\\\a" | test.go:12:21:12:28 | "\\\\\\\\\\a" | test.go:12:21:12:28 | "\\\\\\\\\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:12:21:12:28 | "\\\\\\\\\\a" | used as a regular expression |
| test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | A string literal | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | used as a regular expression | | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | used as a regular expression |
| test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | A string literal | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | used as a regular expression | | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | used as a regular expression |
| test.go:20:21:20:34 | "hello\\aworld" | test.go:20:21:20:34 | "hello\\aworld" | test.go:20:21:20:34 | "hello\\aworld" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:20:21:20:34 | "hello\\aworld" | A string literal | test.go:20:21:20:34 | "hello\\aworld" | used as a regular expression | | test.go:20:21:20:34 | "hello\\aworld" | test.go:20:21:20:34 | "hello\\aworld" | test.go:20:21:20:34 | "hello\\aworld" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:20:21:20:34 | "hello\\aworld" | used as a regular expression |
| test.go:21:21:21:36 | "hello\\\\\\aworld" | test.go:21:21:21:36 | "hello\\\\\\aworld" | test.go:21:21:21:36 | "hello\\\\\\aworld" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:21:21:21:36 | "hello\\\\\\aworld" | A string literal | test.go:21:21:21:36 | "hello\\\\\\aworld" | used as a regular expression | | test.go:21:21:21:36 | "hello\\\\\\aworld" | test.go:21:21:21:36 | "hello\\\\\\aworld" | test.go:21:21:21:36 | "hello\\\\\\aworld" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:21:21:21:36 | "hello\\\\\\aworld" | used as a regular expression |
| test.go:22:21:22:34 | "hello\\bworld" | test.go:22:21:22:34 | "hello\\bworld" | test.go:22:21:22:34 | "hello\\bworld" | $@ that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | test.go:22:21:22:34 | "hello\\bworld" | A string literal | test.go:22:21:22:34 | "hello\\bworld" | used as a regular expression | | test.go:22:21:22:34 | "hello\\bworld" | test.go:22:21:22:34 | "hello\\bworld" | test.go:22:21:22:34 | "hello\\bworld" | This string literal that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | test.go:22:21:22:34 | "hello\\bworld" | used as a regular expression |
| test.go:23:21:23:36 | "hello\\\\\\bworld" | test.go:23:21:23:36 | "hello\\\\\\bworld" | test.go:23:21:23:36 | "hello\\\\\\bworld" | $@ that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | test.go:23:21:23:36 | "hello\\\\\\bworld" | A string literal | test.go:23:21:23:36 | "hello\\\\\\bworld" | used as a regular expression | | test.go:23:21:23:36 | "hello\\\\\\bworld" | test.go:23:21:23:36 | "hello\\\\\\bworld" | test.go:23:21:23:36 | "hello\\\\\\bworld" | This string literal that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | test.go:23:21:23:36 | "hello\\\\\\bworld" | used as a regular expression |

View File

@@ -20,8 +20,8 @@ nodes
| sample.go:47:17:47:39 | call to Intn | semmle.label | call to Intn | | sample.go:47:17:47:39 | call to Intn | semmle.label | call to Intn |
subpaths subpaths
#select #select
| InsecureRandomness.go:12:18:12:40 | call to Intn | InsecureRandomness.go:12:18:12:40 | call to Intn | InsecureRandomness.go:12:18:12:40 | call to Intn | $@ generated with a cryptographically weak RNG is used in $@. | InsecureRandomness.go:12:18:12:40 | call to Intn | A random number | InsecureRandomness.go:12:18:12:40 | call to Intn | a password-related function | | InsecureRandomness.go:12:18:12:40 | call to Intn | InsecureRandomness.go:12:18:12:40 | call to Intn | InsecureRandomness.go:12:18:12:40 | call to Intn | A password-related function depends on a $@ generated with a cryptographically weak RNG. | InsecureRandomness.go:12:18:12:40 | call to Intn | random number |
| sample.go:26:25:26:30 | call to Guid | sample.go:15:49:15:61 | call to Uint32 : uint32 | sample.go:26:25:26:30 | call to Guid | $@ generated with a cryptographically weak RNG is used in $@. | sample.go:15:49:15:61 | call to Uint32 | A random number | sample.go:26:25:26:30 | call to Guid | this cryptographic algorithm | | sample.go:26:25:26:30 | call to Guid | sample.go:15:49:15:61 | call to Uint32 : uint32 | sample.go:26:25:26:30 | call to Guid | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:15:49:15:61 | call to Uint32 | random number |
| sample.go:37:25:37:29 | nonce | sample.go:34:12:34:40 | call to New : pointer type | sample.go:37:25:37:29 | nonce | $@ generated with a cryptographically weak RNG is used in $@. | sample.go:34:12:34:40 | call to New | A random number | sample.go:37:25:37:29 | nonce | this cryptographic algorithm | | sample.go:37:25:37:29 | nonce | sample.go:34:12:34:40 | call to New : pointer type | sample.go:37:25:37:29 | nonce | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:34:12:34:40 | call to New | random number |
| sample.go:37:32:37:36 | nonce | sample.go:34:12:34:40 | call to New : pointer type | sample.go:37:32:37:36 | nonce | $@ generated with a cryptographically weak RNG is used in $@. | sample.go:34:12:34:40 | call to New | A random number | sample.go:37:32:37:36 | nonce | this cryptographic algorithm | | sample.go:37:32:37:36 | nonce | sample.go:34:12:34:40 | call to New : pointer type | sample.go:37:32:37:36 | nonce | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:34:12:34:40 | call to New | random number |
| sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | $@ generated with a cryptographically weak RNG is used in $@. | sample.go:43:17:43:39 | call to Intn | A random number | sample.go:43:17:43:39 | call to Intn | a password-related function | | sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | A password-related function depends on a $@ generated with a cryptographically weak RNG. | sample.go:43:17:43:39 | call to Intn | random number |

View File

@@ -25,6 +25,8 @@ def parse_args():
dest='many', help='Build for a single version/kind') dest='many', help='Build for a single version/kind')
parser.add_argument('--single-version', parser.add_argument('--single-version',
help='Build for a specific version/kind') help='Build for a specific version/kind')
parser.add_argument('--single-version-embeddable', action='store_true',
help='When building a single version, build an embeddable extractor (default is standalone)')
return parser.parse_args() return parser.parse_args()
@@ -235,7 +237,13 @@ def compile_standalone(version):
if args.single_version: if args.single_version:
if args.single_version_embeddable == True:
compile_embeddable(args.single_version)
else:
compile_standalone(args.single_version) compile_standalone(args.single_version)
elif args.single_version_embeddable == True:
print("--single-version-embeddable requires --single-version", file=sys.stderr)
sys.exit(1)
elif args.many: elif args.many:
for version in kotlin_plugin_versions.many_versions: for version in kotlin_plugin_versions.many_versions:
compile_standalone(version) compile_standalone(version)

View File

@@ -155,7 +155,7 @@ open class KotlinFileExtractor(
is IrEnumEntry -> { is IrEnumEntry -> {
val parentId = useDeclarationParent(declaration.parent, false)?.cast<DbReftype>() val parentId = useDeclarationParent(declaration.parent, false)?.cast<DbReftype>()
if (parentId != null) { if (parentId != null) {
extractEnumEntry(declaration, parentId, extractFunctionBodies) extractEnumEntry(declaration, parentId, extractPrivateMembers, extractFunctionBodies)
} }
Unit Unit
} }
@@ -254,9 +254,23 @@ open class KotlinFileExtractor(
} }
} }
fun extractClassInstance(classLabel: Label<out DbClassorinterface>, c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>?, shouldExtractOutline: Boolean, shouldExtractDetails: Boolean) {
DeclarationStackAdjuster(c).use {
if (shouldExtractOutline) {
extractClassWithoutMembers(c, argsIncludingOuterClasses)
}
if (shouldExtractDetails) {
val supertypeMode = if (argsIncludingOuterClasses == null) ExtractSupertypesMode.Raw else ExtractSupertypesMode.Specialised(argsIncludingOuterClasses)
extractClassSupertypes(c, classLabel, supertypeMode, true)
extractNonPrivateMemberPrototypes(c, argsIncludingOuterClasses, classLabel)
}
}
}
// `argsIncludingOuterClasses` can be null to describe a raw generic type. // `argsIncludingOuterClasses` can be null to describe a raw generic type.
// For non-generic types it will be zero-length list. // For non-generic types it will be zero-length list.
fun extractClassInstance(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>?): Label<out DbClassorinterface> { private fun extractClassWithoutMembers(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>?): Label<out DbClassorinterface> {
with("class instance", c) { with("class instance", c) {
if (argsIncludingOuterClasses?.isEmpty() == true) { if (argsIncludingOuterClasses?.isEmpty() == true) {
logger.error("Instance without type arguments: " + c.name.asString()) logger.error("Instance without type arguments: " + c.name.asString())
@@ -342,7 +356,7 @@ open class KotlinFileExtractor(
// `argsIncludingOuterClasses` can be null to describe a raw generic type. // `argsIncludingOuterClasses` can be null to describe a raw generic type.
// For non-generic types it will be zero-length list. // For non-generic types it will be zero-length list.
fun extractNonPrivateMemberPrototypes(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>?, id: Label<out DbClassorinterface>) { private fun extractNonPrivateMemberPrototypes(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>?, id: Label<out DbClassorinterface>) {
with("member prototypes", c) { with("member prototypes", c) {
val typeParamSubstitution = val typeParamSubstitution =
when (argsIncludingOuterClasses) { when (argsIncludingOuterClasses) {
@@ -1254,7 +1268,7 @@ open class KotlinFileExtractor(
} }
} }
private fun extractEnumEntry(ee: IrEnumEntry, parentId: Label<out DbReftype>, extractTypeAccess: Boolean) { private fun extractEnumEntry(ee: IrEnumEntry, parentId: Label<out DbReftype>, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean) {
with("enum entry", ee) { with("enum entry", ee) {
DeclarationStackAdjuster(ee).use { DeclarationStackAdjuster(ee).use {
val id = useEnumEntry(ee) val id = useEnumEntry(ee)
@@ -1265,7 +1279,7 @@ open class KotlinFileExtractor(
tw.writeHasLocation(id, locId) tw.writeHasLocation(id, locId)
tw.writeIsEnumConst(id) tw.writeIsEnumConst(id)
if (extractTypeAccess) { if (extractFunctionBodies) {
val fieldDeclarationId = tw.getFreshIdLabel<DbFielddecl>() val fieldDeclarationId = tw.getFreshIdLabel<DbFielddecl>()
tw.writeFielddecls(fieldDeclarationId, parentId) tw.writeFielddecls(fieldDeclarationId, parentId)
tw.writeFieldDeclaredIn(id, fieldDeclarationId, 0) tw.writeFieldDeclaredIn(id, fieldDeclarationId, 0)
@@ -1273,6 +1287,10 @@ open class KotlinFileExtractor(
extractTypeAccess(type, locId, fieldDeclarationId, 0) extractTypeAccess(type, locId, fieldDeclarationId, 0)
} }
ee.correspondingClass?.let {
extractDeclaration(it, extractPrivateMembers, extractFunctionBodies)
}
} }
} }
} }
@@ -1769,56 +1787,6 @@ open class KotlinFileExtractor(
extractCallValueArguments(id, valueArgsWithDummies + extraArgs, enclosingStmt, enclosingCallable, nextIdx) extractCallValueArguments(id, valueArgsWithDummies + extraArgs, enclosingStmt, enclosingCallable, nextIdx)
} }
fun extractRawMethodAccess(
syntacticCallTarget: IrFunction,
callsite: IrCall,
enclosingCallable: Label<out DbCallable>,
callsiteParent: Label<out DbExprparent>,
childIdx: Int,
enclosingStmt: Label<out DbStmt>,
valueArguments: List<IrExpression?>,
dispatchReceiver: IrExpression?,
extensionReceiver: IrExpression?,
typeArguments: List<IrType> = listOf(),
extractClassTypeArguments: Boolean = false,
superQualifierSymbol: IrClassSymbol? = null) {
val locId = tw.getLocation(callsite)
if (valueArguments.any { it == null }) {
extractsDefaultsCall(
syntacticCallTarget,
locId,
callsite,
enclosingCallable,
callsiteParent,
childIdx,
enclosingStmt,
valueArguments,
dispatchReceiver,
extensionReceiver
)
} else {
extractRawMethodAccess(
syntacticCallTarget,
locId,
callsite.type,
enclosingCallable,
callsiteParent,
childIdx,
enclosingStmt,
valueArguments.size,
{ argParent, idxOffset -> extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset) },
dispatchReceiver?.type,
dispatchReceiver?.let { { callId -> extractExpressionExpr(dispatchReceiver, enclosingCallable, callId, -1, enclosingStmt) } },
extensionReceiver?.let { { argParent -> extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt) } },
typeArguments,
extractClassTypeArguments,
superQualifierSymbol
)
}
}
private fun getFunctionInvokeMethod(typeArgs: List<IrTypeArgument>): IrFunction? { private fun getFunctionInvokeMethod(typeArgs: List<IrTypeArgument>): IrFunction? {
// For `kotlin.FunctionX` and `kotlin.reflect.KFunctionX` interfaces, we're making sure that we // For `kotlin.FunctionX` and `kotlin.reflect.KFunctionX` interfaces, we're making sure that we
// extract the call to the `invoke` method that does exist, `kotlin.jvm.functions.FunctionX::invoke`. // extract the call to the `invoke` method that does exist, `kotlin.jvm.functions.FunctionX::invoke`.
@@ -1877,6 +1845,55 @@ open class KotlinFileExtractor(
} }
} }
fun extractRawMethodAccess(
syntacticCallTarget: IrFunction,
callsite: IrCall,
enclosingCallable: Label<out DbCallable>,
callsiteParent: Label<out DbExprparent>,
childIdx: Int,
enclosingStmt: Label<out DbStmt>,
valueArguments: List<IrExpression?>,
dispatchReceiver: IrExpression?,
extensionReceiver: IrExpression?,
typeArguments: List<IrType> = listOf(),
extractClassTypeArguments: Boolean = false,
superQualifierSymbol: IrClassSymbol? = null) {
val locId = tw.getLocation(callsite)
if (valueArguments.any { it == null }) {
extractsDefaultsCall(
syntacticCallTarget,
locId,
callsite,
enclosingCallable,
callsiteParent,
childIdx,
enclosingStmt,
valueArguments,
dispatchReceiver,
extensionReceiver
)
} else {
extractRawMethodAccess(
syntacticCallTarget,
locId,
callsite.type,
enclosingCallable,
callsiteParent,
childIdx,
enclosingStmt,
valueArguments.size,
{ argParent, idxOffset -> extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset) },
dispatchReceiver?.type,
dispatchReceiver?.let { { callId -> extractExpressionExpr(dispatchReceiver, enclosingCallable, callId, -1, enclosingStmt) } },
extensionReceiver?.let { { argParent -> extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt) } },
typeArguments,
extractClassTypeArguments,
superQualifierSymbol
)
}
}
fun extractRawMethodAccess( fun extractRawMethodAccess(
syntacticCallTarget: IrFunction, syntacticCallTarget: IrFunction,
@@ -4999,7 +5016,7 @@ open class KotlinFileExtractor(
class <Anon> extends Object implements IntPredicate { class <Anon> extends Object implements IntPredicate {
Function1<Integer, Boolean> <fn>; Function1<Integer, Boolean> <fn>;
public <Anon>(Function1<Integer, Boolean> <fn>) { this.<fn> = <fn>; } public <Anon>(Function1<Integer, Boolean> <fn>) { this.<fn> = <fn>; }
public Boolean accept(Integer i) { return <fn>.invoke(i); } public override Boolean accept(Integer i) { return <fn>.invoke(i); }
} }
IntPredicate x = (IntPredicate)new <Anon>(...); IntPredicate x = (IntPredicate)new <Anon>(...);
@@ -5079,6 +5096,7 @@ open class KotlinFileExtractor(
// the real underlying R Function<T, R>.apply(T t). // the real underlying R Function<T, R>.apply(T t).
forceExtractFunction(samMember, classId, extractBody = false, extractMethodAndParameterTypeAccesses = true, typeSub, classTypeArgs, overriddenAttributes = OverriddenFunctionAttributes(id = ids.function, sourceLoc = tw.getLocation(e))) forceExtractFunction(samMember, classId, extractBody = false, extractMethodAndParameterTypeAccesses = true, typeSub, classTypeArgs, overriddenAttributes = OverriddenFunctionAttributes(id = ids.function, sourceLoc = tw.getLocation(e)))
addModifiers(ids.function, "override")
if (st.isSuspendFunctionOrKFunction()) { if (st.isSuspendFunctionOrKFunction()) {
addModifiers(ids.function, "suspend") addModifiers(ids.function, "suspend")
} }

View File

@@ -411,16 +411,9 @@ open class KotlinUsesExtractor(
if (replacedArgsIncludingOuterClasses == null || replacedArgsIncludingOuterClasses.isNotEmpty()) { if (replacedArgsIncludingOuterClasses == null || replacedArgsIncludingOuterClasses.isNotEmpty()) {
// If this is a generic type instantiation or a raw type then it has no // If this is a generic type instantiation or a raw type then it has no
// source entity, so we need to extract it here // source entity, so we need to extract it here
val extractorWithCSource by lazy { this.withFileOfClass(replacedClass) } val shouldExtractClassDetails = inReceiverContext && tw.lm.genericSpecialisationsExtracted.add(classLabelResult.classLabel)
if (!instanceSeenBefore || shouldExtractClassDetails) {
if (!instanceSeenBefore) { this.withFileOfClass(replacedClass).extractClassInstance(classLabel, replacedClass, replacedArgsIncludingOuterClasses, !instanceSeenBefore, shouldExtractClassDetails)
extractorWithCSource.extractClassInstance(replacedClass, replacedArgsIncludingOuterClasses)
}
if (inReceiverContext && tw.lm.genericSpecialisationsExtracted.add(classLabelResult.classLabel)) {
val supertypeMode = if (replacedArgsIncludingOuterClasses == null) ExtractSupertypesMode.Raw else ExtractSupertypesMode.Specialised(replacedArgsIncludingOuterClasses)
extractorWithCSource.extractClassSupertypes(replacedClass, classLabel, supertypeMode, true)
extractorWithCSource.extractNonPrivateMemberPrototypes(replacedClass, replacedArgsIncludingOuterClasses, classLabel)
} }
} }

View File

@@ -1,3 +1,9 @@
## 0.4.1
### Minor Analysis Improvements
* Added external flow sources for the intents received in exported Android services.
## 0.4.0 ## 0.4.0
### Breaking Changes ### Breaking Changes

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Added data flow steps for tainted Android intents that are sent to services and receivers.
* Improved the data flow step for tainted Android intents that are sent to activities so that more cases are covered.

View File

@@ -0,0 +1,4 @@
---
category: deprecated
---
* Deprecated `ContextStartActivityMethod`. Use `StartActivityMethod` instead.

View File

@@ -1,4 +1,5 @@
--- ## 0.4.1
category: minorAnalysis
--- ### Minor Analysis Improvements
* Added external flow sources for the intents received in exported Android services. * Added external flow sources for the intents received in exported Android services.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.4.0 lastReleaseVersion: 0.4.1

View File

@@ -1,5 +1,5 @@
name: codeql/java-all name: codeql/java-all
version: 0.4.1-dev version: 0.4.2-dev
groups: java groups: java
dbscheme: config/semmlecode.dbscheme dbscheme: config/semmlecode.dbscheme
extractor: java extractor: java

View File

@@ -51,9 +51,9 @@ library class MarkerCommentGeneratedFile extends GeneratedFile {
/** /**
* A marker comment that indicates that it is in a generated file. * A marker comment that indicates that it is in a generated file.
*/ */
private class GeneratedFileMarker extends Top instanceof JavadocElement { private class GeneratedFileMarker extends Top {
GeneratedFileMarker() { GeneratedFileMarker() {
exists(string msg | msg = this.getText() | exists(string msg | msg = this.(JavadocElement).getText() or msg = this.(KtComment).getText() |
msg.regexpMatch("(?i).*\\bGenerated By\\b.*\\bDo not edit\\b.*") or msg.regexpMatch("(?i).*\\bGenerated By\\b.*\\bDo not edit\\b.*") or
msg.regexpMatch("(?i).*\\bThis (file|class|interface|art[ei]fact) (was|is|(has been)) (?:auto[ -]?)?gener(e?)ated.*") or msg.regexpMatch("(?i).*\\bThis (file|class|interface|art[ei]fact) (was|is|(has been)) (?:auto[ -]?)?gener(e?)ated.*") or
msg.regexpMatch("(?i).*\\bAny modifications to this file will be lost\\b.*") or msg.regexpMatch("(?i).*\\bAny modifications to this file will be lost\\b.*") or

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

View File

@@ -163,7 +163,9 @@ abstract class Configuration extends string {
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.
*/ */
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } predicate hasFlowTo(Node sink) {
sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode()
}
/** /**
* Holds if data may flow from some source to `sink` for this configuration. * Holds if data may flow from some source to `sink` for this configuration.

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