From 968127eaa3bfb234c6b02595d9a0e540c435da8c Mon Sep 17 00:00:00 2001
From: Stephan Brandauer
Date: Tue, 31 Oct 2023 11:09:02 +0100
Subject: [PATCH 01/22] Java: release automodel extraction queries 0.0.7
---
java/ql/automodel/src/CHANGELOG.md | 4 ++++
java/ql/automodel/src/change-notes/released/0.0.7.md | 3 +++
java/ql/automodel/src/codeql-pack.release.yml | 2 +-
java/ql/automodel/src/qlpack.yml | 2 +-
4 files changed, 9 insertions(+), 2 deletions(-)
create mode 100644 java/ql/automodel/src/change-notes/released/0.0.7.md
diff --git a/java/ql/automodel/src/CHANGELOG.md b/java/ql/automodel/src/CHANGELOG.md
index 89d062a2a24..88b3b77ee45 100644
--- a/java/ql/automodel/src/CHANGELOG.md
+++ b/java/ql/automodel/src/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.0.7
+
+No user-facing changes.
+
## 0.0.6
No user-facing changes.
diff --git a/java/ql/automodel/src/change-notes/released/0.0.7.md b/java/ql/automodel/src/change-notes/released/0.0.7.md
new file mode 100644
index 00000000000..a4e26791ae4
--- /dev/null
+++ b/java/ql/automodel/src/change-notes/released/0.0.7.md
@@ -0,0 +1,3 @@
+## 0.0.7
+
+Support for extracting source candidates.
diff --git a/java/ql/automodel/src/codeql-pack.release.yml b/java/ql/automodel/src/codeql-pack.release.yml
index cf398ce02aa..a2a5484910b 100644
--- a/java/ql/automodel/src/codeql-pack.release.yml
+++ b/java/ql/automodel/src/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.0.6
+lastReleaseVersion: 0.0.7
diff --git a/java/ql/automodel/src/qlpack.yml b/java/ql/automodel/src/qlpack.yml
index a157feb9ebe..23b4a9e7e32 100644
--- a/java/ql/automodel/src/qlpack.yml
+++ b/java/ql/automodel/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/java-automodel-queries
-version: 0.0.7-dev
+version: 0.0.8-dev
groups:
- java
- automodel
From 9087259b1b1c4934e78498891cbd3521f26f92fc Mon Sep 17 00:00:00 2001
From: Stephan Brandauer
Date: Tue, 31 Oct 2023 11:11:22 +0100
Subject: [PATCH 02/22] Java: add instructions to automodel query publish
script
---
java/ql/automodel/publish.sh | 3 +++
1 file changed, 3 insertions(+)
diff --git a/java/ql/automodel/publish.sh b/java/ql/automodel/publish.sh
index b13570c950f..e1362d967f8 100755
--- a/java/ql/automodel/publish.sh
+++ b/java/ql/automodel/publish.sh
@@ -1,6 +1,9 @@
#!/bin/sh
set -e
+# Before running this, make sure there is an SSO-enabled token with package:write
+# permissions to codeql supplied via the GITHUB_TOKEN environment variable
+
AUTOMODEL_ROOT="$(readlink -f "$(dirname $0)")"
WORKSPACE_ROOT="$AUTOMODEL_ROOT/../../.."
GRPS="automodel,-test"
From 475d8da3426e53aad94588bc997b99c75298aec8 Mon Sep 17 00:00:00 2001
From: Tom Hvitved
Date: Tue, 14 Nov 2023 13:07:06 +0100
Subject: [PATCH 03/22] Ruby: Include more nodes in
`{Hash,Array}LiteralCfgNode`
---
.../lib/codeql/ruby/controlflow/CfgNodes.qll | 10 +++----
.../dataflow/hash-flow/hash-flow.expected | 28 +++++++++----------
2 files changed, 18 insertions(+), 20 deletions(-)
diff --git a/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll b/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll
index 92619aa6e29..01f0f1726d3 100644
--- a/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll
+++ b/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll
@@ -960,8 +960,7 @@ module ExprNodes {
exists(ConstantReadAccess array |
array = this.getReceiver().getExpr() and
e.(MethodCall).getMethodName() = "[]" and
- array.getName() = "Array" and
- array.hasGlobalScope()
+ array.getModule().getQualifiedName() = "Array"
)
}
}
@@ -975,11 +974,10 @@ module ExprNodes {
override string getAPrimaryQlClass() { result = "HashLiteralCfgNode" }
HashLiteralCfgNode() {
- exists(ConstantReadAccess array |
- array = this.getReceiver().getExpr() and
+ exists(ConstantReadAccess hash |
+ hash = this.getReceiver().getExpr() and
e.(MethodCall).getMethodName() = "[]" and
- array.getName() = "Hash" and
- array.hasGlobalScope()
+ hash.getModule().getQualifiedName() = "Hash"
)
}
diff --git a/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.expected b/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.expected
index 83b756bfccf..79f2565a590 100644
--- a/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.expected
+++ b/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.expected
@@ -42,10 +42,10 @@ edges
| hash_flow.rb:44:10:44:13 | hash [element 0] | hash_flow.rb:44:10:44:16 | ...[...] |
| hash_flow.rb:46:10:46:13 | hash [element :a] | hash_flow.rb:46:10:46:17 | ...[...] |
| hash_flow.rb:48:10:48:13 | hash [element a] | hash_flow.rb:48:10:48:18 | ...[...] |
-| hash_flow.rb:55:5:55:9 | hash1 [hash-splat position :a] | hash_flow.rb:56:10:56:14 | hash1 [hash-splat position :a] |
-| hash_flow.rb:55:13:55:37 | ...[...] [hash-splat position :a] | hash_flow.rb:55:5:55:9 | hash1 [hash-splat position :a] |
-| hash_flow.rb:55:21:55:30 | call to taint | hash_flow.rb:55:13:55:37 | ...[...] [hash-splat position :a] |
-| hash_flow.rb:56:10:56:14 | hash1 [hash-splat position :a] | hash_flow.rb:56:10:56:18 | ...[...] |
+| hash_flow.rb:55:5:55:9 | hash1 [element :a] | hash_flow.rb:56:10:56:14 | hash1 [element :a] |
+| hash_flow.rb:55:13:55:37 | ...[...] [element :a] | hash_flow.rb:55:5:55:9 | hash1 [element :a] |
+| hash_flow.rb:55:21:55:30 | call to taint | hash_flow.rb:55:13:55:37 | ...[...] [element :a] |
+| hash_flow.rb:56:10:56:14 | hash1 [element :a] | hash_flow.rb:56:10:56:18 | ...[...] |
| hash_flow.rb:59:5:59:5 | x [element :a] | hash_flow.rb:60:18:60:18 | x [element :a] |
| hash_flow.rb:59:13:59:22 | call to taint | hash_flow.rb:59:5:59:5 | x [element :a] |
| hash_flow.rb:60:5:60:9 | hash2 [element :a] | hash_flow.rb:61:10:61:14 | hash2 [element :a] |
@@ -62,10 +62,10 @@ edges
| hash_flow.rb:68:13:68:39 | ...[...] [element :a] | hash_flow.rb:68:5:68:9 | hash4 [element :a] |
| hash_flow.rb:68:22:68:31 | call to taint | hash_flow.rb:68:13:68:39 | ...[...] [element :a] |
| hash_flow.rb:69:10:69:14 | hash4 [element :a] | hash_flow.rb:69:10:69:18 | ...[...] |
-| hash_flow.rb:72:5:72:9 | hash5 [hash-splat position a] | hash_flow.rb:73:10:73:14 | hash5 [hash-splat position a] |
-| hash_flow.rb:72:13:72:45 | ...[...] [hash-splat position a] | hash_flow.rb:72:5:72:9 | hash5 [hash-splat position a] |
-| hash_flow.rb:72:25:72:34 | call to taint | hash_flow.rb:72:13:72:45 | ...[...] [hash-splat position a] |
-| hash_flow.rb:73:10:73:14 | hash5 [hash-splat position a] | hash_flow.rb:73:10:73:19 | ...[...] |
+| hash_flow.rb:72:5:72:9 | hash5 [element a] | hash_flow.rb:73:10:73:14 | hash5 [element a] |
+| hash_flow.rb:72:13:72:45 | ...[...] [element a] | hash_flow.rb:72:5:72:9 | hash5 [element a] |
+| hash_flow.rb:72:25:72:34 | call to taint | hash_flow.rb:72:13:72:45 | ...[...] [element a] |
+| hash_flow.rb:73:10:73:14 | hash5 [element a] | hash_flow.rb:73:10:73:19 | ...[...] |
| hash_flow.rb:76:5:76:9 | hash6 [element a] | hash_flow.rb:77:10:77:14 | hash6 [element a] |
| hash_flow.rb:76:13:76:47 | ...[...] [element a] | hash_flow.rb:76:5:76:9 | hash6 [element a] |
| hash_flow.rb:76:26:76:35 | call to taint | hash_flow.rb:76:13:76:47 | ...[...] [element a] |
@@ -1015,10 +1015,10 @@ nodes
| hash_flow.rb:46:10:46:17 | ...[...] | semmle.label | ...[...] |
| hash_flow.rb:48:10:48:13 | hash [element a] | semmle.label | hash [element a] |
| hash_flow.rb:48:10:48:18 | ...[...] | semmle.label | ...[...] |
-| hash_flow.rb:55:5:55:9 | hash1 [hash-splat position :a] | semmle.label | hash1 [hash-splat position :a] |
-| hash_flow.rb:55:13:55:37 | ...[...] [hash-splat position :a] | semmle.label | ...[...] [hash-splat position :a] |
+| hash_flow.rb:55:5:55:9 | hash1 [element :a] | semmle.label | hash1 [element :a] |
+| hash_flow.rb:55:13:55:37 | ...[...] [element :a] | semmle.label | ...[...] [element :a] |
| hash_flow.rb:55:21:55:30 | call to taint | semmle.label | call to taint |
-| hash_flow.rb:56:10:56:14 | hash1 [hash-splat position :a] | semmle.label | hash1 [hash-splat position :a] |
+| hash_flow.rb:56:10:56:14 | hash1 [element :a] | semmle.label | hash1 [element :a] |
| hash_flow.rb:56:10:56:18 | ...[...] | semmle.label | ...[...] |
| hash_flow.rb:59:5:59:5 | x [element :a] | semmle.label | x [element :a] |
| hash_flow.rb:59:13:59:22 | call to taint | semmle.label | call to taint |
@@ -1039,10 +1039,10 @@ nodes
| hash_flow.rb:68:22:68:31 | call to taint | semmle.label | call to taint |
| hash_flow.rb:69:10:69:14 | hash4 [element :a] | semmle.label | hash4 [element :a] |
| hash_flow.rb:69:10:69:18 | ...[...] | semmle.label | ...[...] |
-| hash_flow.rb:72:5:72:9 | hash5 [hash-splat position a] | semmle.label | hash5 [hash-splat position a] |
-| hash_flow.rb:72:13:72:45 | ...[...] [hash-splat position a] | semmle.label | ...[...] [hash-splat position a] |
+| hash_flow.rb:72:5:72:9 | hash5 [element a] | semmle.label | hash5 [element a] |
+| hash_flow.rb:72:13:72:45 | ...[...] [element a] | semmle.label | ...[...] [element a] |
| hash_flow.rb:72:25:72:34 | call to taint | semmle.label | call to taint |
-| hash_flow.rb:73:10:73:14 | hash5 [hash-splat position a] | semmle.label | hash5 [hash-splat position a] |
+| hash_flow.rb:73:10:73:14 | hash5 [element a] | semmle.label | hash5 [element a] |
| hash_flow.rb:73:10:73:19 | ...[...] | semmle.label | ...[...] |
| hash_flow.rb:76:5:76:9 | hash6 [element a] | semmle.label | hash6 [element a] |
| hash_flow.rb:76:13:76:47 | ...[...] [element a] | semmle.label | ...[...] [element a] |
From 721bde1ce8d5ebb29fe8bbeb513376886c8179ba Mon Sep 17 00:00:00 2001
From: Rasmus Wriedt Larsen
Date: Wed, 15 Nov 2023 09:59:26 +0100
Subject: [PATCH 04/22] Python: Delete orphaned `.expected` files
---
.../experimental/dataflow/regression/pointsto.expected | 1 -
.../Expressions/general/ExplcitCallToDel.expected | 1 -
.../ReturnOrYieldOutsideOfFunction.expected | 9 ---------
3 files changed, 11 deletions(-)
delete mode 100644 python/ql/test/experimental/dataflow/regression/pointsto.expected
delete mode 100644 python/ql/test/query-tests/Expressions/general/ExplcitCallToDel.expected
delete mode 100644 python/ql/test/query-tests/Statements/ReturnOrYieldOutsideOfFunction/ReturnOrYieldOutsideOfFunction.expected
diff --git a/python/ql/test/experimental/dataflow/regression/pointsto.expected b/python/ql/test/experimental/dataflow/regression/pointsto.expected
deleted file mode 100644
index 234bdda3f7f..00000000000
--- a/python/ql/test/experimental/dataflow/regression/pointsto.expected
+++ /dev/null
@@ -1 +0,0 @@
-| pointsto_regressions.py:15:18:15:21 | ControlFlowNode for self | pointsto_regressions.py:19:9:19:12 | ControlFlowNode for self |
diff --git a/python/ql/test/query-tests/Expressions/general/ExplcitCallToDel.expected b/python/ql/test/query-tests/Expressions/general/ExplcitCallToDel.expected
deleted file mode 100644
index 909c9d8ccc8..00000000000
--- a/python/ql/test/query-tests/Expressions/general/ExplcitCallToDel.expected
+++ /dev/null
@@ -1 +0,0 @@
-Failure
\ No newline at end of file
diff --git a/python/ql/test/query-tests/Statements/ReturnOrYieldOutsideOfFunction/ReturnOrYieldOutsideOfFunction.expected b/python/ql/test/query-tests/Statements/ReturnOrYieldOutsideOfFunction/ReturnOrYieldOutsideOfFunction.expected
deleted file mode 100644
index 340312c832f..00000000000
--- a/python/ql/test/query-tests/Statements/ReturnOrYieldOutsideOfFunction/ReturnOrYieldOutsideOfFunction.expected
+++ /dev/null
@@ -1,9 +0,0 @@
-| ReturnOrYieldOutsideOfFunction_test.py:31:9:31:23 | Return | 'return' is used outside of a function. |
-| ReturnOrYieldOutsideOfFunction_test.py:36:9:36:15 | Yield | 'yield' is used outside of a function. |
-| ReturnOrYieldOutsideOfFunction_test.py:41:9:41:25 | YieldFrom | 'yield from' is used outside of a function. |
-| ReturnOrYieldOutsideOfFunction_test.py:45:5:45:12 | Return | 'return' is used outside of a function. |
-| ReturnOrYieldOutsideOfFunction_test.py:49:5:49:11 | Yield | 'yield' is used outside of a function. |
-| ReturnOrYieldOutsideOfFunction_test.py:53:5:53:16 | YieldFrom | 'yield from' is used outside of a function. |
-| ReturnOrYieldOutsideOfFunction_test.py:57:1:57:14 | YieldFrom | 'yield from' is used outside of a function. |
-| ReturnOrYieldOutsideOfFunction_test.py:60:1:60:12 | Return | 'return' is used outside of a function. |
-| ReturnOrYieldOutsideOfFunction_test.py:63:1:63:11 | Yield | 'yield' is used outside of a function. |
From 55f5b26ba6734b0010ba89fb7f88214e4c03a791 Mon Sep 17 00:00:00 2001
From: Rasmus Wriedt Larsen
Date: Wed, 15 Nov 2023 10:09:54 +0100
Subject: [PATCH 05/22] Python: Accept new ordering of query predicates in
`.expected`
---
.../test/experimental/dataflow/basic/localFlowStepTest.expected | 2 +-
.../test/experimental/dataflow/basic/maximalFlowTest.expected | 2 +-
.../test/experimental/dataflow/calls/DataFlowCallTest.expected | 2 +-
.../dataflow/coverage-py2/argumentRoutingTest.expected | 2 +-
.../dataflow/coverage-py3/argumentRoutingTest.expected | 2 +-
.../experimental/dataflow/coverage/NormalDataflowTest.expected | 2 +-
.../experimental/dataflow/coverage/argumentRoutingTest.expected | 2 +-
.../dataflow/exceptions/NormalDataflowTest.expected | 2 +-
.../experimental/dataflow/fieldflow/NormalDataflowTest.expected | 2 +-
.../experimental/dataflow/fieldflow/UnresolvedCalls.expected | 2 +-
.../ql/test/experimental/dataflow/global-flow/accesses.expected | 2 +-
.../experimental/dataflow/match/NormalDataflowTest.expected | 2 +-
.../dataflow/model-summaries/InlineTaintTest.expected | 2 +-
.../dataflow/model-summaries/NormalDataflowTest.expected | 2 +-
.../dataflow/module-initialization/localFlow.expected | 2 +-
.../ql/test/experimental/dataflow/path-graph/PathNodes.expected | 2 +-
.../dataflow/sensitive-data/TestSensitiveDataSources.expected | 2 +-
.../dataflow/summaries/NormalTaintTrackingTest.expected | 2 +-
.../tainttracking/commonSanitizer/InlineTaintTest.expected | 2 +-
.../tainttracking/customSanitizer/InlineTaintTest.expected | 2 +-
.../defaultAdditionalTaintStep-py3/InlineTaintTest.expected | 2 +-
.../defaultAdditionalTaintStep/InlineTaintTest.expected | 2 +-
.../tainttracking/generator-flow/InlineTaintTest.expected | 2 +-
.../tainttracking/generator-flow/NormalDataflowTest.expected | 2 +-
.../tainttracking/unwanted-global-flow/InlineTaintTest.expected | 2 +-
.../dataflow/typetracking-summaries/tracked.expected | 2 +-
.../ql/test/experimental/dataflow/typetracking/tracked.expected | 2 +-
.../experimental/dataflow/typetracking_imports/tracked.expected | 2 +-
.../experimental/dataflow/variable-capture/CaptureTest.expected | 2 +-
.../ql/test/experimental/import-resolution/importflow.expected | 2 +-
python/ql/test/experimental/import-resolution/imports.expected | 2 +-
.../CallGraph-implicit-init/InlineCallGraphTest.expected | 2 +-
.../CallGraph-imports/InlineCallGraphTest.expected | 2 +-
.../library-tests/CallGraph/InlineCallGraphTest.expected | 2 +-
.../meta/inline-taint-test-demo/InlineTaintTest.expected | 2 +-
python/ql/test/library-tests/ApiGraphs/py2/use.expected | 2 +-
.../InlineExpectationsTest/missing-relevant-tag/Test.expected | 2 +-
python/ql/test/library-tests/essa/ssa-compute/UseUse.expected | 2 +-
.../test/library-tests/frameworks/aioch/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/aiohttp/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/aiohttp/InlineTaintTest.expected | 2 +-
.../library-tests/frameworks/aiomysql/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/aiopg/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/aiosqlite/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/asyncpg/ConceptsTest.expected | 2 +-
.../ql/test/library-tests/frameworks/asyncpg/MaDTest.expected | 2 +-
.../frameworks/cassandra-driver/ConceptsTest.expected | 2 +-
.../frameworks/clickhouse_driver/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/crypto/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/cryptodome/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/cryptography/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/cx_Oracle/ConceptsTest.expected | 2 +-
.../ql/test/library-tests/frameworks/dill/ConceptsTest.expected | 2 +-
.../frameworks/django-orm/NormalDataflowTest.expected | 2 +-
.../library-tests/frameworks/django-v1/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/django-v2-v3/ConceptsTest.expected | 2 +-
.../frameworks/django-v2-v3/InlineTaintTest.expected | 2 +-
.../test/library-tests/frameworks/django/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/fabric/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/fabric/InlineTaintTest.expected | 2 +-
.../test/library-tests/frameworks/fastapi/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/fastapi/InlineTaintTest.expected | 2 +-
.../test/library-tests/frameworks/flask/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/flask/InlineTaintTest.expected | 2 +-
.../library-tests/frameworks/flask_admin/ConceptsTest.expected | 2 +-
.../frameworks/flask_admin/InlineTaintTest.expected | 2 +-
.../frameworks/flask_sqlalchemy/ConceptsTest.expected | 2 +-
.../frameworks/flask_sqlalchemy/InlineTaintTest.expected | 2 +-
.../test/library-tests/frameworks/httpx/ConceptsTest.expected | 2 +-
.../ql/test/library-tests/frameworks/idna/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/idna/InlineTaintTest.expected | 2 +-
.../internal-ql-helpers/PoorMansFunctionResolutionTest.expected | 2 +-
.../test/library-tests/frameworks/invoke/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/jmespath/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/jmespath/InlineTaintTest.expected | 2 +-
.../test/library-tests/frameworks/joblib/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/libtaxii/ConceptsTest.expected | 2 +-
.../ql/test/library-tests/frameworks/lxml/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/markupsafe/ConceptsTest.expected | 2 +-
.../frameworks/markupsafe/InlineTaintTest.expected | 2 +-
.../library-tests/frameworks/multidict/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/multidict/InlineTaintTest.expected | 2 +-
.../frameworks/mysql-connector-python/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/mysqldb/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/numpy/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/oracledb/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/pandas/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/peewee/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/peewee/InlineTaintTest.expected | 2 +-
.../library-tests/frameworks/phoenixdb/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/pycurl/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/pymssql/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/pymysql/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/pyodbc/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/requests/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/requests/InlineTaintTest.expected | 2 +-
.../frameworks/rest_framework/InlineTaintTest.expected | 2 +-
.../ql/test/library-tests/frameworks/rsa/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/rsa/InlineTaintTest.expected | 2 +-
.../library-tests/frameworks/ruamel.yaml/ConceptsTest.expected | 2 +-
.../frameworks/serverless/InlineTaintTest.expected | 2 +-
.../library-tests/frameworks/simplejson/ConceptsTest.expected | 2 +-
.../frameworks/simplejson/InlineTaintTest.expected | 2 +-
.../library-tests/frameworks/sqlalchemy/ConceptsTest.expected | 2 +-
.../frameworks/sqlalchemy/InlineTaintTest.expected | 2 +-
.../library-tests/frameworks/stdlib-py2/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/stdlib-py3/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/stdlib/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/stdlib/InlineTaintTest.expected | 2 +-
.../ql/test/library-tests/frameworks/toml/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/tornado/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/tornado/InlineTaintTest.expected | 2 +-
.../test/library-tests/frameworks/twisted/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/twisted/InlineTaintTest.expected | 2 +-
.../test/library-tests/frameworks/ujson/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/ujson/InlineTaintTest.expected | 2 +-
.../test/library-tests/frameworks/urllib3/ConceptsTest.expected | 2 +-
.../library-tests/frameworks/xmltodict/ConceptsTest.expected | 2 +-
.../ql/test/library-tests/frameworks/yaml/ConceptsTest.expected | 2 +-
.../ql/test/library-tests/frameworks/yarl/ConceptsTest.expected | 2 +-
.../test/library-tests/frameworks/yarl/InlineTaintTest.expected | 2 +-
python/ql/test/library-tests/regex/SubstructureTests.expected | 2 +-
.../Functions/ModificationOfParameterWithDefault/test.expected | 2 +-
.../Security/CWE-022-PathInjection/DataflowQueryTest.expected | 2 +-
.../CWE-078-CommandInjection/DataflowQueryTest.expected | 2 +-
.../DataflowQueryTest.expected | 2 +-
.../Security/CWE-209-StackTraceExposure/ExceptionInfo.expected | 2 +-
.../Security/CWE-943-NoSqlInjection/DataflowQueryTest.expected | 2 +-
128 files changed, 128 insertions(+), 128 deletions(-)
diff --git a/python/ql/test/experimental/dataflow/basic/localFlowStepTest.expected b/python/ql/test/experimental/dataflow/basic/localFlowStepTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/experimental/dataflow/basic/localFlowStepTest.expected
+++ b/python/ql/test/experimental/dataflow/basic/localFlowStepTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/basic/maximalFlowTest.expected b/python/ql/test/experimental/dataflow/basic/maximalFlowTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/experimental/dataflow/basic/maximalFlowTest.expected
+++ b/python/ql/test/experimental/dataflow/basic/maximalFlowTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/calls/DataFlowCallTest.expected b/python/ql/test/experimental/dataflow/calls/DataFlowCallTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/experimental/dataflow/calls/DataFlowCallTest.expected
+++ b/python/ql/test/experimental/dataflow/calls/DataFlowCallTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.expected b/python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.expected
+++ b/python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.expected b/python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.expected
+++ b/python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/coverage/NormalDataflowTest.expected b/python/ql/test/experimental/dataflow/coverage/NormalDataflowTest.expected
index 04431311999..9ce23b4c553 100644
--- a/python/ql/test/experimental/dataflow/coverage/NormalDataflowTest.expected
+++ b/python/ql/test/experimental/dataflow/coverage/NormalDataflowTest.expected
@@ -1,3 +1,3 @@
missingAnnotationOnSink
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.expected b/python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.expected
+++ b/python/ql/test/experimental/dataflow/coverage/argumentRoutingTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/exceptions/NormalDataflowTest.expected b/python/ql/test/experimental/dataflow/exceptions/NormalDataflowTest.expected
index 04431311999..9ce23b4c553 100644
--- a/python/ql/test/experimental/dataflow/exceptions/NormalDataflowTest.expected
+++ b/python/ql/test/experimental/dataflow/exceptions/NormalDataflowTest.expected
@@ -1,3 +1,3 @@
missingAnnotationOnSink
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/fieldflow/NormalDataflowTest.expected b/python/ql/test/experimental/dataflow/fieldflow/NormalDataflowTest.expected
index 04431311999..9ce23b4c553 100644
--- a/python/ql/test/experimental/dataflow/fieldflow/NormalDataflowTest.expected
+++ b/python/ql/test/experimental/dataflow/fieldflow/NormalDataflowTest.expected
@@ -1,3 +1,3 @@
missingAnnotationOnSink
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.expected b/python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.expected
+++ b/python/ql/test/experimental/dataflow/fieldflow/UnresolvedCalls.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/global-flow/accesses.expected b/python/ql/test/experimental/dataflow/global-flow/accesses.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/experimental/dataflow/global-flow/accesses.expected
+++ b/python/ql/test/experimental/dataflow/global-flow/accesses.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/match/NormalDataflowTest.expected b/python/ql/test/experimental/dataflow/match/NormalDataflowTest.expected
index 04431311999..9ce23b4c553 100644
--- a/python/ql/test/experimental/dataflow/match/NormalDataflowTest.expected
+++ b/python/ql/test/experimental/dataflow/match/NormalDataflowTest.expected
@@ -1,3 +1,3 @@
missingAnnotationOnSink
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.expected
+++ b/python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.expected b/python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.expected
index 04431311999..9ce23b4c553 100644
--- a/python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.expected
+++ b/python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.expected
@@ -1,3 +1,3 @@
missingAnnotationOnSink
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/module-initialization/localFlow.expected b/python/ql/test/experimental/dataflow/module-initialization/localFlow.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/experimental/dataflow/module-initialization/localFlow.expected
+++ b/python/ql/test/experimental/dataflow/module-initialization/localFlow.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/path-graph/PathNodes.expected b/python/ql/test/experimental/dataflow/path-graph/PathNodes.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/experimental/dataflow/path-graph/PathNodes.expected
+++ b/python/ql/test/experimental/dataflow/path-graph/PathNodes.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.expected b/python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.expected
+++ b/python/ql/test/experimental/dataflow/sensitive-data/TestSensitiveDataSources.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/summaries/NormalTaintTrackingTest.expected b/python/ql/test/experimental/dataflow/summaries/NormalTaintTrackingTest.expected
index 04431311999..9ce23b4c553 100644
--- a/python/ql/test/experimental/dataflow/summaries/NormalTaintTrackingTest.expected
+++ b/python/ql/test/experimental/dataflow/summaries/NormalTaintTrackingTest.expected
@@ -1,3 +1,3 @@
missingAnnotationOnSink
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected
+++ b/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected
index 6e4a1c072bc..5a7d215048d 100644
--- a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected
+++ b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected
@@ -1,7 +1,7 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
isSanitizer
| test.py:21:39:21:39 | ControlFlowNode for s |
| test.py:34:39:34:39 | ControlFlowNode for s |
diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected
+++ b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected
+++ b/python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.expected
+++ b/python/ql/test/experimental/dataflow/tainttracking/generator-flow/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected b/python/ql/test/experimental/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected
index 04431311999..9ce23b4c553 100644
--- a/python/ql/test/experimental/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected
+++ b/python/ql/test/experimental/dataflow/tainttracking/generator-flow/NormalDataflowTest.expected
@@ -1,3 +1,3 @@
missingAnnotationOnSink
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected
+++ b/python/ql/test/experimental/dataflow/tainttracking/unwanted-global-flow/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/typetracking-summaries/tracked.expected b/python/ql/test/experimental/dataflow/typetracking-summaries/tracked.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/experimental/dataflow/typetracking-summaries/tracked.expected
+++ b/python/ql/test/experimental/dataflow/typetracking-summaries/tracked.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/typetracking/tracked.expected b/python/ql/test/experimental/dataflow/typetracking/tracked.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/experimental/dataflow/typetracking/tracked.expected
+++ b/python/ql/test/experimental/dataflow/typetracking/tracked.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected b/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected
+++ b/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.expected b/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.expected
+++ b/python/ql/test/experimental/dataflow/variable-capture/CaptureTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/import-resolution/importflow.expected b/python/ql/test/experimental/import-resolution/importflow.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/experimental/import-resolution/importflow.expected
+++ b/python/ql/test/experimental/import-resolution/importflow.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/import-resolution/imports.expected b/python/ql/test/experimental/import-resolution/imports.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/experimental/import-resolution/imports.expected
+++ b/python/ql/test/experimental/import-resolution/imports.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.expected b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.expected
index de783b3bdcb..802b8ff5d13 100644
--- a/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.expected
+++ b/python/ql/test/experimental/library-tests/CallGraph-implicit-init/InlineCallGraphTest.expected
@@ -1,5 +1,5 @@
-failures
testFailures
+failures
debug_callableNotUnique
pointsTo_found_typeTracker_notFound
typeTracker_found_pointsTo_notFound
diff --git a/python/ql/test/experimental/library-tests/CallGraph-imports/InlineCallGraphTest.expected b/python/ql/test/experimental/library-tests/CallGraph-imports/InlineCallGraphTest.expected
index de783b3bdcb..802b8ff5d13 100644
--- a/python/ql/test/experimental/library-tests/CallGraph-imports/InlineCallGraphTest.expected
+++ b/python/ql/test/experimental/library-tests/CallGraph-imports/InlineCallGraphTest.expected
@@ -1,5 +1,5 @@
-failures
testFailures
+failures
debug_callableNotUnique
pointsTo_found_typeTracker_notFound
typeTracker_found_pointsTo_notFound
diff --git a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected
index 31987baf6d7..55774486be0 100644
--- a/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected
+++ b/python/ql/test/experimental/library-tests/CallGraph/InlineCallGraphTest.expected
@@ -1,5 +1,5 @@
-failures
testFailures
+failures
debug_callableNotUnique
pointsTo_found_typeTracker_notFound
| code/class_attr_assign.py:10:9:10:27 | ControlFlowNode for Attribute() | my_func |
diff --git a/python/ql/test/experimental/meta/inline-taint-test-demo/InlineTaintTest.expected b/python/ql/test/experimental/meta/inline-taint-test-demo/InlineTaintTest.expected
index 511dc50d5ca..b4d2d9c606e 100644
--- a/python/ql/test/experimental/meta/inline-taint-test-demo/InlineTaintTest.expected
+++ b/python/ql/test/experimental/meta/inline-taint-test-demo/InlineTaintTest.expected
@@ -1,4 +1,3 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
| taint_test.py:48:9:48:29 | taint_test.py:48 | ERROR, you should add `SPURIOUS:` to this annotation | should_not_be_tainted |
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
@@ -6,3 +5,4 @@ untaintedArgumentToEnsureTaintedNotMarkedAsMissing
| taint_test.py:37:24:37:40 | taint_test.py:37 | ERROR, you should add `# $ MISSING: tainted` annotation | should_be_tainted |
testFailures
| taint_test.py:41:20:41:21 | ts | Fixed missing result:tainted= |
+failures
diff --git a/python/ql/test/library-tests/ApiGraphs/py2/use.expected b/python/ql/test/library-tests/ApiGraphs/py2/use.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/ApiGraphs/py2/use.expected
+++ b/python/ql/test/library-tests/ApiGraphs/py2/use.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/InlineExpectationsTest/missing-relevant-tag/Test.expected b/python/ql/test/library-tests/InlineExpectationsTest/missing-relevant-tag/Test.expected
index 2cd3654766b..8dd0c425627 100644
--- a/python/ql/test/library-tests/InlineExpectationsTest/missing-relevant-tag/Test.expected
+++ b/python/ql/test/library-tests/InlineExpectationsTest/missing-relevant-tag/Test.expected
@@ -1,4 +1,4 @@
-failures
testFailures
| test.py:1:1:1:3 | foo | Tag mismatch: Actual result with tag 'foo' that is not part of getARelevantTag() |
| test.py:4:1:4:3 | foo | Tag mismatch: Actual result with tag 'foo' that is not part of getARelevantTag() |
+failures
diff --git a/python/ql/test/library-tests/essa/ssa-compute/UseUse.expected b/python/ql/test/library-tests/essa/ssa-compute/UseUse.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/essa/ssa-compute/UseUse.expected
+++ b/python/ql/test/library-tests/essa/ssa-compute/UseUse.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/aioch/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aioch/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/aioch/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/aioch/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/aiohttp/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/aiohttp/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/aiomysql/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aiomysql/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/aiomysql/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/aiomysql/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/aiopg/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aiopg/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/aiopg/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/aiopg/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/asyncpg/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/asyncpg/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/asyncpg/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/asyncpg/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/asyncpg/MaDTest.expected b/python/ql/test/library-tests/frameworks/asyncpg/MaDTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/asyncpg/MaDTest.expected
+++ b/python/ql/test/library-tests/frameworks/asyncpg/MaDTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/clickhouse_driver/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/crypto/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/crypto/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/crypto/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/crypto/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/cryptodome/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/cryptodome/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/cryptodome/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/cryptodome/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/cryptography/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/cryptography/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/cryptography/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/cryptography/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/cx_Oracle/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/cx_Oracle/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/cx_Oracle/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/cx_Oracle/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/dill/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/dill/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/dill/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/dill/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.expected b/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.expected
index 04431311999..9ce23b4c553 100644
--- a/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.expected
+++ b/python/ql/test/library-tests/frameworks/django-orm/NormalDataflowTest.expected
@@ -1,3 +1,3 @@
missingAnnotationOnSink
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/django-v1/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/django-v1/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/django-v1/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/django-v1/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/django-v2-v3/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/django-v2-v3/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/django-v2-v3/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/django-v2-v3/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/django-v2-v3/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/django-v2-v3/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/django-v2-v3/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/django-v2-v3/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/django/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/django/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/django/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/django/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/fabric/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/fabric/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/fabric/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/fabric/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/fabric/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/fabric/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/fabric/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/fabric/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/fastapi/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/fastapi/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/fastapi/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/fastapi/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/fastapi/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/fastapi/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/fastapi/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/fastapi/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/flask/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/flask/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/flask/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/flask/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/flask/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/flask/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/flask/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/flask/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/flask_admin/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/flask_admin/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/flask_admin/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/flask_admin/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/flask_admin/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/flask_admin/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/flask_admin/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/flask_admin/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/flask_sqlalchemy/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/flask_sqlalchemy/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/flask_sqlalchemy/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/flask_sqlalchemy/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/flask_sqlalchemy/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/flask_sqlalchemy/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/flask_sqlalchemy/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/flask_sqlalchemy/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/httpx/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/httpx/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/httpx/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/httpx/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/idna/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/idna/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/idna/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/idna/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/idna/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/idna/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/idna/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/idna/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/internal-ql-helpers/PoorMansFunctionResolutionTest.expected b/python/ql/test/library-tests/frameworks/internal-ql-helpers/PoorMansFunctionResolutionTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/internal-ql-helpers/PoorMansFunctionResolutionTest.expected
+++ b/python/ql/test/library-tests/frameworks/internal-ql-helpers/PoorMansFunctionResolutionTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/invoke/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/invoke/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/invoke/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/invoke/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/jmespath/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/jmespath/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/jmespath/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/jmespath/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/jmespath/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/jmespath/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/jmespath/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/jmespath/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/joblib/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/joblib/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/joblib/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/joblib/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/libtaxii/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/libtaxii/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/libtaxii/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/libtaxii/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/lxml/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/lxml/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/lxml/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/lxml/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/markupsafe/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/markupsafe/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/markupsafe/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/markupsafe/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/markupsafe/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/markupsafe/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/markupsafe/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/markupsafe/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/multidict/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/multidict/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/multidict/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/multidict/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/multidict/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/mysql-connector-python/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/mysql-connector-python/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/mysql-connector-python/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/mysql-connector-python/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/mysqldb/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/mysqldb/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/mysqldb/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/mysqldb/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/numpy/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/numpy/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/numpy/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/numpy/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/oracledb/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/oracledb/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/oracledb/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/oracledb/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/pandas/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/pandas/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/pandas/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/pandas/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/peewee/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/peewee/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/peewee/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/peewee/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/peewee/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/peewee/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/peewee/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/peewee/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/phoenixdb/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/phoenixdb/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/phoenixdb/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/phoenixdb/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/pycurl/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/pycurl/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/pycurl/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/pycurl/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/pymssql/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/pymssql/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/pymssql/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/pymssql/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/pymysql/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/pymysql/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/pymysql/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/pymysql/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/pyodbc/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/pyodbc/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/pyodbc/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/pyodbc/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/requests/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/requests/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/requests/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/requests/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/requests/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/requests/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/requests/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/requests/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/rest_framework/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/rest_framework/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/rest_framework/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/rest_framework/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/rsa/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/rsa/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/rsa/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/rsa/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/rsa/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/rsa/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/rsa/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/rsa/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/ruamel.yaml/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/ruamel.yaml/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/ruamel.yaml/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/ruamel.yaml/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/serverless/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/serverless/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/serverless/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/serverless/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/simplejson/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/simplejson/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/simplejson/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/simplejson/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/simplejson/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/simplejson/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/simplejson/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/simplejson/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/sqlalchemy/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/sqlalchemy/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/sqlalchemy/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/sqlalchemy/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/sqlalchemy/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/stdlib-py2/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/stdlib-py2/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/stdlib-py2/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/stdlib-py2/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/stdlib-py3/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/stdlib-py3/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/stdlib-py3/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/stdlib-py3/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/stdlib/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/stdlib/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/stdlib/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/stdlib/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/stdlib/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/stdlib/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/stdlib/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/stdlib/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/toml/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/toml/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/toml/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/toml/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/tornado/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/tornado/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/tornado/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/tornado/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/tornado/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/tornado/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/tornado/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/tornado/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/twisted/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/twisted/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/twisted/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/twisted/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/twisted/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/twisted/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/twisted/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/twisted/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/ujson/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/ujson/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/ujson/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/ujson/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/ujson/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/ujson/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/ujson/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/ujson/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/urllib3/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/urllib3/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/urllib3/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/urllib3/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/xmltodict/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/xmltodict/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/xmltodict/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/xmltodict/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/yaml/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/yaml/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/yaml/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/yaml/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/yarl/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/yarl/ConceptsTest.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/frameworks/yarl/ConceptsTest.expected
+++ b/python/ql/test/library-tests/frameworks/yarl/ConceptsTest.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.expected b/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.expected
index 4a72c551661..366de37b867 100644
--- a/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.expected
+++ b/python/ql/test/library-tests/frameworks/yarl/InlineTaintTest.expected
@@ -1,4 +1,4 @@
-failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
testFailures
+failures
diff --git a/python/ql/test/library-tests/regex/SubstructureTests.expected b/python/ql/test/library-tests/regex/SubstructureTests.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/library-tests/regex/SubstructureTests.expected
+++ b/python/ql/test/library-tests/regex/SubstructureTests.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.expected b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.expected
+++ b/python/ql/test/query-tests/Functions/ModificationOfParameterWithDefault/test.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.expected b/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.expected
index 04431311999..9ce23b4c553 100644
--- a/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.expected
+++ b/python/ql/test/query-tests/Security/CWE-022-PathInjection/DataflowQueryTest.expected
@@ -1,3 +1,3 @@
missingAnnotationOnSink
-failures
testFailures
+failures
diff --git a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.expected b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.expected
index 04431311999..9ce23b4c553 100644
--- a/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.expected
+++ b/python/ql/test/query-tests/Security/CWE-078-CommandInjection/DataflowQueryTest.expected
@@ -1,3 +1,3 @@
missingAnnotationOnSink
-failures
testFailures
+failures
diff --git a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.expected b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.expected
index 04431311999..9ce23b4c553 100644
--- a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.expected
+++ b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/DataflowQueryTest.expected
@@ -1,3 +1,3 @@
missingAnnotationOnSink
-failures
testFailures
+failures
diff --git a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/ExceptionInfo.expected b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/ExceptionInfo.expected
index 48de9172b36..8ec8033d086 100644
--- a/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/ExceptionInfo.expected
+++ b/python/ql/test/query-tests/Security/CWE-209-StackTraceExposure/ExceptionInfo.expected
@@ -1,2 +1,2 @@
-failures
testFailures
+failures
diff --git a/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/DataflowQueryTest.expected b/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/DataflowQueryTest.expected
index 303d04688ff..9ce23b4c553 100644
--- a/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/DataflowQueryTest.expected
+++ b/python/ql/test/query-tests/Security/CWE-943-NoSqlInjection/DataflowQueryTest.expected
@@ -1,3 +1,3 @@
-failures
missingAnnotationOnSink
testFailures
+failures
From 69453aa144f816eefbf4e0ebd67f1c126538ede3 Mon Sep 17 00:00:00 2001
From: Rasmus Wriedt Larsen
Date: Wed, 15 Nov 2023 10:10:23 +0100
Subject: [PATCH 06/22] Python: Fix missing newline in `.expected`
---
.../2/library-tests/ControlFlow/Exceptions/Handles.expected | 2 +-
.../test/2/library-tests/ControlFlow/Exceptions/Known.expected | 2 +-
.../2/library-tests/ControlFlow/Exceptions/Unknown.expected | 2 +-
.../test/2/library-tests/classes/attr/class_has_attr.expected | 2 +-
.../2/library-tests/comprehensions/ConsistencyCheck.expected | 2 +-
.../test/2/library-tests/modules/general/import_test.expected | 2 +-
.../modules/package_members/module_attributes.expected | 2 +-
.../modules/package_members/module_exports.expected | 2 +-
.../modules/package_members/module_import_as.expected | 2 +-
.../2/library-tests/types/properties/BuiltinProperties.expected | 2 +-
.../3/library-tests/ControlFlow/Exceptions/Handles.expected | 2 +-
.../test/3/library-tests/ControlFlow/Exceptions/Known.expected | 2 +-
.../3/library-tests/ControlFlow/Exceptions/Unknown.expected | 2 +-
.../test/3/library-tests/PointsTo/import_time/Pruned.expected | 2 +-
python/ql/test/3/library-tests/classes/attr/class_attr.expected | 2 +-
.../test/3/library-tests/classes/attr/class_has_attr.expected | 2 +-
python/ql/test/3/library-tests/classes/meta/meta.expected | 2 +-
python/ql/test/3/library-tests/classes/meta/meta_obj.expected | 2 +-
.../modules/package_members/module_attributes.expected | 2 +-
.../modules/package_members/module_exports.expected | 2 +-
.../modules/package_members/module_import_as.expected | 2 +-
.../test/3/library-tests/types/functions/ReturnTypes.expected | 2 +-
.../3/library-tests/types/properties/BuiltinProperties.expected | 2 +-
.../library-tests/ControlFlow/augassign/AugAssignFlow.expected | 2 +-
python/ql/test/library-tests/ControlFlow/augassign/SSA.expected | 2 +-
.../test/library-tests/ControlFlow/comparison/Compare.expected | 2 +-
.../ControlFlow/dominators/DominatesConsistency.expected | 2 +-
python/ql/test/library-tests/ControlFlow/except/test.expected | 2 +-
python/ql/test/library-tests/ControlFlow/general/Cyclo.expected | 2 +-
.../ql/test/library-tests/ControlFlow/general/Reaches.expected | 2 +-
.../test/library-tests/ControlFlow/ssa/deletions/test.expected | 2 +-
python/ql/test/library-tests/PointsTo/functions/test.expected | 2 +-
.../test/library-tests/PointsTo/inheritance/SuperTypes.expected | 2 +-
python/ql/test/library-tests/PointsTo/lookup/Lookup.expected | 2 +-
python/ql/test/library-tests/attributes/SelfAttribute.expected | 2 +-
python/ql/test/library-tests/classes/attr/class_attr.expected | 2 +-
.../test/library-tests/classes/attr/class_defined_attr.expected | 2 +-
.../test/library-tests/classes/attr/class_defines_attr.expected | 2 +-
.../ql/test/library-tests/classes/attr/class_has_attr.expected | 2 +-
python/ql/test/library-tests/classes/attr/hash.expected | 2 +-
python/ql/test/library-tests/comments/blocks.expected | 2 +-
.../ql/test/library-tests/comments/blocks_not_example.expected | 2 +-
python/ql/test/library-tests/comments/lines.expected | 2 +-
.../ql/test/library-tests/comments/lines_not_example.expected | 2 +-
python/ql/test/library-tests/exceptions/Legal.expected | 2 +-
python/ql/test/library-tests/imports/Alias.expected | 2 +-
.../library-tests/locations/negative_numbers/negative.expected | 2 +-
python/ql/test/library-tests/parentheses/Parens.expected | 2 +-
.../ql/test/library-tests/stmts/general/SubExpressions.expected | 2 +-
python/ql/test/library-tests/stmts/raise_stmt/AST.expected | 2 +-
python/ql/test/library-tests/stmts/try_stmt/AST.expected | 2 +-
python/ql/test/library-tests/stmts/with_stmt/AST.expected | 2 +-
python/ql/test/library-tests/types/properties/Deleters.expected | 2 +-
python/ql/test/library-tests/types/properties/Getters.expected | 2 +-
.../library-tests/types/properties/PythonProperties.expected | 2 +-
python/ql/test/library-tests/types/properties/Setters.expected | 2 +-
56 files changed, 56 insertions(+), 56 deletions(-)
diff --git a/python/ql/test/2/library-tests/ControlFlow/Exceptions/Handles.expected b/python/ql/test/2/library-tests/ControlFlow/Exceptions/Handles.expected
index 8286f8ff79f..0ecb19a002e 100644
--- a/python/ql/test/2/library-tests/ControlFlow/Exceptions/Handles.expected
+++ b/python/ql/test/2/library-tests/ControlFlow/Exceptions/Handles.expected
@@ -8,4 +8,4 @@
| 38 | ControlFlowNode for ExceptStmt | builtin-class AttributeError |
| 40 | ControlFlowNode for ExceptStmt | builtin-class IndexError |
| 42 | ControlFlowNode for ExceptStmt | builtin-class KeyError |
-| 57 | ControlFlowNode for ExceptStmt | builtin-class IOError |
\ No newline at end of file
+| 57 | ControlFlowNode for ExceptStmt | builtin-class IOError |
diff --git a/python/ql/test/2/library-tests/ControlFlow/Exceptions/Known.expected b/python/ql/test/2/library-tests/ControlFlow/Exceptions/Known.expected
index ae57cba62e4..acaa91c4f77 100644
--- a/python/ql/test/2/library-tests/ControlFlow/Exceptions/Known.expected
+++ b/python/ql/test/2/library-tests/ControlFlow/Exceptions/Known.expected
@@ -12,4 +12,4 @@
| 35 | ControlFlowNode for Attribute | builtin-class AttributeError |
| 37 | ControlFlowNode for Raise | builtin-class Exception |
| 53 | ControlFlowNode for Attribute() | builtin-class IOError |
-| 54 | ControlFlowNode for Attribute() | builtin-class IOError |
\ No newline at end of file
+| 54 | ControlFlowNode for Attribute() | builtin-class IOError |
diff --git a/python/ql/test/2/library-tests/ControlFlow/Exceptions/Unknown.expected b/python/ql/test/2/library-tests/ControlFlow/Exceptions/Unknown.expected
index 4d570959d6e..28851ef9a46 100644
--- a/python/ql/test/2/library-tests/ControlFlow/Exceptions/Unknown.expected
+++ b/python/ql/test/2/library-tests/ControlFlow/Exceptions/Unknown.expected
@@ -3,4 +3,4 @@
| 36 | ControlFlowNode for a() |
| 51 | ControlFlowNode for open() |
| 56 | ControlFlowNode for Attribute() |
-| 58 | ControlFlowNode for Attribute() |
\ No newline at end of file
+| 58 | ControlFlowNode for Attribute() |
diff --git a/python/ql/test/2/library-tests/classes/attr/class_has_attr.expected b/python/ql/test/2/library-tests/classes/attr/class_has_attr.expected
index 7bcbd739d3c..4de9f4b4dda 100644
--- a/python/ql/test/2/library-tests/classes/attr/class_has_attr.expected
+++ b/python/ql/test/2/library-tests/classes/attr/class_has_attr.expected
@@ -7,4 +7,4 @@
| 36 | class DerivedFromBuiltin | pop |
| 36 | class DerivedFromBuiltin | remove |
| 36 | class DerivedFromBuiltin | reverse |
-| 36 | class DerivedFromBuiltin | sort |
\ No newline at end of file
+| 36 | class DerivedFromBuiltin | sort |
diff --git a/python/ql/test/2/library-tests/comprehensions/ConsistencyCheck.expected b/python/ql/test/2/library-tests/comprehensions/ConsistencyCheck.expected
index c44d5fb5f0a..f082a67fcf6 100644
--- a/python/ql/test/2/library-tests/comprehensions/ConsistencyCheck.expected
+++ b/python/ql/test/2/library-tests/comprehensions/ConsistencyCheck.expected
@@ -1 +1 @@
-| 0 |
\ No newline at end of file
+| 0 |
diff --git a/python/ql/test/2/library-tests/modules/general/import_test.expected b/python/ql/test/2/library-tests/modules/general/import_test.expected
index e15685d33db..afaa1ccc7b2 100644
--- a/python/ql/test/2/library-tests/modules/general/import_test.expected
+++ b/python/ql/test/2/library-tests/modules/general/import_test.expected
@@ -12,4 +12,4 @@
| Module package.helper | 2 | ImportExpr | 0 | bottom | absolute | assistant |
| Module package.helper | 3 | ImportExpr | 0 | top | absolute | sys |
| Module package.helper | 10 | ImportExpr | 1 | bottom | relative | package |
-| Module test_star | 1 | ImportExpr | -1 | bottom | absolute | test_package |
\ No newline at end of file
+| Module test_star | 1 | ImportExpr | -1 | bottom | absolute | test_package |
diff --git a/python/ql/test/2/library-tests/modules/package_members/module_attributes.expected b/python/ql/test/2/library-tests/modules/package_members/module_attributes.expected
index f450f15d13e..7914748b3a7 100644
--- a/python/ql/test/2/library-tests/modules/package_members/module_attributes.expected
+++ b/python/ql/test/2/library-tests/modules/package_members/module_attributes.expected
@@ -54,4 +54,4 @@
| Module test_star | p | str b'p' |
| Module test_star | q | str b'q' |
| Module test_star | r | str b'r' |
-| Module test_star | sys | Module sys |
\ No newline at end of file
+| Module test_star | sys | Module sys |
diff --git a/python/ql/test/2/library-tests/modules/package_members/module_exports.expected b/python/ql/test/2/library-tests/modules/package_members/module_exports.expected
index 3a58b41c0b4..3b42e772bab 100644
--- a/python/ql/test/2/library-tests/modules/package_members/module_exports.expected
+++ b/python/ql/test/2/library-tests/modules/package_members/module_exports.expected
@@ -39,4 +39,4 @@
| Module test_star | p |
| Module test_star | q |
| Module test_star | r |
-| Module test_star | sys |
\ No newline at end of file
+| Module test_star | sys |
diff --git a/python/ql/test/2/library-tests/modules/package_members/module_import_as.expected b/python/ql/test/2/library-tests/modules/package_members/module_import_as.expected
index 5610cff4000..1f2095f6fde 100644
--- a/python/ql/test/2/library-tests/modules/package_members/module_import_as.expected
+++ b/python/ql/test/2/library-tests/modules/package_members/module_import_as.expected
@@ -5,4 +5,4 @@
| Module test_package.module2 | test_package.module2 |
| Module test_package.module3 | test_package.module3 |
| Module test_package.module4 | test_package.module4 |
-| Module test_star | test_star |
\ No newline at end of file
+| Module test_star | test_star |
diff --git a/python/ql/test/2/library-tests/types/properties/BuiltinProperties.expected b/python/ql/test/2/library-tests/types/properties/BuiltinProperties.expected
index 20f721fa72a..914450a2ad9 100644
--- a/python/ql/test/2/library-tests/types/properties/BuiltinProperties.expected
+++ b/python/ql/test/2/library-tests/types/properties/BuiltinProperties.expected
@@ -4,4 +4,4 @@
| builtin-class type | __dict__ | Property __dict__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __doc__ | Property __doc__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __module__ | Property __module__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
-| builtin-class type | __name__ | Property __name__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
\ No newline at end of file
+| builtin-class type | __name__ | Property __name__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
diff --git a/python/ql/test/3/library-tests/ControlFlow/Exceptions/Handles.expected b/python/ql/test/3/library-tests/ControlFlow/Exceptions/Handles.expected
index e6e6fb6b4c5..ca0d2048dc7 100644
--- a/python/ql/test/3/library-tests/ControlFlow/Exceptions/Handles.expected
+++ b/python/ql/test/3/library-tests/ControlFlow/Exceptions/Handles.expected
@@ -8,4 +8,4 @@
| 38 | ControlFlowNode for ExceptStmt | builtin-class AttributeError |
| 40 | ControlFlowNode for ExceptStmt | builtin-class IndexError |
| 42 | ControlFlowNode for ExceptStmt | builtin-class KeyError |
-| 57 | ControlFlowNode for ExceptStmt | builtin-class OSError |
\ No newline at end of file
+| 57 | ControlFlowNode for ExceptStmt | builtin-class OSError |
diff --git a/python/ql/test/3/library-tests/ControlFlow/Exceptions/Known.expected b/python/ql/test/3/library-tests/ControlFlow/Exceptions/Known.expected
index 99abc64c71c..5bddba6eafe 100644
--- a/python/ql/test/3/library-tests/ControlFlow/Exceptions/Known.expected
+++ b/python/ql/test/3/library-tests/ControlFlow/Exceptions/Known.expected
@@ -12,4 +12,4 @@
| 35 | ControlFlowNode for Attribute | builtin-class AttributeError |
| 37 | ControlFlowNode for Raise | builtin-class Exception |
| 53 | ControlFlowNode for Attribute() | builtin-class OSError |
-| 54 | ControlFlowNode for Attribute() | builtin-class OSError |
\ No newline at end of file
+| 54 | ControlFlowNode for Attribute() | builtin-class OSError |
diff --git a/python/ql/test/3/library-tests/ControlFlow/Exceptions/Unknown.expected b/python/ql/test/3/library-tests/ControlFlow/Exceptions/Unknown.expected
index 4d570959d6e..28851ef9a46 100644
--- a/python/ql/test/3/library-tests/ControlFlow/Exceptions/Unknown.expected
+++ b/python/ql/test/3/library-tests/ControlFlow/Exceptions/Unknown.expected
@@ -3,4 +3,4 @@
| 36 | ControlFlowNode for a() |
| 51 | ControlFlowNode for open() |
| 56 | ControlFlowNode for Attribute() |
-| 58 | ControlFlowNode for Attribute() |
\ No newline at end of file
+| 58 | ControlFlowNode for Attribute() |
diff --git a/python/ql/test/3/library-tests/PointsTo/import_time/Pruned.expected b/python/ql/test/3/library-tests/PointsTo/import_time/Pruned.expected
index 88e3d8aa2de..716370a16f2 100644
--- a/python/ql/test/3/library-tests/PointsTo/import_time/Pruned.expected
+++ b/python/ql/test/3/library-tests/PointsTo/import_time/Pruned.expected
@@ -1,2 +1,2 @@
| 28 |
-| 42 |
\ No newline at end of file
+| 42 |
diff --git a/python/ql/test/3/library-tests/classes/attr/class_attr.expected b/python/ql/test/3/library-tests/classes/attr/class_attr.expected
index cb9a29c27db..35b26e0e1b7 100644
--- a/python/ql/test/3/library-tests/classes/attr/class_attr.expected
+++ b/python/ql/test/3/library-tests/classes/attr/class_attr.expected
@@ -9,4 +9,4 @@
| 3 | class DerivedFromBuiltin | pop | Builtin-method pop |
| 3 | class DerivedFromBuiltin | remove | Builtin-method remove |
| 3 | class DerivedFromBuiltin | reverse | Builtin-method reverse |
-| 3 | class DerivedFromBuiltin | sort | Builtin-method sort |
\ No newline at end of file
+| 3 | class DerivedFromBuiltin | sort | Builtin-method sort |
diff --git a/python/ql/test/3/library-tests/classes/attr/class_has_attr.expected b/python/ql/test/3/library-tests/classes/attr/class_has_attr.expected
index 99721ecd3ce..7615be492b4 100644
--- a/python/ql/test/3/library-tests/classes/attr/class_has_attr.expected
+++ b/python/ql/test/3/library-tests/classes/attr/class_has_attr.expected
@@ -9,4 +9,4 @@
| 3 | class DerivedFromBuiltin | pop |
| 3 | class DerivedFromBuiltin | remove |
| 3 | class DerivedFromBuiltin | reverse |
-| 3 | class DerivedFromBuiltin | sort |
\ No newline at end of file
+| 3 | class DerivedFromBuiltin | sort |
diff --git a/python/ql/test/3/library-tests/classes/meta/meta.expected b/python/ql/test/3/library-tests/classes/meta/meta.expected
index a0597936673..5daa7e65135 100644
--- a/python/ql/test/3/library-tests/classes/meta/meta.expected
+++ b/python/ql/test/3/library-tests/classes/meta/meta.expected
@@ -1 +1 @@
-| ClassExpr | Meta |
\ No newline at end of file
+| ClassExpr | Meta |
diff --git a/python/ql/test/3/library-tests/classes/meta/meta_obj.expected b/python/ql/test/3/library-tests/classes/meta/meta_obj.expected
index 8c8f5618ff9..d0e98740490 100644
--- a/python/ql/test/3/library-tests/classes/meta/meta_obj.expected
+++ b/python/ql/test/3/library-tests/classes/meta/meta_obj.expected
@@ -1,2 +1,2 @@
| class HasMeta | class Meta |
-| class Meta | builtin-class type |
\ No newline at end of file
+| class Meta | builtin-class type |
diff --git a/python/ql/test/3/library-tests/modules/package_members/module_attributes.expected b/python/ql/test/3/library-tests/modules/package_members/module_attributes.expected
index ae2a037e77a..e6dbf62d41e 100644
--- a/python/ql/test/3/library-tests/modules/package_members/module_attributes.expected
+++ b/python/ql/test/3/library-tests/modules/package_members/module_attributes.expected
@@ -57,4 +57,4 @@
| Module test_star | p | str u'p' |
| Module test_star | q | str u'q' |
| Module test_star | r | str u'r' |
-| Module test_star | sys | Module sys |
\ No newline at end of file
+| Module test_star | sys | Module sys |
diff --git a/python/ql/test/3/library-tests/modules/package_members/module_exports.expected b/python/ql/test/3/library-tests/modules/package_members/module_exports.expected
index b25017607b2..44ccbb2da1e 100644
--- a/python/ql/test/3/library-tests/modules/package_members/module_exports.expected
+++ b/python/ql/test/3/library-tests/modules/package_members/module_exports.expected
@@ -41,4 +41,4 @@
| Module test_star | p |
| Module test_star | q |
| Module test_star | r |
-| Module test_star | sys |
\ No newline at end of file
+| Module test_star | sys |
diff --git a/python/ql/test/3/library-tests/modules/package_members/module_import_as.expected b/python/ql/test/3/library-tests/modules/package_members/module_import_as.expected
index 5cb15a54429..d96a4d1e25c 100644
--- a/python/ql/test/3/library-tests/modules/package_members/module_import_as.expected
+++ b/python/ql/test/3/library-tests/modules/package_members/module_import_as.expected
@@ -6,4 +6,4 @@
| Module test_package.module3 | test_package.module3 |
| Module test_package.module4 | test_package.module4 |
| Module test_package.module5 | test_package.module5 |
-| Module test_star | test_star |
\ No newline at end of file
+| Module test_star | test_star |
diff --git a/python/ql/test/3/library-tests/types/functions/ReturnTypes.expected b/python/ql/test/3/library-tests/types/functions/ReturnTypes.expected
index db2290e09e7..2f3871a7c69 100644
--- a/python/ql/test/3/library-tests/types/functions/ReturnTypes.expected
+++ b/python/ql/test/3/library-tests/types/functions/ReturnTypes.expected
@@ -21,4 +21,4 @@
| 112 | multi_return | builtin-class int |
| 118 | do_something | builtin-class int |
| 123 | with_flow | builtin-class int |
-| 128 | return_default | builtin-class tuple |
\ No newline at end of file
+| 128 | return_default | builtin-class tuple |
diff --git a/python/ql/test/3/library-tests/types/properties/BuiltinProperties.expected b/python/ql/test/3/library-tests/types/properties/BuiltinProperties.expected
index d96c00d5d32..f34fdbd68b6 100644
--- a/python/ql/test/3/library-tests/types/properties/BuiltinProperties.expected
+++ b/python/ql/test/3/library-tests/types/properties/BuiltinProperties.expected
@@ -6,4 +6,4 @@
| builtin-class type | __module__ | Property __module__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __name__ | Property __name__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __qualname__ | Property __qualname__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
-| builtin-class type | __text_signature__ | Property __text_signature__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
\ No newline at end of file
+| builtin-class type | __text_signature__ | Property __text_signature__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
diff --git a/python/ql/test/library-tests/ControlFlow/augassign/AugAssignFlow.expected b/python/ql/test/library-tests/ControlFlow/augassign/AugAssignFlow.expected
index f5ab8c8a6f1..0939d480cb8 100644
--- a/python/ql/test/library-tests/ControlFlow/augassign/AugAssignFlow.expected
+++ b/python/ql/test/library-tests/ControlFlow/augassign/AugAssignFlow.expected
@@ -4,4 +4,4 @@
| ControlFlowNode for Subscript | ControlFlowNode for Subscript | 23 |
| ControlFlowNode for v | ControlFlowNode for v | 28 |
| ControlFlowNode for x | ControlFlowNode for x | 7 |
-| ControlFlowNode for x | ControlFlowNode for x | 21 |
\ No newline at end of file
+| ControlFlowNode for x | ControlFlowNode for x | 21 |
diff --git a/python/ql/test/library-tests/ControlFlow/augassign/SSA.expected b/python/ql/test/library-tests/ControlFlow/augassign/SSA.expected
index f5c89ccdfc4..581a692e88c 100644
--- a/python/ql/test/library-tests/ControlFlow/augassign/SSA.expected
+++ b/python/ql/test/library-tests/ControlFlow/augassign/SSA.expected
@@ -1,3 +1,3 @@
| ControlFlowNode for v | 28 |
| ControlFlowNode for x | 7 |
-| ControlFlowNode for x | 21 |
\ No newline at end of file
+| ControlFlowNode for x | 21 |
diff --git a/python/ql/test/library-tests/ControlFlow/comparison/Compare.expected b/python/ql/test/library-tests/ControlFlow/comparison/Compare.expected
index 34cb8350342..4e1ea1abe8f 100644
--- a/python/ql/test/library-tests/ControlFlow/comparison/Compare.expected
+++ b/python/ql/test/library-tests/ControlFlow/comparison/Compare.expected
@@ -3,4 +3,4 @@
| 3 | ControlFlowNode for Compare | e | f | < |
| 4 | ControlFlowNode for Compare | g | h | >= |
| 5 | ControlFlowNode for Compare | i | j | <= |
-| 6 | ControlFlowNode for Compare | k | l | != |
\ No newline at end of file
+| 6 | ControlFlowNode for Compare | k | l | != |
diff --git a/python/ql/test/library-tests/ControlFlow/dominators/DominatesConsistency.expected b/python/ql/test/library-tests/ControlFlow/dominators/DominatesConsistency.expected
index fe98b155587..cf01bbbac55 100644
--- a/python/ql/test/library-tests/ControlFlow/dominators/DominatesConsistency.expected
+++ b/python/ql/test/library-tests/ControlFlow/dominators/DominatesConsistency.expected
@@ -1 +1 @@
-| 0 | 0 |
\ No newline at end of file
+| 0 | 0 |
diff --git a/python/ql/test/library-tests/ControlFlow/except/test.expected b/python/ql/test/library-tests/ControlFlow/except/test.expected
index da4b21d23df..ca20f5706f6 100644
--- a/python/ql/test/library-tests/ControlFlow/except/test.expected
+++ b/python/ql/test/library-tests/ControlFlow/except/test.expected
@@ -6,4 +6,4 @@
| ec |
| ed |
| ee |
-| ef |
\ No newline at end of file
+| ef |
diff --git a/python/ql/test/library-tests/ControlFlow/general/Cyclo.expected b/python/ql/test/library-tests/ControlFlow/general/Cyclo.expected
index e814047bf80..60f7bd7de57 100644
--- a/python/ql/test/library-tests/ControlFlow/general/Cyclo.expected
+++ b/python/ql/test/library-tests/ControlFlow/general/Cyclo.expected
@@ -6,4 +6,4 @@
| Function normal_args | 1 |
| Function special_args | 1 |
| Function try_except | 4 |
-| Function try_finally | 2 |
\ No newline at end of file
+| Function try_finally | 2 |
diff --git a/python/ql/test/library-tests/ControlFlow/general/Reaches.expected b/python/ql/test/library-tests/ControlFlow/general/Reaches.expected
index 4fc0324ad13..f37824aa11f 100644
--- a/python/ql/test/library-tests/ControlFlow/general/Reaches.expected
+++ b/python/ql/test/library-tests/ControlFlow/general/Reaches.expected
@@ -16,4 +16,4 @@
| try_body1 |
| try_body2 |
| try_body3 |
-| try_body4 |
\ No newline at end of file
+| try_body4 |
diff --git a/python/ql/test/library-tests/ControlFlow/ssa/deletions/test.expected b/python/ql/test/library-tests/ControlFlow/ssa/deletions/test.expected
index a80d1fe8beb..f4459604e7e 100644
--- a/python/ql/test/library-tests/ControlFlow/ssa/deletions/test.expected
+++ b/python/ql/test/library-tests/ControlFlow/ssa/deletions/test.expected
@@ -3,4 +3,4 @@
| 10 | ControlFlowNode for u3 | u3 | delete |
| 10 | ControlFlowNode for use | use | other |
| 18 | ControlFlowNode for u2 | u2 | delete |
-| 21 | ControlFlowNode for u3 | u3 | delete |
\ No newline at end of file
+| 21 | ControlFlowNode for u3 | u3 | delete |
diff --git a/python/ql/test/library-tests/PointsTo/functions/test.expected b/python/ql/test/library-tests/PointsTo/functions/test.expected
index e2959372536..f50338165a3 100644
--- a/python/ql/test/library-tests/PointsTo/functions/test.expected
+++ b/python/ql/test/library-tests/PointsTo/functions/test.expected
@@ -1,2 +1,2 @@
| 9 | Function meth |
-| 14 | Function meth |
\ No newline at end of file
+| 14 | Function meth |
diff --git a/python/ql/test/library-tests/PointsTo/inheritance/SuperTypes.expected b/python/ql/test/library-tests/PointsTo/inheritance/SuperTypes.expected
index 48ef4076ed2..98833aa0ae7 100644
--- a/python/ql/test/library-tests/PointsTo/inheritance/SuperTypes.expected
+++ b/python/ql/test/library-tests/PointsTo/inheritance/SuperTypes.expected
@@ -34,4 +34,4 @@
| class Wrong2 | class Base |
| class Wrong2 | class Derived1 |
| class Wrong2 | class Derived2 |
-| class Wrong2 | class Derived3 |
\ No newline at end of file
+| class Wrong2 | class Derived3 |
diff --git a/python/ql/test/library-tests/PointsTo/lookup/Lookup.expected b/python/ql/test/library-tests/PointsTo/lookup/Lookup.expected
index d01f9d843aa..7594a005ada 100644
--- a/python/ql/test/library-tests/PointsTo/lookup/Lookup.expected
+++ b/python/ql/test/library-tests/PointsTo/lookup/Lookup.expected
@@ -76,4 +76,4 @@
| 136 | x | global |
| 140 | object | global |
| 142 | x | global |
-| 143 | x | local |
\ No newline at end of file
+| 143 | x | local |
diff --git a/python/ql/test/library-tests/attributes/SelfAttribute.expected b/python/ql/test/library-tests/attributes/SelfAttribute.expected
index 7d5843ffbe0..cf3ed61b50b 100644
--- a/python/ql/test/library-tests/attributes/SelfAttribute.expected
+++ b/python/ql/test/library-tests/attributes/SelfAttribute.expected
@@ -1,4 +1,4 @@
| 10 | a1 | defined |
| 18 | a2 | defined |
| 21 | a0 | |
-| 25 | a1 | guarded |
\ No newline at end of file
+| 25 | a1 | guarded |
diff --git a/python/ql/test/library-tests/classes/attr/class_attr.expected b/python/ql/test/library-tests/classes/attr/class_attr.expected
index 65d7b79023b..70a7962cbb5 100644
--- a/python/ql/test/library-tests/classes/attr/class_attr.expected
+++ b/python/ql/test/library-tests/classes/attr/class_attr.expected
@@ -29,4 +29,4 @@
| 103 | class Sub | float | builtin-class float |
| 103 | class Sub | h | Builtin-function hash |
| 103 | class Sub | int | builtin-class int |
-| 103 | class Sub | l | Builtin-function len |
\ No newline at end of file
+| 103 | class Sub | l | Builtin-function len |
diff --git a/python/ql/test/library-tests/classes/attr/class_defined_attr.expected b/python/ql/test/library-tests/classes/attr/class_defined_attr.expected
index 26712c5f275..4d8f464843f 100644
--- a/python/ql/test/library-tests/classes/attr/class_defined_attr.expected
+++ b/python/ql/test/library-tests/classes/attr/class_defined_attr.expected
@@ -16,4 +16,4 @@
| 96 | class Oddities | float | builtin-class float |
| 96 | class Oddities | h | Builtin-function hash |
| 96 | class Oddities | int | builtin-class int |
-| 96 | class Oddities | l | Builtin-function len |
\ No newline at end of file
+| 96 | class Oddities | l | Builtin-function len |
diff --git a/python/ql/test/library-tests/classes/attr/class_defines_attr.expected b/python/ql/test/library-tests/classes/attr/class_defines_attr.expected
index 88adc304ada..eb7d71b0e73 100644
--- a/python/ql/test/library-tests/classes/attr/class_defines_attr.expected
+++ b/python/ql/test/library-tests/classes/attr/class_defines_attr.expected
@@ -19,4 +19,4 @@
| 96 | class Oddities | float |
| 96 | class Oddities | h |
| 96 | class Oddities | int |
-| 96 | class Oddities | l |
\ No newline at end of file
+| 96 | class Oddities | l |
diff --git a/python/ql/test/library-tests/classes/attr/class_has_attr.expected b/python/ql/test/library-tests/classes/attr/class_has_attr.expected
index e73ad4d1894..ed51f498a38 100644
--- a/python/ql/test/library-tests/classes/attr/class_has_attr.expected
+++ b/python/ql/test/library-tests/classes/attr/class_has_attr.expected
@@ -34,4 +34,4 @@
| 103 | class Sub | float |
| 103 | class Sub | h |
| 103 | class Sub | int |
-| 103 | class Sub | l |
\ No newline at end of file
+| 103 | class Sub | l |
diff --git a/python/ql/test/library-tests/classes/attr/hash.expected b/python/ql/test/library-tests/classes/attr/hash.expected
index a65142422a0..00800c3f262 100644
--- a/python/ql/test/library-tests/classes/attr/hash.expected
+++ b/python/ql/test/library-tests/classes/attr/hash.expected
@@ -1,2 +1,2 @@
| 92 | class Unhashable | NoneType None |
-| 103 | class Sub | NoneType None |
\ No newline at end of file
+| 103 | class Sub | NoneType None |
diff --git a/python/ql/test/library-tests/comments/blocks.expected b/python/ql/test/library-tests/comments/blocks.expected
index d337745d4d4..74942439562 100644
--- a/python/ql/test/library-tests/comments/blocks.expected
+++ b/python/ql/test/library-tests/comments/blocks.expected
@@ -1,4 +1,4 @@
| 15 | 16 | Commented out code |
| 21 | 72 | Commented out code |
| 78 | 85 | Commented out code |
-| 94 | 97 | Commented out code |
\ No newline at end of file
+| 94 | 97 | Commented out code |
diff --git a/python/ql/test/library-tests/comments/blocks_not_example.expected b/python/ql/test/library-tests/comments/blocks_not_example.expected
index 7a0a7158601..3d6fbc8f7f3 100644
--- a/python/ql/test/library-tests/comments/blocks_not_example.expected
+++ b/python/ql/test/library-tests/comments/blocks_not_example.expected
@@ -1,3 +1,3 @@
| 15 | 16 | Commented out code |
| 21 | 72 | Commented out code |
-| 78 | 85 | Commented out code |
\ No newline at end of file
+| 78 | 85 | Commented out code |
diff --git a/python/ql/test/library-tests/comments/lines.expected b/python/ql/test/library-tests/comments/lines.expected
index 7c45cf8cd11..6e36571b543 100644
--- a/python/ql/test/library-tests/comments/lines.expected
+++ b/python/ql/test/library-tests/comments/lines.expected
@@ -43,4 +43,4 @@
| 94 | Comment # def f(): |
| 95 | Comment # call() |
| 96 | Comment # x.y = z |
-| 97 | Comment # return x |
\ No newline at end of file
+| 97 | Comment # return x |
diff --git a/python/ql/test/library-tests/comments/lines_not_example.expected b/python/ql/test/library-tests/comments/lines_not_example.expected
index f476f967cda..bf9849826f2 100644
--- a/python/ql/test/library-tests/comments/lines_not_example.expected
+++ b/python/ql/test/library-tests/comments/lines_not_example.expected
@@ -39,4 +39,4 @@
| 82 | Comment #except Exception: |
| 83 | Comment # pass |
| 84 | Comment #except: |
-| 85 | Comment # pass |
\ No newline at end of file
+| 85 | Comment # pass |
diff --git a/python/ql/test/library-tests/exceptions/Legal.expected b/python/ql/test/library-tests/exceptions/Legal.expected
index 1b6fd6ec1c4..34ff257193a 100644
--- a/python/ql/test/library-tests/exceptions/Legal.expected
+++ b/python/ql/test/library-tests/exceptions/Legal.expected
@@ -9,4 +9,4 @@
| class InnerNotException1 | no |
| class InnerNotException2 | no |
| class NotException1 | no |
-| class NotException2 | no |
\ No newline at end of file
+| class NotException2 | no |
diff --git a/python/ql/test/library-tests/imports/Alias.expected b/python/ql/test/library-tests/imports/Alias.expected
index 6ea5e16c29c..a74dfb46b58 100644
--- a/python/ql/test/library-tests/imports/Alias.expected
+++ b/python/ql/test/library-tests/imports/Alias.expected
@@ -1,3 +1,3 @@
| Alias | a | a |
| Alias | b | b |
-| Alias | c | d |
\ No newline at end of file
+| Alias | c | d |
diff --git a/python/ql/test/library-tests/locations/negative_numbers/negative.expected b/python/ql/test/library-tests/locations/negative_numbers/negative.expected
index 77c824ac91f..8122e2c860a 100644
--- a/python/ql/test/library-tests/locations/negative_numbers/negative.expected
+++ b/python/ql/test/library-tests/locations/negative_numbers/negative.expected
@@ -23,4 +23,4 @@
| UnaryExpr | 15 | 2 | 15 | 19 | () |
| UnaryExpr | 16 | 2 | 16 | 5 | () |
| UnaryExpr | 17 | 2 | 17 | 8 | () |
-| UnaryExpr | 19 | 1 | 19 | 3 | |
\ No newline at end of file
+| UnaryExpr | 19 | 1 | 19 | 3 | |
diff --git a/python/ql/test/library-tests/parentheses/Parens.expected b/python/ql/test/library-tests/parentheses/Parens.expected
index c19d295830d..4be830e85ae 100644
--- a/python/ql/test/library-tests/parentheses/Parens.expected
+++ b/python/ql/test/library-tests/parentheses/Parens.expected
@@ -27,4 +27,4 @@
| 52 | BinaryExpr |
| 55 | BinaryExpr |
| 56 | BinaryExpr |
-| 61 | Tuple |
\ No newline at end of file
+| 61 | Tuple |
diff --git a/python/ql/test/library-tests/stmts/general/SubExpressions.expected b/python/ql/test/library-tests/stmts/general/SubExpressions.expected
index e40356ab46b..503475c0eca 100644
--- a/python/ql/test/library-tests/stmts/general/SubExpressions.expected
+++ b/python/ql/test/library-tests/stmts/general/SubExpressions.expected
@@ -3,4 +3,4 @@
| Delete | Subscript | Subscript | 2 |
| Delete | Subscript | a | 2 |
| Delete | Subscript | b | 2 |
-| Delete | x | x | 3 |
\ No newline at end of file
+| Delete | x | x | 3 |
diff --git a/python/ql/test/library-tests/stmts/raise_stmt/AST.expected b/python/ql/test/library-tests/stmts/raise_stmt/AST.expected
index 655013b4592..28a9d342648 100644
--- a/python/ql/test/library-tests/stmts/raise_stmt/AST.expected
+++ b/python/ql/test/library-tests/stmts/raise_stmt/AST.expected
@@ -4,4 +4,4 @@
| 2 | FunctionDef | 2 | FunctionExpr |
| 2 | FunctionDef | 2 | f |
| 2 | FunctionExpr | 2 | Function f |
-| 4 | Raise | 4 | Exception |
\ No newline at end of file
+| 4 | Raise | 4 | Exception |
diff --git a/python/ql/test/library-tests/stmts/try_stmt/AST.expected b/python/ql/test/library-tests/stmts/try_stmt/AST.expected
index a8c2778fc99..adf1db6e7a7 100644
--- a/python/ql/test/library-tests/stmts/try_stmt/AST.expected
+++ b/python/ql/test/library-tests/stmts/try_stmt/AST.expected
@@ -31,4 +31,4 @@
| 18 | ExprStmt | 18 | call3a() |
| 18 | call3a() | 18 | call3a |
| 20 | ExprStmt | 20 | call3b() |
-| 20 | call3b() | 20 | call3b |
\ No newline at end of file
+| 20 | call3b() | 20 | call3b |
diff --git a/python/ql/test/library-tests/stmts/with_stmt/AST.expected b/python/ql/test/library-tests/stmts/with_stmt/AST.expected
index acae99eab4c..c46f1256a16 100644
--- a/python/ql/test/library-tests/stmts/with_stmt/AST.expected
+++ b/python/ql/test/library-tests/stmts/with_stmt/AST.expected
@@ -17,4 +17,4 @@
| 8 | With | 8 | y |
| 8 | With | 9 | ExprStmt |
| 9 | ExprStmt | 9 | call() |
-| 9 | call() | 9 | call |
\ No newline at end of file
+| 9 | call() | 9 | call |
diff --git a/python/ql/test/library-tests/types/properties/Deleters.expected b/python/ql/test/library-tests/types/properties/Deleters.expected
index 1fb91ed794b..e3520ed3c6c 100644
--- a/python/ql/test/library-tests/types/properties/Deleters.expected
+++ b/python/ql/test/library-tests/types/properties/Deleters.expected
@@ -1 +1 @@
-| Property p2 | Function p2 |
\ No newline at end of file
+| Property p2 | Function p2 |
diff --git a/python/ql/test/library-tests/types/properties/Getters.expected b/python/ql/test/library-tests/types/properties/Getters.expected
index c451d9c1f38..7faca5f1aec 100644
--- a/python/ql/test/library-tests/types/properties/Getters.expected
+++ b/python/ql/test/library-tests/types/properties/Getters.expected
@@ -1,3 +1,3 @@
| Property p1 | Function p1 |
| Property p2 | Function p2 |
-| Property p3 | Function p3 |
\ No newline at end of file
+| Property p3 | Function p3 |
diff --git a/python/ql/test/library-tests/types/properties/PythonProperties.expected b/python/ql/test/library-tests/types/properties/PythonProperties.expected
index 4bb0de96c31..cb52d973b4e 100644
--- a/python/ql/test/library-tests/types/properties/PythonProperties.expected
+++ b/python/ql/test/library-tests/types/properties/PythonProperties.expected
@@ -1,3 +1,3 @@
| Property p1 |
| Property p2 |
-| Property p3 |
\ No newline at end of file
+| Property p3 |
diff --git a/python/ql/test/library-tests/types/properties/Setters.expected b/python/ql/test/library-tests/types/properties/Setters.expected
index 852998fd746..df863d0d417 100644
--- a/python/ql/test/library-tests/types/properties/Setters.expected
+++ b/python/ql/test/library-tests/types/properties/Setters.expected
@@ -1,2 +1,2 @@
| Property p1 | Function p1 |
-| Property p3 | Function p3_set |
\ No newline at end of file
+| Property p3 | Function p3_set |
From a46a7fadb262d228afb55d731f808f7d390dfbc9 Mon Sep 17 00:00:00 2001
From: Max Schaefer
Date: Mon, 13 Nov 2023 14:49:54 +0000
Subject: [PATCH 07/22] Java: Improve QHelp for `java/path-injection` to
mention less disruptive fixes.
---
.../src/Security/CWE/CWE-022/TaintedPath.java | 16 ++-------
.../Security/CWE/CWE-022/TaintedPath.qhelp | 35 ++++++++++++-------
.../Security/CWE/CWE-022/TaintedPathGood.java | 14 ++++++++
.../CWE-022/semmle/tests/TaintedPath.expected | 12 +++++++
.../CWE-022/semmle/tests/TaintedPath.java | 35 +++++++++++++++++++
.../security/CWE-022/semmle/tests/Test.java | 8 +++++
6 files changed, 93 insertions(+), 27 deletions(-)
create mode 100644 java/ql/src/Security/CWE/CWE-022/TaintedPathGood.java
create mode 100644 java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java
diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPath.java b/java/ql/src/Security/CWE/CWE-022/TaintedPath.java
index 339640ccc32..1fad061d0ba 100644
--- a/java/ql/src/Security/CWE/CWE-022/TaintedPath.java
+++ b/java/ql/src/Security/CWE/CWE-022/TaintedPath.java
@@ -2,23 +2,11 @@ public void sendUserFile(Socket sock, String user) {
BufferedReader filenameReader = new BufferedReader(
new InputStreamReader(sock.getInputStream(), "UTF-8"));
String filename = filenameReader.readLine();
- // BAD: read from a file using a path controlled by the user
- BufferedReader fileReader = new BufferedReader(
- new FileReader("/home/" + user + "/" + filename));
+ // BAD: read from a file without checking its path
+ BufferedReader fileReader = new BufferedReader(new FileReader(filename));
String fileLine = fileReader.readLine();
while(fileLine != null) {
sock.getOutputStream().write(fileLine.getBytes());
fileLine = fileReader.readLine();
}
}
-
-public void sendUserFileFixed(Socket sock, String user) {
- // ...
-
- // GOOD: remove all dots and directory delimiters from the filename before using
- String filename = filenameReader.readLine().replaceAll("\\.", "").replaceAll("/", "");
- BufferedReader fileReader = new BufferedReader(
- new FileReader("/home/" + user + "/" + filename));
-
- // ...
-}
diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp b/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp
index b32d3c65039..46a7a6d60cf 100644
--- a/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp
+++ b/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp
@@ -13,27 +13,36 @@ such as "..". Such a path may potentially point to any directory on the file sys
-Validate user input before using it to construct a file path. Ideally, follow these rules:
+Validate user input before using it to construct a file path.
-
-- Do not allow more than a single "." character.
-- Do not allow directory separators such as "/" or "\" (depending on the file system).
-- Do not rely on simply replacing problematic sequences such as "../". For example, after applying this filter to
-".../...//" the resulting string would still be "../".
-- Ideally use a whitelist of known good patterns.
-
+The choice of validation depends on the use case.
+
+If you want to allow paths spanning multiple folders, a common strategy is to make sure that the constructed
+file path is contained within a safe root folder, for example by checking that the path starts with the root folder.
+Additionally, you need to ensure that the path does not contain any ".." components, since these would allow
+the path to escape the root folder.
+
+A safer (but more restrictive) option is to use an allow list of safe paths and make sure that
+the user input is one of those paths.
-In this example, a file name is read from a java.net.Socket and then used to access a file in the
-user's home directory and send it back over the socket. However, a malicious user could enter a file name which contains special
-characters. For example, the string "../../etc/passwd" will result in the code reading the file located at
-"/home/[user]/../../etc/passwd", which is the system's password file. This file would then be sent back to the user,
-giving them access to all the system's passwords.
+In this example, a file name is read from a java.net.Socket and then used to access a file
+and send it back over the socket. However, a malicious user could enter a file name anywhere on the file system,
+such as "/etc/passwd".
+Simply checking that the path is under a trusted location (such as the user's home directory) is not enough,
+however, since the path could contain relative components such as "..". For example, the string
+"/home/[user]/../../etc/passwd" starts with the user's home directory, but would still result in the code reading
+the file located at "/etc/passwd".
+
+To fix this, we check that the user-provided path does not contain ".." and starts with the user's home directory.
+
+
+
diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPathGood.java b/java/ql/src/Security/CWE/CWE-022/TaintedPathGood.java
new file mode 100644
index 00000000000..dbd851846ce
--- /dev/null
+++ b/java/ql/src/Security/CWE/CWE-022/TaintedPathGood.java
@@ -0,0 +1,14 @@
+public void sendUserFileGood(Socket sock, String user) {
+ BufferedReader filenameReader = new BufferedReader(
+ new InputStreamReader(sock.getInputStream(), "UTF-8"));
+ String filename = filenameReader.readLine();
+ // GOOD: ensure that the file is in a designated folder in the user's home directory
+ if (!filePath.contains("..") && filePath.startsWith("/home/" + user + "/public/")) {
+ BufferedReader fileReader = new BufferedReader(new FileReader(filePath));
+ String fileLine = fileReader.readLine();
+ while(fileLine != null) {
+ sock.getOutputStream().write(fileLine.getBytes());
+ fileLine = fileReader.readLine();
+ }
+ }
+}
diff --git a/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.expected b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.expected
index 8ebc5a03a31..ff2a1aee759 100644
--- a/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.expected
+++ b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.expected
@@ -1,4 +1,9 @@
edges
+| TaintedPath.java:11:38:11:110 | new BufferedReader(...) : BufferedReader | TaintedPath.java:12:24:12:37 | filenameReader : BufferedReader |
+| TaintedPath.java:11:57:11:109 | new InputStreamReader(...) : InputStreamReader | TaintedPath.java:11:38:11:110 | new BufferedReader(...) : BufferedReader |
+| TaintedPath.java:11:79:11:99 | getInputStream(...) : InputStream | TaintedPath.java:11:57:11:109 | new InputStreamReader(...) : InputStreamReader |
+| TaintedPath.java:12:24:12:37 | filenameReader : BufferedReader | TaintedPath.java:12:24:12:48 | readLine(...) : String |
+| TaintedPath.java:12:24:12:48 | readLine(...) : String | TaintedPath.java:14:68:14:75 | filename |
| Test.java:19:18:19:38 | getHostName(...) : String | Test.java:24:20:24:23 | temp |
| Test.java:19:18:19:38 | getHostName(...) : String | Test.java:27:21:27:24 | temp |
| Test.java:19:18:19:38 | getHostName(...) : String | Test.java:30:44:30:47 | temp |
@@ -184,6 +189,12 @@ edges
| mad/Test.java:221:26:221:33 | source(...) : String | mad/Test.java:221:19:221:33 | (...)... |
| mad/Test.java:226:29:226:36 | source(...) : String | mad/Test.java:226:20:226:36 | (...)... |
nodes
+| TaintedPath.java:11:38:11:110 | new BufferedReader(...) : BufferedReader | semmle.label | new BufferedReader(...) : BufferedReader |
+| TaintedPath.java:11:57:11:109 | new InputStreamReader(...) : InputStreamReader | semmle.label | new InputStreamReader(...) : InputStreamReader |
+| TaintedPath.java:11:79:11:99 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
+| TaintedPath.java:12:24:12:37 | filenameReader : BufferedReader | semmle.label | filenameReader : BufferedReader |
+| TaintedPath.java:12:24:12:48 | readLine(...) : String | semmle.label | readLine(...) : String |
+| TaintedPath.java:14:68:14:75 | filename | semmle.label | filename |
| Test.java:19:18:19:38 | getHostName(...) : String | semmle.label | getHostName(...) : String |
| Test.java:24:20:24:23 | temp | semmle.label | temp |
| Test.java:27:21:27:24 | temp | semmle.label | temp |
@@ -375,6 +386,7 @@ nodes
| mad/Test.java:226:29:226:36 | source(...) : String | semmle.label | source(...) : String |
subpaths
#select
+| TaintedPath.java:14:53:14:76 | new FileReader(...) | TaintedPath.java:11:79:11:99 | getInputStream(...) : InputStream | TaintedPath.java:14:68:14:75 | filename | This path depends on a $@. | TaintedPath.java:11:79:11:99 | getInputStream(...) | user-provided value |
| Test.java:24:11:24:24 | new File(...) | Test.java:19:18:19:38 | getHostName(...) : String | Test.java:24:20:24:23 | temp | This path depends on a $@. | Test.java:19:18:19:38 | getHostName(...) | user-provided value |
| Test.java:27:11:27:25 | get(...) | Test.java:19:18:19:38 | getHostName(...) : String | Test.java:27:21:27:24 | temp | This path depends on a $@. | Test.java:19:18:19:38 | getHostName(...) | user-provided value |
| Test.java:30:11:30:48 | getPath(...) | Test.java:19:18:19:38 | getHostName(...) : String | Test.java:30:44:30:47 | temp | This path depends on a $@. | Test.java:19:18:19:38 | getHostName(...) | user-provided value |
diff --git a/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java
new file mode 100644
index 00000000000..2c97312cb76
--- /dev/null
+++ b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java
@@ -0,0 +1,35 @@
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.InputStreamReader;
+import java.net.Socket;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.io.IOException;
+
+public class TaintedPath {
+ public void sendUserFile(Socket sock, String user) throws IOException {
+ BufferedReader filenameReader = new BufferedReader(new InputStreamReader(sock.getInputStream(), "UTF-8"));
+ String filename = filenameReader.readLine();
+ // BAD: read from a file without checking its path
+ BufferedReader fileReader = new BufferedReader(new FileReader(filename));
+ String fileLine = fileReader.readLine();
+ while(fileLine != null) {
+ sock.getOutputStream().write(fileLine.getBytes());
+ fileLine = fileReader.readLine();
+ }
+ }
+
+ public void sendUserFileGood(Socket sock, String user) throws IOException {
+ BufferedReader filenameReader = new BufferedReader(new InputStreamReader(sock.getInputStream(), "UTF-8"));
+ String filePath = filenameReader.readLine();
+ // GOOD: ensure that the file is in a designated folder in the user's home directory
+ if (!filePath.contains("..") && filePath.startsWith("/home/" + user + "/public/")) {
+ BufferedReader fileReader = new BufferedReader(new FileReader(filePath));
+ String fileLine = fileReader.readLine();
+ while(fileLine != null) {
+ sock.getOutputStream().write(fileLine.getBytes());
+ fileLine = fileReader.readLine();
+ }
+ }
+ }
+}
diff --git a/java/ql/test/query-tests/security/CWE-022/semmle/tests/Test.java b/java/ql/test/query-tests/security/CWE-022/semmle/tests/Test.java
index 446c9b50a35..080cc263f08 100644
--- a/java/ql/test/query-tests/security/CWE-022/semmle/tests/Test.java
+++ b/java/ql/test/query-tests/security/CWE-022/semmle/tests/Test.java
@@ -101,4 +101,12 @@ class Test {
new File(new URI(null, null, null, 0, t, null, null));
}
+ void doGet6(String root, InetAddress address)
+ throws IOException{
+ String temp = address.getHostName();
+ // GOOD: Use `contains` and `startsWith` to check if the path is safe
+ if (!temp.contains("..") && temp.startsWith(root + "/")) {
+ File file = new File(temp);
+ }
+ }
}
From afe318edbe40a2c327c661b3ca4c4ee1e98a2615 Mon Sep 17 00:00:00 2001
From: Jeroen Ketema
Date: Thu, 16 Nov 2023 10:52:05 +0100
Subject: [PATCH 08/22] C++: Delete `cpp/tainted-format-string-through-global`
---
...UncontrolledFormatStringThroughGlobalVar.c | 24 -------
...ntrolledFormatStringThroughGlobalVar.qhelp | 36 ----------
...ncontrolledFormatStringThroughGlobalVar.ql | 40 -----------
...ed-format-string-through-global-deleted.md | 4 ++
...olledFormatStringThroughGlobalVar.expected | 69 -------------------
...ntrolledFormatStringThroughGlobalVar.qlref | 1 -
6 files changed, 4 insertions(+), 170 deletions(-)
delete mode 100644 cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.c
delete mode 100644 cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.qhelp
delete mode 100644 cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.ql
create mode 100644 cpp/ql/src/change-notes/2023-11-16-tainted-format-string-through-global-deleted.md
delete mode 100644 cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected
delete mode 100644 cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.qlref
diff --git a/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.c b/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.c
deleted file mode 100644
index 2700109a586..00000000000
--- a/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#include
-
-char *copy;
-
-void copyArgv(char **argv) {
- copy = argv[1];
-}
-
-void printWrapper(char *str) {
- printf(str);
-}
-
-int main(int argc, char **argv) {
- copyArgv(argv);
-
- // This should be avoided
- printf(copy);
-
- // This should be avoided too, because it has the same effect
- printWrapper(copy);
-
- // This is fine
- printf("%s", copy);
-}
diff --git a/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.qhelp b/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.qhelp
deleted file mode 100644
index 80b84580a57..00000000000
--- a/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.qhelp
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-The program uses input from the user, propagated via a global variable, as a format string for printf style functions.
-This can lead to buffer overflows or data representation problems. An attacker can exploit this weakness to crash the program,
-disclose information or even execute arbitrary code.
-
-This rule only identifies inputs from the user that are transferred through global variables before being used in printf style functions.
-Analyzing the flow of data through global variables is more prone to errors and so this rule may identify some examples of code where
-the input is not really from the user. For example, when a global variable is set in two places, one that comes from the user and one that does not.
-In this case we would mark all usages of the global variable as input from the user, but the input from the user may always came after the call to the
-printf style functions.
-
-The results of this rule should be considered alongside the related rule "Uncontrolled format string" which tracks the flow of the
-values input by a user, excluding global variables, until the values are used as the format argument for a printf like function call.
-
-
-
-Use constant expressions as the format strings. If you need to print a value from the user, use printf("%s", value_from_user).
-
-
-
-
-
-
-
-
-CERT C Coding
-Standard: FIO30-C. Exclude
-user input from format strings.
-
-
-
-
diff --git a/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.ql b/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.ql
deleted file mode 100644
index b37e34c296c..00000000000
--- a/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.ql
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * @name Uncontrolled format string (through global variable)
- * @description Using externally-controlled format strings in
- * printf-style functions can lead to buffer overflows
- * or data representation problems.
- * @kind path-problem
- * @problem.severity warning
- * @security-severity 9.3
- * @precision high
- * @id cpp/tainted-format-string-through-global
- * @tags reliability
- * security
- * external/cwe/cwe-134
- */
-
-import cpp
-import semmle.code.cpp.security.FunctionWithWrappers
-import semmle.code.cpp.security.Security
-import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
-import TaintedWithPath
-
-class Configuration extends TaintTrackingConfiguration {
- override predicate isSink(Element tainted) {
- exists(PrintfLikeFunction printf | printf.outermostWrapperFunctionCall(tainted, _))
- }
-
- override predicate taintThroughGlobals() { any() }
-}
-
-from
- PrintfLikeFunction printf, Expr arg, PathNode sourceNode, PathNode sinkNode,
- string printfFunction, Expr userValue, string cause
-where
- printf.outermostWrapperFunctionCall(arg, printfFunction) and
- not taintedWithoutGlobals(arg) and
- taintedWithPath(userValue, arg, sourceNode, sinkNode) and
- isUserInput(userValue, cause)
-select arg, sourceNode, sinkNode,
- "The value of this argument may come from $@ and is being used as a formatting argument to " +
- printfFunction + ".", userValue, cause
diff --git a/cpp/ql/src/change-notes/2023-11-16-tainted-format-string-through-global-deleted.md b/cpp/ql/src/change-notes/2023-11-16-tainted-format-string-through-global-deleted.md
new file mode 100644
index 00000000000..9e4d972f85e
--- /dev/null
+++ b/cpp/ql/src/change-notes/2023-11-16-tainted-format-string-through-global-deleted.md
@@ -0,0 +1,4 @@
+---
+category: breaking
+---
+* The `cpp/tainted-format-string-through-global` query has been deleted. This does not lead to a loss of alerts, as the query duplicated a subset of the alerts from `cpp/tainted-format-string`.
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected
deleted file mode 100644
index 6aca673fb4b..00000000000
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected
+++ /dev/null
@@ -1,69 +0,0 @@
-edges
-| globalVars.c:8:7:8:10 | copy | globalVars.c:27:9:27:12 | copy |
-| globalVars.c:8:7:8:10 | copy | globalVars.c:27:9:27:12 | copy |
-| globalVars.c:8:7:8:10 | copy | globalVars.c:30:15:30:18 | copy |
-| globalVars.c:8:7:8:10 | copy | globalVars.c:30:15:30:18 | copy |
-| globalVars.c:8:7:8:10 | copy | globalVars.c:30:15:30:18 | copy |
-| globalVars.c:8:7:8:10 | copy | globalVars.c:33:15:33:18 | copy |
-| globalVars.c:8:7:8:10 | copy | globalVars.c:35:11:35:14 | copy |
-| globalVars.c:9:7:9:11 | copy2 | globalVars.c:38:9:38:13 | copy2 |
-| globalVars.c:9:7:9:11 | copy2 | globalVars.c:38:9:38:13 | copy2 |
-| globalVars.c:9:7:9:11 | copy2 | globalVars.c:41:15:41:19 | copy2 |
-| globalVars.c:9:7:9:11 | copy2 | globalVars.c:41:15:41:19 | copy2 |
-| globalVars.c:9:7:9:11 | copy2 | globalVars.c:41:15:41:19 | copy2 |
-| globalVars.c:9:7:9:11 | copy2 | globalVars.c:44:15:44:19 | copy2 |
-| globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 |
-| globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 |
-| globalVars.c:11:22:11:25 | argv | globalVars.c:8:7:8:10 | copy |
-| globalVars.c:11:22:11:25 | argv | globalVars.c:12:2:12:15 | ... = ... |
-| globalVars.c:12:2:12:15 | ... = ... | globalVars.c:8:7:8:10 | copy |
-| globalVars.c:15:21:15:23 | val | globalVars.c:9:7:9:11 | copy2 |
-| globalVars.c:15:21:15:23 | val | globalVars.c:16:2:16:12 | ... = ... |
-| globalVars.c:16:2:16:12 | ... = ... | globalVars.c:9:7:9:11 | copy2 |
-| globalVars.c:24:11:24:14 | argv | globalVars.c:11:22:11:25 | argv |
-| globalVars.c:24:11:24:14 | argv | globalVars.c:11:22:11:25 | argv |
-| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy |
-| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy |
-| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy |
-| globalVars.c:30:15:30:18 | copy | globalVars.c:35:11:35:14 | copy |
-| globalVars.c:33:15:33:18 | copy | globalVars.c:35:11:35:14 | copy |
-| globalVars.c:35:11:35:14 | copy | globalVars.c:15:21:15:23 | val |
-| globalVars.c:35:11:35:14 | copy | globalVars.c:35:11:35:14 | copy |
-| globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 |
-| globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 |
-| globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 |
-| globalVars.c:41:15:41:19 | copy2 | globalVars.c:50:9:50:13 | copy2 |
-| globalVars.c:41:15:41:19 | copy2 | globalVars.c:50:9:50:13 | copy2 |
-| globalVars.c:44:15:44:19 | copy2 | globalVars.c:50:9:50:13 | copy2 |
-| globalVars.c:44:15:44:19 | copy2 | globalVars.c:50:9:50:13 | copy2 |
-subpaths
-nodes
-| globalVars.c:8:7:8:10 | copy | semmle.label | copy |
-| globalVars.c:9:7:9:11 | copy2 | semmle.label | copy2 |
-| globalVars.c:11:22:11:25 | argv | semmle.label | argv |
-| globalVars.c:12:2:12:15 | ... = ... | semmle.label | ... = ... |
-| globalVars.c:15:21:15:23 | val | semmle.label | val |
-| globalVars.c:16:2:16:12 | ... = ... | semmle.label | ... = ... |
-| globalVars.c:24:11:24:14 | argv | semmle.label | argv |
-| globalVars.c:24:11:24:14 | argv | semmle.label | argv |
-| globalVars.c:27:9:27:12 | copy | semmle.label | copy |
-| globalVars.c:27:9:27:12 | copy | semmle.label | copy |
-| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
-| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
-| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
-| globalVars.c:33:15:33:18 | copy | semmle.label | copy |
-| globalVars.c:35:11:35:14 | copy | semmle.label | copy |
-| globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 |
-| globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 |
-| globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 |
-| globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 |
-| globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 |
-| globalVars.c:44:15:44:19 | copy2 | semmle.label | copy2 |
-| globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 |
-| globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 |
-#select
-| globalVars.c:27:9:27:12 | copy | globalVars.c:24:11:24:14 | argv | globalVars.c:27:9:27:12 | copy | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | globalVars.c:24:11:24:14 | argv | argv |
-| globalVars.c:30:15:30:18 | copy | globalVars.c:24:11:24:14 | argv | globalVars.c:30:15:30:18 | copy | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(str), which calls printf(format). | globalVars.c:24:11:24:14 | argv | argv |
-| globalVars.c:38:9:38:13 | copy2 | globalVars.c:24:11:24:14 | argv | globalVars.c:38:9:38:13 | copy2 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | globalVars.c:24:11:24:14 | argv | argv |
-| globalVars.c:41:15:41:19 | copy2 | globalVars.c:24:11:24:14 | argv | globalVars.c:41:15:41:19 | copy2 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(str), which calls printf(format). | globalVars.c:24:11:24:14 | argv | argv |
-| globalVars.c:50:9:50:13 | copy2 | globalVars.c:24:11:24:14 | argv | globalVars.c:50:9:50:13 | copy2 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | globalVars.c:24:11:24:14 | argv | argv |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.qlref
deleted file mode 100644
index eac059de2bb..00000000000
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.qlref
+++ /dev/null
@@ -1 +0,0 @@
-Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.ql
\ No newline at end of file
From 2eb67549e63840f00cb2d13feda42b2e0cf469cc Mon Sep 17 00:00:00 2001
From: Jeroen Ketema
Date: Thu, 16 Nov 2023 10:56:47 +0100
Subject: [PATCH 09/22] C++: Tweak change note slightly
---
.../2023-11-16-tainted-format-string-through-global-deleted.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cpp/ql/src/change-notes/2023-11-16-tainted-format-string-through-global-deleted.md b/cpp/ql/src/change-notes/2023-11-16-tainted-format-string-through-global-deleted.md
index 9e4d972f85e..a4b3be355bc 100644
--- a/cpp/ql/src/change-notes/2023-11-16-tainted-format-string-through-global-deleted.md
+++ b/cpp/ql/src/change-notes/2023-11-16-tainted-format-string-through-global-deleted.md
@@ -1,4 +1,4 @@
---
category: breaking
---
-* The `cpp/tainted-format-string-through-global` query has been deleted. This does not lead to a loss of alerts, as the query duplicated a subset of the alerts from `cpp/tainted-format-string`.
+* The `cpp/tainted-format-string-through-global` query has been deleted. This does not lead to a loss of relevant alerts, as the query duplicated a subset of the alerts from `cpp/tainted-format-string`.
From 5c0fb2030d647ddda7e029a0acb8bf3eea56c03f Mon Sep 17 00:00:00 2001
From: Mathias Vorreiter Pedersen
Date: Thu, 16 Nov 2023 09:57:08 +0000
Subject: [PATCH 10/22] C++: Move change note.
---
cpp/ql/{src => lib}/change-notes/2023-10-31-odbc-models.md | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename cpp/ql/{src => lib}/change-notes/2023-10-31-odbc-models.md (100%)
diff --git a/cpp/ql/src/change-notes/2023-10-31-odbc-models.md b/cpp/ql/lib/change-notes/2023-10-31-odbc-models.md
similarity index 100%
rename from cpp/ql/src/change-notes/2023-10-31-odbc-models.md
rename to cpp/ql/lib/change-notes/2023-10-31-odbc-models.md
From 009d58034f9b9bcf370c8fb8074847cec58b866e Mon Sep 17 00:00:00 2001
From: Max Schaefer
Date: Thu, 16 Nov 2023 10:05:21 +0000
Subject: [PATCH 11/22] Address suggestions from review.
---
.../Security/CWE/CWE-022/TaintedPath.qhelp | 31 ++++++++++---------
.../Security/CWE/CWE-022/TaintedPathGood.java | 4 +--
.../CWE-022/semmle/tests/TaintedPath.java | 6 ++--
3 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp b/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp
index 46a7a6d60cf..569b8903b0f 100644
--- a/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp
+++ b/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp
@@ -8,22 +8,28 @@ can result in sensitive information being revealed or deleted, or an attacker be
behavior by modifying unexpected files.
Paths that are naively constructed from data controlled by a user may contain unexpected special characters,
-such as "..". Such a path may potentially point to any directory on the file system.
+such as "..". Such a path may potentially point anywhere on the file system.
Validate user input before using it to construct a file path.
-The choice of validation depends on the use case.
+The choice of validation depends on whether you want to allow the user to specify complex paths with
+multiple components that may span multiple folders, or only simple filenames without a path component.
-If you want to allow paths spanning multiple folders, a common strategy is to make sure that the constructed
-file path is contained within a safe root folder, for example by checking that the path starts with the root folder.
-Additionally, you need to ensure that the path does not contain any ".." components, since these would allow
-the path to escape the root folder.
+In the former case, a common strategy is to make sure that the constructed file path is contained within
+a safe root folder, for example by checking that the path starts with the root folder. Additionally,
+you need to ensure that the path does not contain any ".." components, since otherwise
+even a path that starts with the root folder could be used to access files outside the root folder.
-A safer (but more restrictive) option is to use an allow list of safe paths and make sure that
-the user input is one of those paths.
+In the latter case, if you want to ensure that the user input is interpreted as a simple filename without
+a path component, you can remove all path separators ("/" or "\") and all ".." sequences from the input
+before using it to construct a file path. Note that it is not sufficient to only remove "../" sequences:
+for example, applying this filter to ".../...//" would still result in the string "../".
+
+Finally, the simplest (but most restrictive) option is to use an allow list of safe patterns and make sure that
+the user input matches one of these patterns.
@@ -34,12 +40,9 @@ such as "/etc/passwd".
-Simply checking that the path is under a trusted location (such as the user's home directory) is not enough,
-however, since the path could contain relative components such as "..". For example, the string
-"/home/[user]/../../etc/passwd" starts with the user's home directory, but would still result in the code reading
-the file located at "/etc/passwd".
-
-To fix this, we check that the user-provided path does not contain ".." and starts with the user's home directory.
+Simply checking that the path is under a trusted location (such as a known public folder) is not enough,
+however, since the path could contain relative components such as "..". To fix this, we check that the it does
+not contain ".." and starts with the public folder.
diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPathGood.java b/java/ql/src/Security/CWE/CWE-022/TaintedPathGood.java
index dbd851846ce..37e8be7486c 100644
--- a/java/ql/src/Security/CWE/CWE-022/TaintedPathGood.java
+++ b/java/ql/src/Security/CWE/CWE-022/TaintedPathGood.java
@@ -3,8 +3,8 @@ public void sendUserFileGood(Socket sock, String user) {
new InputStreamReader(sock.getInputStream(), "UTF-8"));
String filename = filenameReader.readLine();
// GOOD: ensure that the file is in a designated folder in the user's home directory
- if (!filePath.contains("..") && filePath.startsWith("/home/" + user + "/public/")) {
- BufferedReader fileReader = new BufferedReader(new FileReader(filePath));
+ if (!filename.contains("..") && filename.startsWith("/home/" + user + "/public/")) {
+ BufferedReader fileReader = new BufferedReader(new FileReader(filename));
String fileLine = fileReader.readLine();
while(fileLine != null) {
sock.getOutputStream().write(fileLine.getBytes());
diff --git a/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java
index 2c97312cb76..5a5a63ad6ad 100644
--- a/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java
+++ b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java
@@ -21,10 +21,10 @@ public class TaintedPath {
public void sendUserFileGood(Socket sock, String user) throws IOException {
BufferedReader filenameReader = new BufferedReader(new InputStreamReader(sock.getInputStream(), "UTF-8"));
- String filePath = filenameReader.readLine();
+ String filename = filenameReader.readLine();
// GOOD: ensure that the file is in a designated folder in the user's home directory
- if (!filePath.contains("..") && filePath.startsWith("/home/" + user + "/public/")) {
- BufferedReader fileReader = new BufferedReader(new FileReader(filePath));
+ if (!filename.contains("..") && filename.startsWith("/home/" + user + "/public/")) {
+ BufferedReader fileReader = new BufferedReader(new FileReader(filename));
String fileLine = fileReader.readLine();
while(fileLine != null) {
sock.getOutputStream().write(fileLine.getBytes());
From 947b094387278c3cf0e4f2162a84df3def2bf688 Mon Sep 17 00:00:00 2001
From: Max Schaefer
Date: Thu, 16 Nov 2023 10:06:19 +0000
Subject: [PATCH 12/22] Add additional example.
---
java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp | 5 +++++
.../src/Security/CWE/CWE-022/TaintedPathGood2.java | 13 +++++++++++++
.../security/CWE-022/semmle/tests/TaintedPath.java | 13 +++++++++++++
3 files changed, 31 insertions(+)
create mode 100644 java/ql/src/Security/CWE/CWE-022/TaintedPathGood2.java
diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp b/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp
index 569b8903b0f..f2471048520 100644
--- a/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp
+++ b/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp
@@ -46,6 +46,11 @@ not contain ".." and starts with the public folder.
+Alternatively, if we only want to allow simple filenames without a path component, we can remove all path
+separators ("/" or "\") and all ".." sequences from the input before using it to construct a file path.
+
+
+
diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPathGood2.java b/java/ql/src/Security/CWE/CWE-022/TaintedPathGood2.java
new file mode 100644
index 00000000000..6f5a19d5fd8
--- /dev/null
+++ b/java/ql/src/Security/CWE/CWE-022/TaintedPathGood2.java
@@ -0,0 +1,13 @@
+public void sendUserFileGood(Socket sock, String user) {
+ BufferedReader filenameReader = new BufferedReader(
+ new InputStreamReader(sock.getInputStream(), "UTF-8"));
+ String filename = filenameReader.readLine();
+ // GOOD: remove all ".." sequences and path separators from the filename
+ filename = filename.replaceAll("\\.\\.|[/\\\\]", "");
+ BufferedReader fileReader = new BufferedReader(new FileReader(filename));
+ String fileLine = fileReader.readLine();
+ while(fileLine != null) {
+ sock.getOutputStream().write(fileLine.getBytes());
+ fileLine = fileReader.readLine();
+ }
+}
diff --git a/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java
index 5a5a63ad6ad..6f20e66c34e 100644
--- a/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java
+++ b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java
@@ -32,4 +32,17 @@ public class TaintedPath {
}
}
}
+
+ public void sendUserFileGood2(Socket sock, String user) throws IOException {
+ BufferedReader filenameReader = new BufferedReader(new InputStreamReader(sock.getInputStream(), "UTF-8"));
+ String filename = filenameReader.readLine();
+ // GOOD: remove all ".." sequences and path separators from the filename
+ filename = filename.replaceAll("\\.\\.|[/\\\\]", "");
+ BufferedReader fileReader = new BufferedReader(new FileReader(filename));
+ String fileLine = fileReader.readLine();
+ while(fileLine != null) {
+ sock.getOutputStream().write(fileLine.getBytes());
+ fileLine = fileReader.readLine();
+ }
+ }
}
From 30925da7d903ceb6bf51a187006ae8fb4c203d9b Mon Sep 17 00:00:00 2001
From: Stephan Brandauer
Date: Wed, 15 Nov 2023 13:38:01 +0100
Subject: [PATCH 13/22] Java Automodel: tests that demonstrate that there is no
sink candidate of an object being constructed in app mode
---
...utomodelApplicationModeCharacteristics.qll | 4 +++-
...lApplicationModeExtractCandidates.expected | 22 +++++++++----------
...cationModeExtractNegativeExamples.expected | 8 +++----
...cationModeExtractPositiveExamples.expected | 8 +++----
.../Test.java | 12 ++++++++++
5 files changed, 34 insertions(+), 20 deletions(-)
diff --git a/java/ql/automodel/src/AutomodelApplicationModeCharacteristics.qll b/java/ql/automodel/src/AutomodelApplicationModeCharacteristics.qll
index f8f2c8aaf58..c9a7e32147d 100644
--- a/java/ql/automodel/src/AutomodelApplicationModeCharacteristics.qll
+++ b/java/ql/automodel/src/AutomodelApplicationModeCharacteristics.qll
@@ -30,7 +30,9 @@ newtype TApplicationModeEndpoint =
arg.asExpr() = argExpr and call = argExpr.getCall() and not argExpr.isVararg()
)
} or
- TInstanceArgument(Call call, DataFlow::Node arg) { arg = DataFlow::getInstanceArgument(call) } or
+ TInstanceArgument(Call call, DataFlow::Node arg) {
+ arg = DataFlow::getInstanceArgument(call)
+ } or
TImplicitVarargsArray(Call call, DataFlow::Node arg, int idx) {
exists(Argument argExpr |
arg.asExpr() = argExpr and
diff --git a/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractCandidates.expected b/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractCandidates.expected
index b3de04f0551..5e98f212879 100644
--- a/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractCandidates.expected
+++ b/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractCandidates.expected
@@ -1,13 +1,13 @@
| PluginImpl.java:5:27:5:37 | name | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | PluginImpl.java:5:27:5:37 | name | CallContext | hudson/Plugin.java:5:5:5:31 | /** Configure method doc */ | MethodDoc | hudson/Plugin.java:3:1:3:17 | /** Plugin doc */ | ClassDoc | file://hudson:1:1:1:1 | hudson | package | file://Plugin:1:1:1:1 | Plugin | type | file://true:1:1:1:1 | true | subtypes | file://configure:1:1:1:1 | configure | name | file://(String,String):1:1:1:1 | (String,String) | signature | file://:1:1:1:1 | | input | file://Parameter[0]:1:1:1:1 | Parameter[0] | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
| PluginImpl.java:5:40:5:51 | value | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | PluginImpl.java:5:40:5:51 | value | CallContext | hudson/Plugin.java:5:5:5:31 | /** Configure method doc */ | MethodDoc | hudson/Plugin.java:3:1:3:17 | /** Plugin doc */ | ClassDoc | file://hudson:1:1:1:1 | hudson | package | file://Plugin:1:1:1:1 | Plugin | type | file://true:1:1:1:1 | true | subtypes | file://configure:1:1:1:1 | configure | name | file://(String,String):1:1:1:1 | (String,String) | signature | file://:1:1:1:1 | | input | file://Parameter[1]:1:1:1:1 | Parameter[1] | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
-| Test.java:18:3:18:11 | reference | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:18:3:18:24 | set(...) | CallContext | Test.java:18:3:18:11 | reference | MethodDoc | Test.java:18:3:18:11 | reference | ClassDoc | file://java.util.concurrent.atomic:1:1:1:1 | java.util.concurrent.atomic | package | file://AtomicReference:1:1:1:1 | AtomicReference | type | file://false:1:1:1:1 | false | subtypes | file://set:1:1:1:1 | set | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
-| Test.java:23:3:23:10 | supplier | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:23:3:23:16 | get(...) | CallContext | Test.java:23:3:23:10 | supplier | MethodDoc | Test.java:23:3:23:10 | supplier | ClassDoc | file://java.util.function:1:1:1:1 | java.util.function | package | file://Supplier:1:1:1:1 | Supplier | type | file://true:1:1:1:1 | true | subtypes | file://get:1:1:1:1 | get | name | file://():1:1:1:1 | () | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
-| Test.java:23:3:23:16 | get(...) | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:23:3:23:16 | get(...) | CallContext | Test.java:23:3:23:16 | get(...) | MethodDoc | Test.java:23:3:23:16 | get(...) | ClassDoc | file://java.util.function:1:1:1:1 | java.util.function | package | file://Supplier:1:1:1:1 | Supplier | type | file://true:1:1:1:1 | true | subtypes | file://get:1:1:1:1 | get | name | file://():1:1:1:1 | () | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
-| Test.java:27:3:31:3 | copy(...) | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:27:3:31:3 | copy(...) | CallContext | Test.java:27:3:31:3 | copy(...) | MethodDoc | Test.java:27:3:31:3 | copy(...) | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://copy:1:1:1:1 | copy | name | file://(Path,Path,CopyOption[]):1:1:1:1 | (Path,Path,CopyOption[]) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
-| Test.java:35:10:37:3 | newInputStream(...) | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:35:10:37:3 | newInputStream(...) | CallContext | Test.java:35:10:37:3 | newInputStream(...) | MethodDoc | Test.java:35:10:37:3 | newInputStream(...) | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://newInputStream:1:1:1:1 | newInputStream | name | file://(Path,OpenOption[]):1:1:1:1 | (Path,OpenOption[]) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
-| Test.java:36:4:36:11 | openPath | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:35:10:37:3 | newInputStream(...) | CallContext | Test.java:36:4:36:11 | openPath | MethodDoc | Test.java:36:4:36:11 | openPath | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://newInputStream:1:1:1:1 | newInputStream | name | file://(Path,OpenOption[]):1:1:1:1 | (Path,OpenOption[]) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://ai-manual:1:1:1:1 | ai-manual | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
-| Test.java:42:4:42:22 | get(...) | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:42:4:42:22 | get(...) | CallContext | Test.java:42:4:42:22 | get(...) | MethodDoc | Test.java:42:4:42:22 | get(...) | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Paths:1:1:1:1 | Paths | type | file://false:1:1:1:1 | false | subtypes | file://get:1:1:1:1 | get | name | file://(String,String[]):1:1:1:1 | (String,String[]) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
-| Test.java:53:3:58:3 | walk(...) | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:53:3:58:3 | walk(...) | CallContext | Test.java:53:3:58:3 | walk(...) | MethodDoc | Test.java:53:3:58:3 | walk(...) | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://walk:1:1:1:1 | walk | name | file://(Path,FileVisitOption[]):1:1:1:1 | (Path,FileVisitOption[]) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
-| Test.java:55:4:55:4 | o | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:53:3:58:3 | walk(...) | CallContext | Test.java:53:3:58:3 | walk(...) | MethodDoc | Test.java:53:3:58:3 | walk(...) | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://walk:1:1:1:1 | walk | name | file://(Path,FileVisitOption[]):1:1:1:1 | (Path,FileVisitOption[]) | signature | file://Argument[1]:1:1:1:1 | Argument[1] | input | file://:1:1:1:1 | | output | file://true:1:1:1:1 | true | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
-| Test.java:62:3:62:3 | c | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:62:3:62:20 | getInputStream(...) | CallContext | Test.java:62:3:62:3 | c | MethodDoc | Test.java:62:3:62:3 | c | ClassDoc | file://java.net:1:1:1:1 | java.net | package | file://URLConnection:1:1:1:1 | URLConnection | type | file://true:1:1:1:1 | true | subtypes | file://getInputStream:1:1:1:1 | getInputStream | name | file://():1:1:1:1 | () | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
-| Test.java:67:30:67:47 | writer | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:67:30:67:47 | writer | CallContext | Test.java:67:30:67:47 | writer | MethodDoc | Test.java:67:30:67:47 | writer | ClassDoc | file://java.lang:1:1:1:1 | java.lang | package | file://Throwable:1:1:1:1 | Throwable | type | file://true:1:1:1:1 | true | subtypes | file://printStackTrace:1:1:1:1 | printStackTrace | name | file://(PrintWriter):1:1:1:1 | (PrintWriter) | signature | file://:1:1:1:1 | | input | file://Parameter[0]:1:1:1:1 | Parameter[0] | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
+| Test.java:19:3:19:11 | reference | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:19:3:19:24 | set(...) | CallContext | Test.java:19:3:19:11 | reference | MethodDoc | Test.java:19:3:19:11 | reference | ClassDoc | file://java.util.concurrent.atomic:1:1:1:1 | java.util.concurrent.atomic | package | file://AtomicReference:1:1:1:1 | AtomicReference | type | file://false:1:1:1:1 | false | subtypes | file://set:1:1:1:1 | set | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
+| Test.java:24:3:24:10 | supplier | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:24:3:24:16 | get(...) | CallContext | Test.java:24:3:24:10 | supplier | MethodDoc | Test.java:24:3:24:10 | supplier | ClassDoc | file://java.util.function:1:1:1:1 | java.util.function | package | file://Supplier:1:1:1:1 | Supplier | type | file://true:1:1:1:1 | true | subtypes | file://get:1:1:1:1 | get | name | file://():1:1:1:1 | () | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
+| Test.java:24:3:24:16 | get(...) | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:24:3:24:16 | get(...) | CallContext | Test.java:24:3:24:16 | get(...) | MethodDoc | Test.java:24:3:24:16 | get(...) | ClassDoc | file://java.util.function:1:1:1:1 | java.util.function | package | file://Supplier:1:1:1:1 | Supplier | type | file://true:1:1:1:1 | true | subtypes | file://get:1:1:1:1 | get | name | file://():1:1:1:1 | () | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
+| Test.java:28:3:32:3 | copy(...) | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:28:3:32:3 | copy(...) | CallContext | Test.java:28:3:32:3 | copy(...) | MethodDoc | Test.java:28:3:32:3 | copy(...) | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://copy:1:1:1:1 | copy | name | file://(Path,Path,CopyOption[]):1:1:1:1 | (Path,Path,CopyOption[]) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
+| Test.java:36:10:38:3 | newInputStream(...) | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:36:10:38:3 | newInputStream(...) | CallContext | Test.java:36:10:38:3 | newInputStream(...) | MethodDoc | Test.java:36:10:38:3 | newInputStream(...) | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://newInputStream:1:1:1:1 | newInputStream | name | file://(Path,OpenOption[]):1:1:1:1 | (Path,OpenOption[]) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
+| Test.java:37:4:37:11 | openPath | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:36:10:38:3 | newInputStream(...) | CallContext | Test.java:37:4:37:11 | openPath | MethodDoc | Test.java:37:4:37:11 | openPath | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://newInputStream:1:1:1:1 | newInputStream | name | file://(Path,OpenOption[]):1:1:1:1 | (Path,OpenOption[]) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://ai-manual:1:1:1:1 | ai-manual | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
+| Test.java:43:4:43:22 | get(...) | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:43:4:43:22 | get(...) | CallContext | Test.java:43:4:43:22 | get(...) | MethodDoc | Test.java:43:4:43:22 | get(...) | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Paths:1:1:1:1 | Paths | type | file://false:1:1:1:1 | false | subtypes | file://get:1:1:1:1 | get | name | file://(String,String[]):1:1:1:1 | (String,String[]) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
+| Test.java:54:3:59:3 | walk(...) | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:54:3:59:3 | walk(...) | CallContext | Test.java:54:3:59:3 | walk(...) | MethodDoc | Test.java:54:3:59:3 | walk(...) | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://walk:1:1:1:1 | walk | name | file://(Path,FileVisitOption[]):1:1:1:1 | (Path,FileVisitOption[]) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
+| Test.java:56:4:56:4 | o | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:54:3:59:3 | walk(...) | CallContext | Test.java:54:3:59:3 | walk(...) | MethodDoc | Test.java:54:3:59:3 | walk(...) | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://walk:1:1:1:1 | walk | name | file://(Path,FileVisitOption[]):1:1:1:1 | (Path,FileVisitOption[]) | signature | file://Argument[1]:1:1:1:1 | Argument[1] | input | file://:1:1:1:1 | | output | file://true:1:1:1:1 | true | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
+| Test.java:63:3:63:3 | c | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:63:3:63:20 | getInputStream(...) | CallContext | Test.java:63:3:63:3 | c | MethodDoc | Test.java:63:3:63:3 | c | ClassDoc | file://java.net:1:1:1:1 | java.net | package | file://URLConnection:1:1:1:1 | URLConnection | type | file://true:1:1:1:1 | true | subtypes | file://getInputStream:1:1:1:1 | getInputStream | name | file://():1:1:1:1 | () | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
+| Test.java:68:30:68:47 | writer | Related locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:68:30:68:47 | writer | CallContext | Test.java:68:30:68:47 | writer | MethodDoc | Test.java:68:30:68:47 | writer | ClassDoc | file://java.lang:1:1:1:1 | java.lang | package | file://Throwable:1:1:1:1 | Throwable | type | file://true:1:1:1:1 | true | subtypes | file://printStackTrace:1:1:1:1 | printStackTrace | name | file://(PrintWriter):1:1:1:1 | (PrintWriter) | signature | file://:1:1:1:1 | | input | file://Parameter[0]:1:1:1:1 | Parameter[0] | output | file://false:1:1:1:1 | false | isVarargsArray | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
diff --git a/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.expected b/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.expected
index 092551af317..28019a8a844 100644
--- a/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.expected
+++ b/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.expected
@@ -1,4 +1,4 @@
-| Test.java:47:10:49:3 | compareTo(...) | known sanitizer\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:47:10:49:3 | compareTo(...) | CallContext | Test.java:47:10:49:3 | compareTo(...) | MethodDoc | Test.java:47:10:49:3 | compareTo(...) | ClassDoc | file://java.io:1:1:1:1 | java.io | package | file://File:1:1:1:1 | File | type | file://true:1:1:1:1 | true | subtypes | file://compareTo:1:1:1:1 | compareTo | name | file://(File):1:1:1:1 | (File) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
-| Test.java:48:4:48:5 | f2 | known non-sink\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:47:10:49:3 | compareTo(...) | CallContext | Test.java:48:4:48:5 | f2 | MethodDoc | Test.java:48:4:48:5 | f2 | ClassDoc | file://java.io:1:1:1:1 | java.io | package | file://File:1:1:1:1 | File | type | file://true:1:1:1:1 | true | subtypes | file://compareTo:1:1:1:1 | compareTo | name | file://(File):1:1:1:1 | (File) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
-| Test.java:54:4:54:4 | p | taint step\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:53:3:58:3 | walk(...) | CallContext | Test.java:54:4:54:4 | p | MethodDoc | Test.java:54:4:54:4 | p | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://walk:1:1:1:1 | walk | name | file://(Path,FileVisitOption[]):1:1:1:1 | (Path,FileVisitOption[]) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
-| Test.java:66:7:66:18 | this | exception\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:66:7:66:18 | super(...) | CallContext | Test.java:66:7:66:18 | super(...) | MethodDoc | Test.java:66:7:66:18 | super(...) | ClassDoc | file://java.lang:1:1:1:1 | java.lang | package | file://Exception:1:1:1:1 | Exception | type | file://true:1:1:1:1 | true | subtypes | file://Exception:1:1:1:1 | Exception | name | file://():1:1:1:1 | () | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
+| Test.java:48:10:50:3 | compareTo(...) | known sanitizer\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:48:10:50:3 | compareTo(...) | CallContext | Test.java:48:10:50:3 | compareTo(...) | MethodDoc | Test.java:48:10:50:3 | compareTo(...) | ClassDoc | file://java.io:1:1:1:1 | java.io | package | file://File:1:1:1:1 | File | type | file://true:1:1:1:1 | true | subtypes | file://compareTo:1:1:1:1 | compareTo | name | file://(File):1:1:1:1 | (File) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
+| Test.java:49:4:49:5 | f2 | known non-sink\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:48:10:50:3 | compareTo(...) | CallContext | Test.java:49:4:49:5 | f2 | MethodDoc | Test.java:49:4:49:5 | f2 | ClassDoc | file://java.io:1:1:1:1 | java.io | package | file://File:1:1:1:1 | File | type | file://true:1:1:1:1 | true | subtypes | file://compareTo:1:1:1:1 | compareTo | name | file://(File):1:1:1:1 | (File) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
+| Test.java:55:4:55:4 | p | taint step\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:54:3:59:3 | walk(...) | CallContext | Test.java:55:4:55:4 | p | MethodDoc | Test.java:55:4:55:4 | p | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://walk:1:1:1:1 | walk | name | file://(Path,FileVisitOption[]):1:1:1:1 | (Path,FileVisitOption[]) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
+| Test.java:67:7:67:18 | this | exception\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:67:7:67:18 | super(...) | CallContext | Test.java:67:7:67:18 | super(...) | MethodDoc | Test.java:67:7:67:18 | super(...) | ClassDoc | file://java.lang:1:1:1:1 | java.lang | package | file://Exception:1:1:1:1 | Exception | type | file://true:1:1:1:1 | true | subtypes | file://Exception:1:1:1:1 | Exception | name | file://():1:1:1:1 | () | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
diff --git a/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractPositiveExamples.expected b/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractPositiveExamples.expected
index 3419e5c0c8d..60db0852024 100644
--- a/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractPositiveExamples.expected
+++ b/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractPositiveExamples.expected
@@ -1,4 +1,4 @@
-| Test.java:28:4:28:9 | source | path-injection\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:27:3:31:3 | copy(...) | CallContext | Test.java:28:4:28:9 | source | MethodDoc | Test.java:28:4:28:9 | source | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://copy:1:1:1:1 | copy | name | file://(Path,Path,CopyOption[]):1:1:1:1 | (Path,Path,CopyOption[]) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
-| Test.java:29:4:29:9 | target | path-injection\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:27:3:31:3 | copy(...) | CallContext | Test.java:29:4:29:9 | target | MethodDoc | Test.java:29:4:29:9 | target | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://copy:1:1:1:1 | copy | name | file://(Path,Path,CopyOption[]):1:1:1:1 | (Path,Path,CopyOption[]) | signature | file://Argument[1]:1:1:1:1 | Argument[1] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
-| Test.java:36:4:36:11 | openPath | path-injection\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:35:10:37:3 | newInputStream(...) | CallContext | Test.java:36:4:36:11 | openPath | MethodDoc | Test.java:36:4:36:11 | openPath | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://newInputStream:1:1:1:1 | newInputStream | name | file://(Path,OpenOption[]):1:1:1:1 | (Path,OpenOption[]) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
-| Test.java:62:3:62:20 | getInputStream(...) | remote\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:62:3:62:20 | getInputStream(...) | CallContext | Test.java:62:3:62:20 | getInputStream(...) | MethodDoc | Test.java:62:3:62:20 | getInputStream(...) | ClassDoc | file://java.net:1:1:1:1 | java.net | package | file://URLConnection:1:1:1:1 | URLConnection | type | file://true:1:1:1:1 | true | subtypes | file://getInputStream:1:1:1:1 | getInputStream | name | file://():1:1:1:1 | () | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
+| Test.java:29:4:29:9 | source | path-injection\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:28:3:32:3 | copy(...) | CallContext | Test.java:29:4:29:9 | source | MethodDoc | Test.java:29:4:29:9 | source | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://copy:1:1:1:1 | copy | name | file://(Path,Path,CopyOption[]):1:1:1:1 | (Path,Path,CopyOption[]) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
+| Test.java:30:4:30:9 | target | path-injection\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:28:3:32:3 | copy(...) | CallContext | Test.java:30:4:30:9 | target | MethodDoc | Test.java:30:4:30:9 | target | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://copy:1:1:1:1 | copy | name | file://(Path,Path,CopyOption[]):1:1:1:1 | (Path,Path,CopyOption[]) | signature | file://Argument[1]:1:1:1:1 | Argument[1] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
+| Test.java:37:4:37:11 | openPath | path-injection\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:36:10:38:3 | newInputStream(...) | CallContext | Test.java:37:4:37:11 | openPath | MethodDoc | Test.java:37:4:37:11 | openPath | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://newInputStream:1:1:1:1 | newInputStream | name | file://(Path,OpenOption[]):1:1:1:1 | (Path,OpenOption[]) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
+| Test.java:63:3:63:20 | getInputStream(...) | remote\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:63:3:63:20 | getInputStream(...) | CallContext | Test.java:63:3:63:20 | getInputStream(...) | MethodDoc | Test.java:63:3:63:20 | getInputStream(...) | ClassDoc | file://java.net:1:1:1:1 | java.net | package | file://URLConnection:1:1:1:1 | URLConnection | type | file://true:1:1:1:1 | true | subtypes | file://getInputStream:1:1:1:1 | getInputStream | name | file://():1:1:1:1 | () | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
diff --git a/java/ql/automodel/test/AutomodelApplicationModeExtraction/Test.java b/java/ql/automodel/test/AutomodelApplicationModeExtraction/Test.java
index 0bfb83ad520..3851a689969 100644
--- a/java/ql/automodel/test/AutomodelApplicationModeExtraction/Test.java
+++ b/java/ql/automodel/test/AutomodelApplicationModeExtraction/Test.java
@@ -11,6 +11,7 @@ import java.util.function.Supplier;
import java.io.File;
import java.nio.file.FileVisitOption;
import java.net.URLConnection;
+import java.util.concurrent.FutureTask;
class Test {
public static void main(String[] args) throws Exception {
@@ -67,4 +68,15 @@ class OverrideTest extends Exception {
public void printStackTrace(PrintWriter writer) { // writer is a source candidate because it overrides an existing method
return;
}
+
+}
+
+class TaskUtils {
+ public FutureTask getTask() {
+ FutureTask ft = new FutureTask(() -> {
+ // ^-- no sink candidate for the `this` qualifier of a constructor
+ return 42;
+ });
+ return ft;
+ }
}
From d7c97d9d92fc5682f7b26f0bcb6dafd3793cffc3 Mon Sep 17 00:00:00 2001
From: Stephan Brandauer
Date: Thu, 16 Nov 2023 12:26:08 +0100
Subject: [PATCH 14/22] Java Automodel: remove constructor instance arguments
from endpoints and update test expectations
---
.../automodel/src/AutomodelApplicationModeCharacteristics.qll | 2 +-
.../AutomodelApplicationModeExtractNegativeExamples.expected | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/java/ql/automodel/src/AutomodelApplicationModeCharacteristics.qll b/java/ql/automodel/src/AutomodelApplicationModeCharacteristics.qll
index c9a7e32147d..e5dd4d01c8c 100644
--- a/java/ql/automodel/src/AutomodelApplicationModeCharacteristics.qll
+++ b/java/ql/automodel/src/AutomodelApplicationModeCharacteristics.qll
@@ -31,7 +31,7 @@ newtype TApplicationModeEndpoint =
)
} or
TInstanceArgument(Call call, DataFlow::Node arg) {
- arg = DataFlow::getInstanceArgument(call)
+ arg = DataFlow::getInstanceArgument(call) and not call instanceof ConstructorCall
} or
TImplicitVarargsArray(Call call, DataFlow::Node arg, int idx) {
exists(Argument argExpr |
diff --git a/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.expected b/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.expected
index 28019a8a844..91f33b6fb05 100644
--- a/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.expected
+++ b/java/ql/automodel/test/AutomodelApplicationModeExtraction/AutomodelApplicationModeExtractNegativeExamples.expected
@@ -1,4 +1,3 @@
| Test.java:48:10:50:3 | compareTo(...) | known sanitizer\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:48:10:50:3 | compareTo(...) | CallContext | Test.java:48:10:50:3 | compareTo(...) | MethodDoc | Test.java:48:10:50:3 | compareTo(...) | ClassDoc | file://java.io:1:1:1:1 | java.io | package | file://File:1:1:1:1 | File | type | file://true:1:1:1:1 | true | subtypes | file://compareTo:1:1:1:1 | compareTo | name | file://(File):1:1:1:1 | (File) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://false:1:1:1:1 | false | isVarargsArray | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
| Test.java:49:4:49:5 | f2 | known non-sink\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:48:10:50:3 | compareTo(...) | CallContext | Test.java:49:4:49:5 | f2 | MethodDoc | Test.java:49:4:49:5 | f2 | ClassDoc | file://java.io:1:1:1:1 | java.io | package | file://File:1:1:1:1 | File | type | file://true:1:1:1:1 | true | subtypes | file://compareTo:1:1:1:1 | compareTo | name | file://(File):1:1:1:1 | (File) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
| Test.java:55:4:55:4 | p | taint step\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:54:3:59:3 | walk(...) | CallContext | Test.java:55:4:55:4 | p | MethodDoc | Test.java:55:4:55:4 | p | ClassDoc | file://java.nio.file:1:1:1:1 | java.nio.file | package | file://Files:1:1:1:1 | Files | type | file://false:1:1:1:1 | false | subtypes | file://walk:1:1:1:1 | walk | name | file://(Path,FileVisitOption[]):1:1:1:1 | (Path,FileVisitOption[]) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
-| Test.java:67:7:67:18 | this | exception\nrelated locations: $@, $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@. | Test.java:67:7:67:18 | super(...) | CallContext | Test.java:67:7:67:18 | super(...) | MethodDoc | Test.java:67:7:67:18 | super(...) | ClassDoc | file://java.lang:1:1:1:1 | java.lang | package | file://Exception:1:1:1:1 | Exception | type | file://true:1:1:1:1 | true | subtypes | file://Exception:1:1:1:1 | Exception | name | file://():1:1:1:1 | () | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://:1:1:1:1 | | output | file://false:1:1:1:1 | false | isVarargsArray | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
From de83929a6047dc9f61c32991905e59ae0733ee31 Mon Sep 17 00:00:00 2001
From: Henry Mercer
Date: Thu, 16 Nov 2023 11:36:44 +0000
Subject: [PATCH 15/22] Remove LoC metrics from the analysis summary
---
cpp/ql/src/Summary/LinesOfCode.ql | 1 +
javascript/ql/src/Summary/LinesOfCode.ql | 1 +
python/ql/src/Summary/LinesOfCode.ql | 1 +
3 files changed, 3 insertions(+)
diff --git a/cpp/ql/src/Summary/LinesOfCode.ql b/cpp/ql/src/Summary/LinesOfCode.ql
index 3b2aa2ac4c9..9e2cab4851b 100644
--- a/cpp/ql/src/Summary/LinesOfCode.ql
+++ b/cpp/ql/src/Summary/LinesOfCode.ql
@@ -4,6 +4,7 @@
* @description The total number of lines of C/C++ code across all files, including system headers, libraries, and auto-generated files. This is a useful metric of the size of a database. For all files that were seen during the build, this query counts the lines of code, excluding whitespace or comments.
* @kind metric
* @tags summary
+ * telemetry
*/
import cpp
diff --git a/javascript/ql/src/Summary/LinesOfCode.ql b/javascript/ql/src/Summary/LinesOfCode.ql
index 9f89e0e2163..83bb06a644e 100644
--- a/javascript/ql/src/Summary/LinesOfCode.ql
+++ b/javascript/ql/src/Summary/LinesOfCode.ql
@@ -4,6 +4,7 @@
* @description The total number of lines of JavaScript or TypeScript code across all files checked into the repository, except in `node_modules`. This is a useful metric of the size of a database. For all files that were seen during extraction, this query counts the lines of code, excluding whitespace or comments.
* @kind metric
* @tags summary
+ * telemetry
*/
import javascript
diff --git a/python/ql/src/Summary/LinesOfCode.ql b/python/ql/src/Summary/LinesOfCode.ql
index d9bfc4f872c..a07a896c4ca 100644
--- a/python/ql/src/Summary/LinesOfCode.ql
+++ b/python/ql/src/Summary/LinesOfCode.ql
@@ -5,6 +5,7 @@
* database. This query counts the lines of code, excluding whitespace or comments.
* @kind metric
* @tags summary
+ * telemetry
* @id py/summary/lines-of-code
*/
From 143e1680bd4e27c8b5fc9fddbeeee2c29fd4d278 Mon Sep 17 00:00:00 2001
From: Max Schaefer <54907921+max-schaefer@users.noreply.github.com>
Date: Thu, 16 Nov 2023 11:42:35 +0000
Subject: [PATCH 16/22] Apply suggestions from code review
Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com>
---
java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp b/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp
index f2471048520..b371a114059 100644
--- a/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp
+++ b/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp
@@ -41,12 +41,12 @@ such as "/etc/passwd".
Simply checking that the path is under a trusted location (such as a known public folder) is not enough,
-however, since the path could contain relative components such as "..". To fix this, we check that the it does
+however, since the path could contain relative components such as "..". To fix this, check that it does
not contain ".." and starts with the public folder.
-Alternatively, if we only want to allow simple filenames without a path component, we can remove all path
+
Alternatively, if you only want to allow simple filenames without a path component, you can remove all path
separators ("/" or "\") and all ".." sequences from the input before using it to construct a file path.
From 30926401157a8349d873cb980f0f2b9ccab9f070 Mon Sep 17 00:00:00 2001
From: Stephan Brandauer
Date: Thu, 16 Nov 2023 12:42:50 +0100
Subject: [PATCH 17/22] Java Automodel: make test case for Argument[this] sink
candidates in ctors in framework mode
---
.../AutomodelFrameworkModeExtractCandidates.expected | 3 +++
.../com/github/codeql/test/PublicClass.java | 4 ++++
2 files changed, 7 insertions(+)
diff --git a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected b/java/ql/automodel/test/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected
index 2bb9b2edb25..3914ce3dec9 100644
--- a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected
+++ b/java/ql/automodel/test/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected
@@ -10,6 +10,9 @@
| com/github/codeql/test/PublicClass.java:13:18:13:31 | nonPublicStuff | Related locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:13:18:13:31 | nonPublicStuff | MethodDoc | com/github/codeql/test/PublicClass.java:13:18:13:31 | nonPublicStuff | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://true:1:1:1:1 | true | subtypes | file://nonPublicStuff:1:1:1:1 | nonPublicStuff | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://:1:1:1:1 | | output | file://this:1:1:1:1 | this | parameterName | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
| com/github/codeql/test/PublicClass.java:13:33:13:42 | arg | Related locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:13:33:13:42 | arg | MethodDoc | com/github/codeql/test/PublicClass.java:13:33:13:42 | arg | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://true:1:1:1:1 | true | subtypes | file://nonPublicStuff:1:1:1:1 | nonPublicStuff | name | file://(String):1:1:1:1 | (String) | signature | file://:1:1:1:1 | | input | file://Parameter[0]:1:1:1:1 | Parameter[0] | output | file://arg:1:1:1:1 | arg | parameterName | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
| com/github/codeql/test/PublicClass.java:13:33:13:42 | arg | Related locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:13:33:13:42 | arg | MethodDoc | com/github/codeql/test/PublicClass.java:13:33:13:42 | arg | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://true:1:1:1:1 | true | subtypes | file://nonPublicStuff:1:1:1:1 | nonPublicStuff | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://arg:1:1:1:1 | arg | parameterName | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
+| com/github/codeql/test/PublicClass.java:22:10:22:20 | PublicClass | Related locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:22:10:22:20 | PublicClass | MethodDoc | com/github/codeql/test/PublicClass.java:22:10:22:20 | PublicClass | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://true:1:1:1:1 | true | subtypes | file://PublicClass:1:1:1:1 | PublicClass | name | file://(Object):1:1:1:1 | (Object) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://:1:1:1:1 | | parameterName | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
+| com/github/codeql/test/PublicClass.java:22:10:22:20 | PublicClass | Related locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:22:10:22:20 | PublicClass | MethodDoc | com/github/codeql/test/PublicClass.java:22:10:22:20 | PublicClass | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://true:1:1:1:1 | true | subtypes | file://PublicClass:1:1:1:1 | PublicClass | name | file://(Object):1:1:1:1 | (Object) | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://:1:1:1:1 | | output | file://this:1:1:1:1 | this | parameterName | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
+| com/github/codeql/test/PublicClass.java:22:22:22:33 | input | Related locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:22:22:22:33 | input | MethodDoc | com/github/codeql/test/PublicClass.java:22:22:22:33 | input | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://true:1:1:1:1 | true | subtypes | file://PublicClass:1:1:1:1 | PublicClass | name | file://(Object):1:1:1:1 | (Object) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://input:1:1:1:1 | input | parameterName | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
| com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | Related locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | MethodDoc | com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicInterface:1:1:1:1 | PublicInterface | type | file://true:1:1:1:1 | true | subtypes | file://stuff:1:1:1:1 | stuff | name | file://(String):1:1:1:1 | (String) | signature | file://:1:1:1:1 | | input | file://Parameter[this]:1:1:1:1 | Parameter[this] | output | file://this:1:1:1:1 | this | parameterName | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
| com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | Related locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | MethodDoc | com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicInterface:1:1:1:1 | PublicInterface | type | file://true:1:1:1:1 | true | subtypes | file://stuff:1:1:1:1 | stuff | name | file://(String):1:1:1:1 | (String) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://:1:1:1:1 | | parameterName | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
| com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | Related locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | MethodDoc | com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicInterface:1:1:1:1 | PublicInterface | type | file://true:1:1:1:1 | true | subtypes | file://stuff:1:1:1:1 | stuff | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://:1:1:1:1 | | output | file://this:1:1:1:1 | this | parameterName | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
diff --git a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java b/java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java
index 49613d6d361..cb009cc8afc 100644
--- a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java
+++ b/java/ql/automodel/test/AutomodelFrameworkModeExtraction/com/github/codeql/test/PublicClass.java
@@ -18,4 +18,8 @@ public class PublicClass {
void packagePrivateStuff(String arg) {
System.out.println(arg);
}
+
+ public PublicClass(Object input) {
+ // the `this` qualifier is not a candidate
+ }
}
From 84e58b77aa1f612de02d1098652011811485fdde Mon Sep 17 00:00:00 2001
From: Stephan Brandauer
Date: Thu, 16 Nov 2023 12:43:38 +0100
Subject: [PATCH 18/22] Java Automodel: remove Qualifiers of constructors from
endpoints
---
java/ql/automodel/src/AutomodelFrameworkModeCharacteristics.qll | 2 +-
.../AutomodelFrameworkModeExtractCandidates.expected | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/java/ql/automodel/src/AutomodelFrameworkModeCharacteristics.qll b/java/ql/automodel/src/AutomodelFrameworkModeCharacteristics.qll
index 222c9344339..038d0f27ff5 100644
--- a/java/ql/automodel/src/AutomodelFrameworkModeCharacteristics.qll
+++ b/java/ql/automodel/src/AutomodelFrameworkModeCharacteristics.qll
@@ -25,7 +25,7 @@ newtype JavaRelatedLocationType =
newtype TFrameworkModeEndpoint =
TExplicitParameter(Parameter p) or
- TQualifier(Callable c) or
+ TQualifier(Callable c) { not c instanceof Constructor } or
TReturnValue(Callable c) or
TOverridableParameter(Method m, Parameter p) {
p.getCallable() = m and
diff --git a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected b/java/ql/automodel/test/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected
index 3914ce3dec9..fc3debce039 100644
--- a/java/ql/automodel/test/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected
+++ b/java/ql/automodel/test/AutomodelFrameworkModeExtraction/AutomodelFrameworkModeExtractCandidates.expected
@@ -11,7 +11,6 @@
| com/github/codeql/test/PublicClass.java:13:33:13:42 | arg | Related locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:13:33:13:42 | arg | MethodDoc | com/github/codeql/test/PublicClass.java:13:33:13:42 | arg | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://true:1:1:1:1 | true | subtypes | file://nonPublicStuff:1:1:1:1 | nonPublicStuff | name | file://(String):1:1:1:1 | (String) | signature | file://:1:1:1:1 | | input | file://Parameter[0]:1:1:1:1 | Parameter[0] | output | file://arg:1:1:1:1 | arg | parameterName | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
| com/github/codeql/test/PublicClass.java:13:33:13:42 | arg | Related locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:13:33:13:42 | arg | MethodDoc | com/github/codeql/test/PublicClass.java:13:33:13:42 | arg | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://true:1:1:1:1 | true | subtypes | file://nonPublicStuff:1:1:1:1 | nonPublicStuff | name | file://(String):1:1:1:1 | (String) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://arg:1:1:1:1 | arg | parameterName | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
| com/github/codeql/test/PublicClass.java:22:10:22:20 | PublicClass | Related locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:22:10:22:20 | PublicClass | MethodDoc | com/github/codeql/test/PublicClass.java:22:10:22:20 | PublicClass | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://true:1:1:1:1 | true | subtypes | file://PublicClass:1:1:1:1 | PublicClass | name | file://(Object):1:1:1:1 | (Object) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://:1:1:1:1 | | parameterName | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
-| com/github/codeql/test/PublicClass.java:22:10:22:20 | PublicClass | Related locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:22:10:22:20 | PublicClass | MethodDoc | com/github/codeql/test/PublicClass.java:22:10:22:20 | PublicClass | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://true:1:1:1:1 | true | subtypes | file://PublicClass:1:1:1:1 | PublicClass | name | file://(Object):1:1:1:1 | (Object) | signature | file://Argument[this]:1:1:1:1 | Argument[this] | input | file://:1:1:1:1 | | output | file://this:1:1:1:1 | this | parameterName | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
| com/github/codeql/test/PublicClass.java:22:22:22:33 | input | Related locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicClass.java:22:22:22:33 | input | MethodDoc | com/github/codeql/test/PublicClass.java:22:22:22:33 | input | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicClass:1:1:1:1 | PublicClass | type | file://true:1:1:1:1 | true | subtypes | file://PublicClass:1:1:1:1 | PublicClass | name | file://(Object):1:1:1:1 | (Object) | signature | file://Argument[0]:1:1:1:1 | Argument[0] | input | file://:1:1:1:1 | | output | file://input:1:1:1:1 | input | parameterName | file://:1:1:1:1 | | alreadyAiModeled | file://sinkModel:1:1:1:1 | sinkModel | extensibleType |
| com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | Related locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | MethodDoc | com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicInterface:1:1:1:1 | PublicInterface | type | file://true:1:1:1:1 | true | subtypes | file://stuff:1:1:1:1 | stuff | name | file://(String):1:1:1:1 | (String) | signature | file://:1:1:1:1 | | input | file://Parameter[this]:1:1:1:1 | Parameter[this] | output | file://this:1:1:1:1 | this | parameterName | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
| com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | Related locations: $@, $@.\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@, $@. | com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | MethodDoc | com/github/codeql/test/PublicInterface.java:4:17:4:21 | stuff | ClassDoc | file://com.github.codeql.test:1:1:1:1 | com.github.codeql.test | package | file://PublicInterface:1:1:1:1 | PublicInterface | type | file://true:1:1:1:1 | true | subtypes | file://stuff:1:1:1:1 | stuff | name | file://(String):1:1:1:1 | (String) | signature | file://:1:1:1:1 | | input | file://ReturnValue:1:1:1:1 | ReturnValue | output | file://:1:1:1:1 | | parameterName | file://:1:1:1:1 | | alreadyAiModeled | file://sourceModel:1:1:1:1 | sourceModel | extensibleType |
From a5e7ef424e241b72ad9a4c82d113379368683026 Mon Sep 17 00:00:00 2001
From: Max Schaefer
Date: Thu, 16 Nov 2023 11:54:16 +0000
Subject: [PATCH 19/22] Revert "Add additional example."
This reverts commit 947b094387278c3cf0e4f2162a84df3def2bf688.
---
java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp | 5 -----
.../src/Security/CWE/CWE-022/TaintedPathGood2.java | 13 -------------
.../security/CWE-022/semmle/tests/TaintedPath.java | 13 -------------
3 files changed, 31 deletions(-)
delete mode 100644 java/ql/src/Security/CWE/CWE-022/TaintedPathGood2.java
diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp b/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp
index b371a114059..a68bdad3441 100644
--- a/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp
+++ b/java/ql/src/Security/CWE/CWE-022/TaintedPath.qhelp
@@ -46,11 +46,6 @@ not contain ".." and starts with the public folder.
-Alternatively, if you only want to allow simple filenames without a path component, you can remove all path
-separators ("/" or "\") and all ".." sequences from the input before using it to construct a file path.
-
-
-
diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPathGood2.java b/java/ql/src/Security/CWE/CWE-022/TaintedPathGood2.java
deleted file mode 100644
index 6f5a19d5fd8..00000000000
--- a/java/ql/src/Security/CWE/CWE-022/TaintedPathGood2.java
+++ /dev/null
@@ -1,13 +0,0 @@
-public void sendUserFileGood(Socket sock, String user) {
- BufferedReader filenameReader = new BufferedReader(
- new InputStreamReader(sock.getInputStream(), "UTF-8"));
- String filename = filenameReader.readLine();
- // GOOD: remove all ".." sequences and path separators from the filename
- filename = filename.replaceAll("\\.\\.|[/\\\\]", "");
- BufferedReader fileReader = new BufferedReader(new FileReader(filename));
- String fileLine = fileReader.readLine();
- while(fileLine != null) {
- sock.getOutputStream().write(fileLine.getBytes());
- fileLine = fileReader.readLine();
- }
-}
diff --git a/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java
index 6f20e66c34e..5a5a63ad6ad 100644
--- a/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java
+++ b/java/ql/test/query-tests/security/CWE-022/semmle/tests/TaintedPath.java
@@ -32,17 +32,4 @@ public class TaintedPath {
}
}
}
-
- public void sendUserFileGood2(Socket sock, String user) throws IOException {
- BufferedReader filenameReader = new BufferedReader(new InputStreamReader(sock.getInputStream(), "UTF-8"));
- String filename = filenameReader.readLine();
- // GOOD: remove all ".." sequences and path separators from the filename
- filename = filename.replaceAll("\\.\\.|[/\\\\]", "");
- BufferedReader fileReader = new BufferedReader(new FileReader(filename));
- String fileLine = fileReader.readLine();
- while(fileLine != null) {
- sock.getOutputStream().write(fileLine.getBytes());
- fileLine = fileReader.readLine();
- }
- }
}
From 2c23dacca15b48bb4ab0ac48cd4682ed7ec234ae Mon Sep 17 00:00:00 2001
From: Tom Hvitved
Date: Thu, 16 Nov 2023 12:29:19 +0100
Subject: [PATCH 20/22] Ruby: Add more hash/array literal tests
---
.../dataflow/array-flow/array-flow.expected | 219 ++++++++++++++++++
.../dataflow/array-flow/array-flow.ql | 3 +
.../dataflow/array-flow/array_flow.rb | 30 +++
.../dataflow/hash-flow/hash-flow.expected | 102 ++++++++
.../dataflow/hash-flow/hash-flow.ql | 3 +
.../dataflow/hash-flow/hash_flow.rb | 36 ++-
6 files changed, 392 insertions(+), 1 deletion(-)
diff --git a/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected b/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected
index 0d61ff1515b..f36cf514b89 100644
--- a/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected
+++ b/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected
@@ -2108,6 +2108,18 @@ edges
| array_flow.rb:1641:10:1641:10 | a [element] | array_flow.rb:1641:10:1641:17 | ...[...] |
| array_flow.rb:1643:10:1643:10 | a [element 0] | array_flow.rb:1643:10:1643:15 | ...[...] |
| array_flow.rb:1643:10:1643:10 | a [element] | array_flow.rb:1643:10:1643:15 | ...[...] |
+| array_flow.rb:1647:5:1647:5 | a [element 1] | array_flow.rb:1649:10:1649:10 | a [element 1] |
+| array_flow.rb:1647:5:1647:5 | a [element 1] | array_flow.rb:1651:10:1651:10 | a [element 1] |
+| array_flow.rb:1647:9:1647:32 | ...[...] [element 1] | array_flow.rb:1647:5:1647:5 | a [element 1] |
+| array_flow.rb:1647:18:1647:28 | call to source | array_flow.rb:1647:9:1647:32 | ...[...] [element 1] |
+| array_flow.rb:1649:10:1649:10 | a [element 1] | array_flow.rb:1649:10:1649:13 | ...[...] |
+| array_flow.rb:1651:10:1651:10 | a [element 1] | array_flow.rb:1651:10:1651:13 | ...[...] |
+| array_flow.rb:1668:9:1668:10 | a2 [element 1] | array_flow.rb:1670:14:1670:15 | a2 [element 1] |
+| array_flow.rb:1668:9:1668:10 | a2 [element 1] | array_flow.rb:1672:14:1672:15 | a2 [element 1] |
+| array_flow.rb:1668:14:1668:41 | ...[...] [element 1] | array_flow.rb:1668:9:1668:10 | a2 [element 1] |
+| array_flow.rb:1668:25:1668:37 | call to source | array_flow.rb:1668:14:1668:41 | ...[...] [element 1] |
+| array_flow.rb:1670:14:1670:15 | a2 [element 1] | array_flow.rb:1670:14:1670:18 | ...[...] |
+| array_flow.rb:1672:14:1672:15 | a2 [element 1] | array_flow.rb:1672:14:1672:18 | ...[...] |
nodes
| array_flow.rb:2:5:2:5 | a [element 0] | semmle.label | a [element 0] |
| array_flow.rb:2:9:2:20 | * ... [element 0] | semmle.label | * ... [element 0] |
@@ -4348,7 +4360,210 @@ nodes
| array_flow.rb:1643:10:1643:10 | a [element 0] | semmle.label | a [element 0] |
| array_flow.rb:1643:10:1643:10 | a [element] | semmle.label | a [element] |
| array_flow.rb:1643:10:1643:15 | ...[...] | semmle.label | ...[...] |
+| array_flow.rb:1647:5:1647:5 | a [element 1] | semmle.label | a [element 1] |
+| array_flow.rb:1647:9:1647:32 | ...[...] [element 1] | semmle.label | ...[...] [element 1] |
+| array_flow.rb:1647:18:1647:28 | call to source | semmle.label | call to source |
+| array_flow.rb:1649:10:1649:10 | a [element 1] | semmle.label | a [element 1] |
+| array_flow.rb:1649:10:1649:13 | ...[...] | semmle.label | ...[...] |
+| array_flow.rb:1651:10:1651:10 | a [element 1] | semmle.label | a [element 1] |
+| array_flow.rb:1651:10:1651:13 | ...[...] | semmle.label | ...[...] |
+| array_flow.rb:1668:9:1668:10 | a2 [element 1] | semmle.label | a2 [element 1] |
+| array_flow.rb:1668:14:1668:41 | ...[...] [element 1] | semmle.label | ...[...] [element 1] |
+| array_flow.rb:1668:25:1668:37 | call to source | semmle.label | call to source |
+| array_flow.rb:1670:14:1670:15 | a2 [element 1] | semmle.label | a2 [element 1] |
+| array_flow.rb:1670:14:1670:18 | ...[...] | semmle.label | ...[...] |
+| array_flow.rb:1672:14:1672:15 | a2 [element 1] | semmle.label | a2 [element 1] |
+| array_flow.rb:1672:14:1672:18 | ...[...] | semmle.label | ...[...] |
subpaths
+arrayLiteral
+| array_flow.rb:9:9:9:25 | call to [] |
+| array_flow.rb:33:9:33:22 | call to [] |
+| array_flow.rb:40:9:40:24 | call to [] |
+| array_flow.rb:41:9:41:27 | call to [] |
+| array_flow.rb:48:9:48:22 | call to [] |
+| array_flow.rb:55:9:55:24 | call to [] |
+| array_flow.rb:56:9:56:24 | call to [] |
+| array_flow.rb:63:9:63:24 | call to [] |
+| array_flow.rb:64:9:64:24 | call to [] |
+| array_flow.rb:71:9:71:24 | call to [] |
+| array_flow.rb:80:9:80:25 | call to [] |
+| array_flow.rb:88:9:88:26 | call to [] |
+| array_flow.rb:96:9:96:26 | call to [] |
+| array_flow.rb:103:9:103:39 | call to [] |
+| array_flow.rb:109:9:109:42 | call to [] |
+| array_flow.rb:120:9:120:14 | call to [] |
+| array_flow.rb:128:9:128:14 | call to [] |
+| array_flow.rb:129:15:129:32 | call to [] |
+| array_flow.rb:136:9:136:14 | call to [] |
+| array_flow.rb:144:9:144:14 | call to [] |
+| array_flow.rb:145:15:145:32 | call to [] |
+| array_flow.rb:152:9:152:26 | call to [] |
+| array_flow.rb:159:9:159:26 | call to [] |
+| array_flow.rb:166:9:166:25 | call to [] |
+| array_flow.rb:175:9:175:16 | call to [] |
+| array_flow.rb:176:9:176:16 | call to [] |
+| array_flow.rb:177:9:177:25 | call to [] |
+| array_flow.rb:178:9:178:17 | call to [] |
+| array_flow.rb:184:9:184:26 | call to [] |
+| array_flow.rb:192:9:192:26 | call to [] |
+| array_flow.rb:200:9:200:26 | call to [] |
+| array_flow.rb:208:9:208:26 | call to [] |
+| array_flow.rb:215:9:215:42 | call to [] |
+| array_flow.rb:224:9:224:26 | call to [] |
+| array_flow.rb:231:9:231:28 | call to [] |
+| array_flow.rb:240:9:240:28 | call to [] |
+| array_flow.rb:250:9:250:28 | call to [] |
+| array_flow.rb:253:9:253:25 | call to [] |
+| array_flow.rb:264:9:264:26 | call to [] |
+| array_flow.rb:273:9:273:26 | call to [] |
+| array_flow.rb:279:9:279:26 | call to [] |
+| array_flow.rb:286:9:286:28 | call to [] |
+| array_flow.rb:287:9:287:28 | call to [] |
+| array_flow.rb:294:9:294:26 | call to [] |
+| array_flow.rb:301:9:301:26 | call to [] |
+| array_flow.rb:308:9:308:26 | call to [] |
+| array_flow.rb:316:9:316:28 | call to [] |
+| array_flow.rb:325:9:325:42 | call to [] |
+| array_flow.rb:330:9:330:42 | call to [] |
+| array_flow.rb:338:9:338:26 | call to [] |
+| array_flow.rb:349:9:349:26 | call to [] |
+| array_flow.rb:350:22:350:24 | call to [] |
+| array_flow.rb:355:9:355:47 | call to [] |
+| array_flow.rb:355:30:355:46 | call to [] |
+| array_flow.rb:364:9:364:28 | call to [] |
+| array_flow.rb:372:9:372:42 | call to [] |
+| array_flow.rb:387:9:387:42 | call to [] |
+| array_flow.rb:395:9:395:26 | call to [] |
+| array_flow.rb:403:9:403:26 | call to [] |
+| array_flow.rb:412:9:412:26 | call to [] |
+| array_flow.rb:419:9:419:26 | call to [] |
+| array_flow.rb:427:9:427:26 | call to [] |
+| array_flow.rb:435:9:435:29 | call to [] |
+| array_flow.rb:442:9:442:29 | call to [] |
+| array_flow.rb:451:9:451:31 | call to [] |
+| array_flow.rb:460:9:460:29 | call to [] |
+| array_flow.rb:466:9:466:45 | call to [] |
+| array_flow.rb:482:9:482:31 | call to [] |
+| array_flow.rb:498:9:498:29 | call to [] |
+| array_flow.rb:506:9:506:29 | call to [] |
+| array_flow.rb:518:9:518:16 | call to [] |
+| array_flow.rb:525:9:525:29 | call to [] |
+| array_flow.rb:535:9:535:31 | call to [] |
+| array_flow.rb:543:9:543:29 | call to [] |
+| array_flow.rb:551:9:551:29 | call to [] |
+| array_flow.rb:558:9:558:42 | call to [] |
+| array_flow.rb:570:9:570:28 | call to [] |
+| array_flow.rb:573:9:573:25 | call to [] |
+| array_flow.rb:584:9:584:31 | call to [] |
+| array_flow.rb:584:16:584:30 | call to [] |
+| array_flow.rb:590:9:590:31 | call to [] |
+| array_flow.rb:590:16:590:30 | call to [] |
+| array_flow.rb:600:9:600:31 | call to [] |
+| array_flow.rb:611:9:611:31 | call to [] |
+| array_flow.rb:622:9:622:31 | call to [] |
+| array_flow.rb:631:9:631:29 | call to [] |
+| array_flow.rb:638:9:638:39 | call to [] |
+| array_flow.rb:655:9:655:28 | call to [] |
+| array_flow.rb:669:9:669:28 | call to [] |
+| array_flow.rb:676:9:676:26 | call to [] |
+| array_flow.rb:683:9:683:28 | call to [] |
+| array_flow.rb:684:24:684:43 | call to [] |
+| array_flow.rb:684:46:684:59 | call to [] |
+| array_flow.rb:689:9:689:26 | call to [] |
+| array_flow.rb:699:9:699:28 | call to [] |
+| array_flow.rb:708:9:708:28 | call to [] |
+| array_flow.rb:717:9:717:28 | call to [] |
+| array_flow.rb:726:9:726:26 | call to [] |
+| array_flow.rb:754:9:754:26 | call to [] |
+| array_flow.rb:772:9:772:26 | call to [] |
+| array_flow.rb:800:9:800:26 | call to [] |
+| array_flow.rb:818:9:818:26 | call to [] |
+| array_flow.rb:834:9:834:26 | call to [] |
+| array_flow.rb:844:9:844:26 | call to [] |
+| array_flow.rb:853:9:853:26 | call to [] |
+| array_flow.rb:860:9:860:26 | call to [] |
+| array_flow.rb:866:9:866:26 | call to [] |
+| array_flow.rb:876:9:876:26 | call to [] |
+| array_flow.rb:905:9:905:42 | call to [] |
+| array_flow.rb:913:9:913:42 | call to [] |
+| array_flow.rb:924:9:924:28 | call to [] |
+| array_flow.rb:935:9:935:28 | call to [] |
+| array_flow.rb:936:9:936:28 | call to [] |
+| array_flow.rb:937:9:937:28 | call to [] |
+| array_flow.rb:944:9:944:25 | call to [] |
+| array_flow.rb:953:9:953:16 | call to [] |
+| array_flow.rb:954:9:954:16 | call to [] |
+| array_flow.rb:955:9:955:25 | call to [] |
+| array_flow.rb:956:9:956:17 | call to [] |
+| array_flow.rb:962:9:962:39 | call to [] |
+| array_flow.rb:976:9:976:26 | call to [] |
+| array_flow.rb:985:9:985:26 | call to [] |
+| array_flow.rb:995:9:995:26 | call to [] |
+| array_flow.rb:1005:9:1005:26 | call to [] |
+| array_flow.rb:1016:9:1016:31 | call to [] |
+| array_flow.rb:1017:19:1017:32 | call to [] |
+| array_flow.rb:1023:9:1023:44 | call to [] |
+| array_flow.rb:1034:9:1034:44 | call to [] |
+| array_flow.rb:1045:9:1045:27 | call to [] |
+| array_flow.rb:1053:9:1053:27 | call to [] |
+| array_flow.rb:1063:9:1063:56 | call to [] |
+| array_flow.rb:1095:9:1095:56 | call to [] |
+| array_flow.rb:1106:9:1106:56 | call to [] |
+| array_flow.rb:1117:9:1117:56 | call to [] |
+| array_flow.rb:1128:9:1128:56 | call to [] |
+| array_flow.rb:1141:9:1141:30 | call to [] |
+| array_flow.rb:1149:9:1149:27 | call to [] |
+| array_flow.rb:1159:9:1159:41 | call to [] |
+| array_flow.rb:1166:9:1166:41 | call to [] |
+| array_flow.rb:1174:9:1174:41 | call to [] |
+| array_flow.rb:1184:9:1184:27 | call to [] |
+| array_flow.rb:1195:9:1195:27 | call to [] |
+| array_flow.rb:1206:9:1206:47 | call to [] |
+| array_flow.rb:1260:9:1260:47 | call to [] |
+| array_flow.rb:1268:9:1268:47 | call to [] |
+| array_flow.rb:1279:9:1279:47 | call to [] |
+| array_flow.rb:1290:9:1290:47 | call to [] |
+| array_flow.rb:1301:9:1301:47 | call to [] |
+| array_flow.rb:1312:9:1312:47 | call to [] |
+| array_flow.rb:1321:9:1321:47 | call to [] |
+| array_flow.rb:1330:9:1330:47 | call to [] |
+| array_flow.rb:1339:9:1339:47 | call to [] |
+| array_flow.rb:1348:9:1348:47 | call to [] |
+| array_flow.rb:1359:9:1359:27 | call to [] |
+| array_flow.rb:1367:9:1367:27 | call to [] |
+| array_flow.rb:1375:9:1375:27 | call to [] |
+| array_flow.rb:1383:9:1383:27 | call to [] |
+| array_flow.rb:1397:9:1397:27 | call to [] |
+| array_flow.rb:1404:9:1404:27 | call to [] |
+| array_flow.rb:1417:9:1417:27 | call to [] |
+| array_flow.rb:1427:9:1427:27 | call to [] |
+| array_flow.rb:1439:9:1439:27 | call to [] |
+| array_flow.rb:1447:9:1447:44 | call to [] |
+| array_flow.rb:1471:9:1471:27 | call to [] |
+| array_flow.rb:1484:9:1484:30 | call to [] |
+| array_flow.rb:1490:9:1490:27 | call to [] |
+| array_flow.rb:1500:9:1500:27 | call to [] |
+| array_flow.rb:1507:9:1507:68 | call to [] |
+| array_flow.rb:1507:10:1507:27 | call to [] |
+| array_flow.rb:1507:30:1507:47 | call to [] |
+| array_flow.rb:1507:50:1507:67 | call to [] |
+| array_flow.rb:1518:9:1518:29 | call to [] |
+| array_flow.rb:1519:9:1519:26 | call to [] |
+| array_flow.rb:1520:9:1520:26 | call to [] |
+| array_flow.rb:1528:9:1528:47 | call to [] |
+| array_flow.rb:1542:9:1542:44 | call to [] |
+| array_flow.rb:1549:9:1549:44 | call to [] |
+| array_flow.rb:1561:9:1561:29 | call to [] |
+| array_flow.rb:1572:9:1572:44 | call to [] |
+| array_flow.rb:1596:9:1596:29 | call to [] |
+| array_flow.rb:1597:9:1597:29 | call to [] |
+| array_flow.rb:1598:9:1598:29 | call to [] |
+| array_flow.rb:1612:9:1612:29 | call to [] |
+| array_flow.rb:1613:9:1613:26 | call to [] |
+| array_flow.rb:1621:9:1621:13 | call to [] |
+| array_flow.rb:1621:10:1621:12 | call to [] |
+| array_flow.rb:1647:9:1647:32 | ...[...] |
+| array_flow.rb:1668:14:1668:41 | ...[...] |
#select
| array_flow.rb:3:10:3:13 | ...[...] | array_flow.rb:2:10:2:20 | call to source | array_flow.rb:3:10:3:13 | ...[...] | $@ | array_flow.rb:2:10:2:20 | call to source | call to source |
| array_flow.rb:5:10:5:13 | ...[...] | array_flow.rb:2:10:2:20 | call to source | array_flow.rb:5:10:5:13 | ...[...] | $@ | array_flow.rb:2:10:2:20 | call to source | call to source |
@@ -5045,3 +5260,7 @@ subpaths
| array_flow.rb:1643:10:1643:15 | ...[...] | array_flow.rb:1634:16:1634:28 | call to source | array_flow.rb:1643:10:1643:15 | ...[...] | $@ | array_flow.rb:1634:16:1634:28 | call to source | call to source |
| array_flow.rb:1643:10:1643:15 | ...[...] | array_flow.rb:1636:14:1636:26 | call to source | array_flow.rb:1643:10:1643:15 | ...[...] | $@ | array_flow.rb:1636:14:1636:26 | call to source | call to source |
| array_flow.rb:1643:10:1643:15 | ...[...] | array_flow.rb:1638:16:1638:28 | call to source | array_flow.rb:1643:10:1643:15 | ...[...] | $@ | array_flow.rb:1638:16:1638:28 | call to source | call to source |
+| array_flow.rb:1649:10:1649:13 | ...[...] | array_flow.rb:1647:18:1647:28 | call to source | array_flow.rb:1649:10:1649:13 | ...[...] | $@ | array_flow.rb:1647:18:1647:28 | call to source | call to source |
+| array_flow.rb:1651:10:1651:13 | ...[...] | array_flow.rb:1647:18:1647:28 | call to source | array_flow.rb:1651:10:1651:13 | ...[...] | $@ | array_flow.rb:1647:18:1647:28 | call to source | call to source |
+| array_flow.rb:1670:14:1670:18 | ...[...] | array_flow.rb:1668:25:1668:37 | call to source | array_flow.rb:1670:14:1670:18 | ...[...] | $@ | array_flow.rb:1668:25:1668:37 | call to source | call to source |
+| array_flow.rb:1672:14:1672:18 | ...[...] | array_flow.rb:1668:25:1668:37 | call to source | array_flow.rb:1672:14:1672:18 | ...[...] | $@ | array_flow.rb:1668:25:1668:37 | call to source | call to source |
diff --git a/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.ql b/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.ql
index e02827eaf8d..756833e8b35 100644
--- a/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.ql
+++ b/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.ql
@@ -3,10 +3,13 @@
*/
import codeql.ruby.AST
+import codeql.ruby.CFG
import TestUtilities.InlineFlowTest
import DefaultFlowTest
import ValueFlow::PathGraph
+query predicate arrayLiteral(CfgNodes::ExprNodes::ArrayLiteralCfgNode n) { any() }
+
from ValueFlow::PathNode source, ValueFlow::PathNode sink
where ValueFlow::flowPath(source, sink)
select sink, source, sink, "$@", source, source.toString()
diff --git a/ruby/ql/test/library-tests/dataflow/array-flow/array_flow.rb b/ruby/ql/test/library-tests/dataflow/array-flow/array_flow.rb
index fb5ee3c728a..bc137a38334 100644
--- a/ruby/ql/test/library-tests/dataflow/array-flow/array_flow.rb
+++ b/ruby/ql/test/library-tests/dataflow/array-flow/array_flow.rb
@@ -1642,3 +1642,33 @@ def m137
# unknown read
sink(a[1.0]) # $ hasValueFlow=137.1 $ hasValueFlow=137.2 $ hasValueFlow=137.3 $ hasValueFlow=137.4
end
+
+def m138(i)
+ a = Array[0, source(138), 2]
+ sink(a[0])
+ sink(a[1]) # $ hasValueFlow=138
+ sink(a[2])
+ sink(a[i]) # $ hasValueFlow=138
+end
+
+class M139
+ class Array
+ def self.[]
+ ::Array.new
+ end
+ end
+
+ def m139(i)
+ a = Array[0, source(139.1), 2]
+ sink(a[0])
+ sink(a[1])
+ sink(a[2])
+ sink(a[i])
+
+ a2 = ::Array[0, source(139.2), 2]
+ sink(a2[0])
+ sink(a2[1]) # $ hasValueFlow=139.2
+ sink(a2[2])
+ sink(a2[i]) # $ hasValueFlow=139.2
+ end
+end
diff --git a/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.expected b/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.expected
index 79f2565a590..00372d87e00 100644
--- a/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.expected
+++ b/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.expected
@@ -964,6 +964,18 @@ edges
| hash_flow.rb:963:11:963:19 | ...[...] | hash_flow.rb:963:10:963:20 | ( ... ) |
| hash_flow.rb:965:11:965:15 | hash1 [element :f] | hash_flow.rb:965:11:965:19 | ...[...] |
| hash_flow.rb:965:11:965:19 | ...[...] | hash_flow.rb:965:10:965:20 | ( ... ) |
+| hash_flow.rb:971:5:971:5 | h [element :b] | hash_flow.rb:973:10:973:10 | h [element :b] |
+| hash_flow.rb:971:5:971:5 | h [element :b] | hash_flow.rb:975:10:975:10 | h [element :b] |
+| hash_flow.rb:971:9:971:38 | ...[...] [element :b] | hash_flow.rb:971:5:971:5 | h [element :b] |
+| hash_flow.rb:971:23:971:31 | call to taint | hash_flow.rb:971:9:971:38 | ...[...] [element :b] |
+| hash_flow.rb:973:10:973:10 | h [element :b] | hash_flow.rb:973:10:973:14 | ...[...] |
+| hash_flow.rb:975:10:975:10 | h [element :b] | hash_flow.rb:975:10:975:13 | ...[...] |
+| hash_flow.rb:994:9:994:10 | h2 [element :b] | hash_flow.rb:996:14:996:15 | h2 [element :b] |
+| hash_flow.rb:994:9:994:10 | h2 [element :b] | hash_flow.rb:998:14:998:15 | h2 [element :b] |
+| hash_flow.rb:994:14:994:47 | ...[...] [element :b] | hash_flow.rb:994:9:994:10 | h2 [element :b] |
+| hash_flow.rb:994:30:994:40 | call to taint | hash_flow.rb:994:14:994:47 | ...[...] [element :b] |
+| hash_flow.rb:996:14:996:15 | h2 [element :b] | hash_flow.rb:996:14:996:19 | ...[...] |
+| hash_flow.rb:998:14:998:15 | h2 [element :b] | hash_flow.rb:998:14:998:18 | ...[...] |
nodes
| hash_flow.rb:10:5:10:8 | hash [element 0] | semmle.label | hash [element 0] |
| hash_flow.rb:10:5:10:8 | hash [element :a] | semmle.label | hash [element :a] |
@@ -1999,7 +2011,93 @@ nodes
| hash_flow.rb:965:10:965:20 | ( ... ) | semmle.label | ( ... ) |
| hash_flow.rb:965:11:965:15 | hash1 [element :f] | semmle.label | hash1 [element :f] |
| hash_flow.rb:965:11:965:19 | ...[...] | semmle.label | ...[...] |
+| hash_flow.rb:971:5:971:5 | h [element :b] | semmle.label | h [element :b] |
+| hash_flow.rb:971:9:971:38 | ...[...] [element :b] | semmle.label | ...[...] [element :b] |
+| hash_flow.rb:971:23:971:31 | call to taint | semmle.label | call to taint |
+| hash_flow.rb:973:10:973:10 | h [element :b] | semmle.label | h [element :b] |
+| hash_flow.rb:973:10:973:14 | ...[...] | semmle.label | ...[...] |
+| hash_flow.rb:975:10:975:10 | h [element :b] | semmle.label | h [element :b] |
+| hash_flow.rb:975:10:975:13 | ...[...] | semmle.label | ...[...] |
+| hash_flow.rb:994:9:994:10 | h2 [element :b] | semmle.label | h2 [element :b] |
+| hash_flow.rb:994:14:994:47 | ...[...] [element :b] | semmle.label | ...[...] [element :b] |
+| hash_flow.rb:994:30:994:40 | call to taint | semmle.label | call to taint |
+| hash_flow.rb:996:14:996:15 | h2 [element :b] | semmle.label | h2 [element :b] |
+| hash_flow.rb:996:14:996:19 | ...[...] | semmle.label | ...[...] |
+| hash_flow.rb:998:14:998:15 | h2 [element :b] | semmle.label | h2 [element :b] |
+| hash_flow.rb:998:14:998:18 | ...[...] | semmle.label | ...[...] |
subpaths
+hashLiteral
+| hash_flow.rb:10:12:21:5 | call to [] |
+| hash_flow.rb:55:13:55:37 | ...[...] |
+| hash_flow.rb:59:9:59:29 | call to [] |
+| hash_flow.rb:60:13:60:19 | ...[...] |
+| hash_flow.rb:64:13:64:45 | ...[...] |
+| hash_flow.rb:68:13:68:39 | ...[...] |
+| hash_flow.rb:72:13:72:45 | ...[...] |
+| hash_flow.rb:76:13:76:47 | ...[...] |
+| hash_flow.rb:76:18:76:46 | call to [] |
+| hash_flow.rb:84:13:84:42 | call to [] |
+| hash_flow.rb:92:12:95:5 | call to [] |
+| hash_flow.rb:127:12:130:5 | call to [] |
+| hash_flow.rb:143:12:146:5 | call to [] |
+| hash_flow.rb:158:12:161:5 | call to [] |
+| hash_flow.rb:169:12:172:5 | call to [] |
+| hash_flow.rb:181:12:184:5 | call to [] |
+| hash_flow.rb:193:12:196:5 | call to [] |
+| hash_flow.rb:209:12:216:5 | call to [] |
+| hash_flow.rb:212:15:215:9 | call to [] |
+| hash_flow.rb:226:12:229:5 | call to [] |
+| hash_flow.rb:241:12:244:5 | call to [] |
+| hash_flow.rb:255:12:258:5 | call to [] |
+| hash_flow.rb:270:12:273:5 | call to [] |
+| hash_flow.rb:284:12:289:5 | call to [] |
+| hash_flow.rb:300:12:304:5 | call to [] |
+| hash_flow.rb:322:12:326:5 | call to [] |
+| hash_flow.rb:341:12:345:5 | call to [] |
+| hash_flow.rb:357:12:361:5 | call to [] |
+| hash_flow.rb:373:12:377:5 | call to [] |
+| hash_flow.rb:385:12:389:5 | call to [] |
+| hash_flow.rb:402:13:406:5 | call to [] |
+| hash_flow.rb:407:13:411:5 | call to [] |
+| hash_flow.rb:428:13:432:5 | call to [] |
+| hash_flow.rb:433:13:437:5 | call to [] |
+| hash_flow.rb:461:12:464:5 | call to [] |
+| hash_flow.rb:473:12:476:5 | call to [] |
+| hash_flow.rb:488:12:491:5 | call to [] |
+| hash_flow.rb:504:12:508:5 | call to [] |
+| hash_flow.rb:509:13:511:5 | call to [] |
+| hash_flow.rb:519:12:523:5 | call to [] |
+| hash_flow.rb:535:12:539:5 | call to [] |
+| hash_flow.rb:551:12:555:5 | call to [] |
+| hash_flow.rb:565:12:569:5 | call to [] |
+| hash_flow.rb:584:12:588:5 | call to [] |
+| hash_flow.rb:597:12:601:5 | call to [] |
+| hash_flow.rb:618:12:622:5 | call to [] |
+| hash_flow.rb:632:12:636:5 | call to [] |
+| hash_flow.rb:648:12:652:5 | call to [] |
+| hash_flow.rb:664:12:668:5 | call to [] |
+| hash_flow.rb:679:13:683:5 | call to [] |
+| hash_flow.rb:684:13:688:5 | call to [] |
+| hash_flow.rb:712:12:716:5 | call to [] |
+| hash_flow.rb:724:12:728:5 | call to [] |
+| hash_flow.rb:738:13:742:5 | call to [] |
+| hash_flow.rb:743:13:747:5 | call to [] |
+| hash_flow.rb:748:12:748:59 | call to [] |
+| hash_flow.rb:762:12:767:5 | call to [] |
+| hash_flow.rb:790:13:794:5 | call to [] |
+| hash_flow.rb:795:13:799:5 | call to [] |
+| hash_flow.rb:816:13:820:5 | call to [] |
+| hash_flow.rb:821:13:825:5 | call to [] |
+| hash_flow.rb:849:13:853:5 | call to [] |
+| hash_flow.rb:854:13:858:5 | call to [] |
+| hash_flow.rb:881:13:885:5 | call to [] |
+| hash_flow.rb:886:13:890:5 | call to [] |
+| hash_flow.rb:911:13:915:5 | call to [] |
+| hash_flow.rb:916:13:920:5 | call to [] |
+| hash_flow.rb:941:13:945:5 | call to [] |
+| hash_flow.rb:946:13:950:5 | call to [] |
+| hash_flow.rb:971:9:971:38 | ...[...] |
+| hash_flow.rb:994:14:994:47 | ...[...] |
#select
| hash_flow.rb:22:10:22:17 | ...[...] | hash_flow.rb:11:15:11:24 | call to taint | hash_flow.rb:22:10:22:17 | ...[...] | $@ | hash_flow.rb:11:15:11:24 | call to taint | call to taint |
| hash_flow.rb:24:10:24:17 | ...[...] | hash_flow.rb:13:12:13:21 | call to taint | hash_flow.rb:24:10:24:17 | ...[...] | $@ | hash_flow.rb:13:12:13:21 | call to taint | call to taint |
@@ -2241,3 +2339,7 @@ subpaths
| hash_flow.rb:962:10:962:20 | ( ... ) | hash_flow.rb:944:12:944:22 | call to taint | hash_flow.rb:962:10:962:20 | ( ... ) | $@ | hash_flow.rb:944:12:944:22 | call to taint | call to taint |
| hash_flow.rb:963:10:963:20 | ( ... ) | hash_flow.rb:947:12:947:22 | call to taint | hash_flow.rb:963:10:963:20 | ( ... ) | $@ | hash_flow.rb:947:12:947:22 | call to taint | call to taint |
| hash_flow.rb:965:10:965:20 | ( ... ) | hash_flow.rb:949:12:949:22 | call to taint | hash_flow.rb:965:10:965:20 | ( ... ) | $@ | hash_flow.rb:949:12:949:22 | call to taint | call to taint |
+| hash_flow.rb:973:10:973:14 | ...[...] | hash_flow.rb:971:23:971:31 | call to taint | hash_flow.rb:973:10:973:14 | ...[...] | $@ | hash_flow.rb:971:23:971:31 | call to taint | call to taint |
+| hash_flow.rb:975:10:975:13 | ...[...] | hash_flow.rb:971:23:971:31 | call to taint | hash_flow.rb:975:10:975:13 | ...[...] | $@ | hash_flow.rb:971:23:971:31 | call to taint | call to taint |
+| hash_flow.rb:996:14:996:19 | ...[...] | hash_flow.rb:994:30:994:40 | call to taint | hash_flow.rb:996:14:996:19 | ...[...] | $@ | hash_flow.rb:994:30:994:40 | call to taint | call to taint |
+| hash_flow.rb:998:14:998:18 | ...[...] | hash_flow.rb:994:30:994:40 | call to taint | hash_flow.rb:998:14:998:18 | ...[...] | $@ | hash_flow.rb:994:30:994:40 | call to taint | call to taint |
diff --git a/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.ql b/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.ql
index 6f8978fe819..e3b694d3e75 100644
--- a/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.ql
+++ b/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.ql
@@ -3,10 +3,13 @@
*/
import codeql.ruby.AST
+import codeql.ruby.CFG
import TestUtilities.InlineFlowTest
import ValueFlowTest
import ValueFlow::PathGraph
+query predicate hashLiteral(CfgNodes::ExprNodes::HashLiteralCfgNode n) { any() }
+
from ValueFlow::PathNode source, ValueFlow::PathNode sink
where ValueFlow::flowPath(source, sink)
select sink, source, sink, "$@", source, source.toString()
diff --git a/ruby/ql/test/library-tests/dataflow/hash-flow/hash_flow.rb b/ruby/ql/test/library-tests/dataflow/hash-flow/hash_flow.rb
index dbadd617b35..14c2504f959 100644
--- a/ruby/ql/test/library-tests/dataflow/hash-flow/hash_flow.rb
+++ b/ruby/ql/test/library-tests/dataflow/hash-flow/hash_flow.rb
@@ -965,4 +965,38 @@ def m52()
sink (hash1[:f]) # $ hasValueFlow=52.4
end
-m52()
\ No newline at end of file
+m52()
+
+def m53(i)
+ h = Hash[a: 1, b: taint(53), c: 2]
+ sink(h[:a])
+ sink(h[:b]) # $ hasValueFlow=53
+ sink(h[:c])
+ sink(h[i]) # $ hasValueFlow=53
+end
+
+m53(:b)
+
+class M54
+ class Hash
+ def self.[](**kwargs)
+ ::Hash.new
+ end
+ end
+
+ def m54(i)
+ h = Hash[a: 0, b: taint(54.1), c: 2]
+ sink(h[:a])
+ sink(h[:b])
+ sink(h[:c])
+ sink(h[i])
+
+ h2 = ::Hash[a: 0, b: taint(54.2), c: 2]
+ sink(h2[:a])
+ sink(h2[:b]) # $ hasValueFlow=54.2
+ sink(h2[:c])
+ sink(h2[i]) # $ hasValueFlow=54.2
+ end
+end
+
+M54.new.m54(:b)
From 078f223052acf4db8c829a4854c8b56bfb2ae1d5 Mon Sep 17 00:00:00 2001
From: Mathias Vorreiter Pedersen
Date: Tue, 14 Nov 2023 16:46:58 +0000
Subject: [PATCH 21/22] C++: Rewrite 'cpp/cpp/integer-overflow-tainted' away
from DefaultTaintTracking.
---
.../CWE/CWE-190/IntegerOverflowTainted.ql | 87 ++++++++++++++++---
1 file changed, 77 insertions(+), 10 deletions(-)
diff --git a/cpp/ql/src/Security/CWE/CWE-190/IntegerOverflowTainted.ql b/cpp/ql/src/Security/CWE/CWE-190/IntegerOverflowTainted.ql
index 19fe7df4c44..98c53828d2a 100644
--- a/cpp/ql/src/Security/CWE/CWE-190/IntegerOverflowTainted.ql
+++ b/cpp/ql/src/Security/CWE/CWE-190/IntegerOverflowTainted.ql
@@ -15,7 +15,11 @@
import cpp
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
-import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
+import semmle.code.cpp.dataflow.new.DataFlow
+import semmle.code.cpp.security.FlowSources as FS
+import semmle.code.cpp.dataflow.new.TaintTracking
+import semmle.code.cpp.ir.IR
+import semmle.code.cpp.controlflow.IRGuards as IRGuards
/** Holds if `expr` might overflow. */
predicate outOfBoundsExpr(Expr expr, string kind) {
@@ -27,13 +31,76 @@ predicate outOfBoundsExpr(Expr expr, string kind) {
else none()
}
-from Expr use, Expr origin, string kind
+predicate isSource(FS::FlowSource source, string sourceType) { sourceType = source.getSourceType() }
+
+predicate isSink(DataFlow::Node sink, string kind) {
+ exists(Expr use |
+ use = sink.asExpr() and
+ not use.getUnspecifiedType() instanceof PointerType and
+ outOfBoundsExpr(use, kind) and
+ not inSystemMacroExpansion(use)
+ )
+}
+
+predicate hasUpperBoundsCheck(Variable var) {
+ exists(RelationalOperation oper, VariableAccess access |
+ oper.getAnOperand() = access and
+ access.getTarget() = var and
+ // Comparing to 0 is not an upper bound check
+ not oper.getAnOperand().getValue() = "0"
+ )
+}
+
+predicate constantInstruction(Instruction instr) {
+ instr instanceof ConstantInstruction or
+ constantInstruction(instr.(UnaryInstruction).getUnary())
+}
+
+predicate readsVariable(LoadInstruction load, Variable var) {
+ load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var
+}
+
+predicate nodeIsBarrierEqualityCandidate(DataFlow::Node node, Operand access, Variable checkedVar) {
+ exists(Instruction instr | instr = node.asInstruction() |
+ readsVariable(instr, checkedVar) and
+ any(IRGuards::IRGuardCondition guard).ensuresEq(access, _, _, instr.getBlock(), true)
+ )
+}
+
+module Config implements DataFlow::ConfigSig {
+ predicate isSource(DataFlow::Node source) { isSource(source, _) }
+
+ predicate isSink(DataFlow::Node sink) { isSink(sink, _) }
+
+ predicate isBarrier(DataFlow::Node node) {
+ // Block flow if there's an upper bound check of the variable anywhere in the program
+ exists(Variable checkedVar, Instruction instr | instr = node.asInstruction() |
+ readsVariable(instr, checkedVar) and
+ hasUpperBoundsCheck(checkedVar)
+ )
+ or
+ // Block flow if the node is guarded by an equality check
+ exists(Variable checkedVar, Operand access |
+ nodeIsBarrierEqualityCandidate(node, access, checkedVar) and
+ readsVariable(access.getDef(), checkedVar)
+ )
+ or
+ // Block flow to any binary instruction whose operands are both non-constants.
+ exists(BinaryInstruction iTo |
+ iTo = node.asInstruction() and
+ not constantInstruction(iTo.getLeft()) and
+ not constantInstruction(iTo.getRight()) and
+ // propagate taint from either the pointer or the offset, regardless of constantness
+ not iTo instanceof PointerArithmeticInstruction
+ )
+ }
+}
+
+module Flow = TaintTracking::Global;
+
+from DataFlow::Node source, DataFlow::Node sink, string kind, string sourceType
where
- not use.getUnspecifiedType() instanceof PointerType and
- outOfBoundsExpr(use, kind) and
- tainted(origin, use) and
- origin != use and
- not inSystemMacroExpansion(use) and
- // Avoid double-counting: don't include all the conversions of `use`.
- not use instanceof Conversion
-select use, "$@ flows an expression which might " + kind + ".", origin, "User-provided value"
+ Flow::flow(source, sink) and
+ isSource(source, sourceType) and
+ isSink(sink, kind)
+select sink, "$@ flows an expression which might " + kind + ".", source, sourceType
From da2215e7e5329cf79ad6f209aaf70942db0ae55b Mon Sep 17 00:00:00 2001
From: Mathias Vorreiter Pedersen
Date: Tue, 14 Nov 2023 16:47:09 +0000
Subject: [PATCH 22/22] C++: Accept test changes.
---
.../SAMATE/IntegerOverflowTainted.expected | 2 +-
.../tainted/IntegerOverflowTainted.expected | 41 +++++++++++--------
.../IntegerOverflowTainted.expected | 2 +-
3 files changed, 25 insertions(+), 20 deletions(-)
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/IntegerOverflowTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/IntegerOverflowTainted.expected
index 81a97849431..bd2085e9863 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/IntegerOverflowTainted.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/IntegerOverflowTainted.expected
@@ -1 +1 @@
-| examples.cpp:66:9:66:14 | -- ... | $@ flows an expression which might overflow negatively. | examples.cpp:63:26:63:30 | & ... | User-provided value |
+| examples.cpp:66:9:66:14 | -- ... | $@ flows an expression which might overflow negatively. | examples.cpp:63:26:63:30 | fscanf output argument | value read by fscanf |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/IntegerOverflowTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/IntegerOverflowTainted.expected
index 4b6f14663c0..2f01718f0f4 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/IntegerOverflowTainted.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/IntegerOverflowTainted.expected
@@ -1,18 +1,23 @@
-| test2.cpp:14:11:14:15 | ... * ... | $@ flows an expression which might overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
-| test2.cpp:15:11:15:19 | ... * ... | $@ flows an expression which might overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
-| test2.cpp:16:11:16:21 | ... * ... | $@ flows an expression which might overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
-| test2.cpp:17:11:17:22 | ... * ... | $@ flows an expression which might overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
-| test2.cpp:39:9:39:18 | ... + ... | $@ flows an expression which might overflow. | test2.cpp:36:9:36:14 | buffer | User-provided value |
-| test2.cpp:40:3:40:13 | ... += ... | $@ flows an expression which might overflow. | test2.cpp:36:9:36:14 | buffer | User-provided value |
-| test3.c:12:31:12:34 | * ... | $@ flows an expression which might overflow negatively. | test3.c:11:15:11:18 | argv | User-provided value |
-| test3.c:13:16:13:19 | * ... | $@ flows an expression which might overflow negatively. | test3.c:11:15:11:18 | argv | User-provided value |
-| test4.cpp:13:17:13:20 | access to array | $@ flows an expression which might overflow negatively. | test4.cpp:9:13:9:16 | argv | User-provided value |
-| test5.cpp:10:9:10:15 | call to strtoul | $@ flows an expression which might overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
-| test5.cpp:17:6:17:27 | ... * ... | $@ flows an expression which might overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
-| test5.cpp:19:6:19:13 | ... * ... | $@ flows an expression which might overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
-| test6.cpp:11:15:11:15 | s | $@ flows an expression which might overflow. | test6.cpp:39:23:39:24 | & ... | User-provided value |
-| test6.cpp:16:15:16:15 | s | $@ flows an expression which might overflow. | test6.cpp:39:23:39:24 | & ... | User-provided value |
-| test6.cpp:30:16:30:16 | s | $@ flows an expression which might overflow. | test6.cpp:39:23:39:24 | & ... | User-provided value |
-| test.c:14:15:14:35 | ... * ... | $@ flows an expression which might overflow. | test.c:11:29:11:32 | argv | User-provided value |
-| test.c:44:7:44:12 | ... -- | $@ flows an expression which might overflow negatively. | test.c:41:17:41:20 | argv | User-provided value |
-| test.c:54:7:54:12 | ... -- | $@ flows an expression which might overflow negatively. | test.c:51:17:51:20 | argv | User-provided value |
+| test2.cpp:14:11:14:15 | ... * ... | $@ flows an expression which might overflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
+| test2.cpp:15:11:15:19 | ... * ... | $@ flows an expression which might overflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
+| test2.cpp:16:11:16:21 | ... * ... | $@ flows an expression which might overflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
+| test2.cpp:17:11:17:22 | ... * ... | $@ flows an expression which might overflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
+| test2.cpp:39:9:39:18 | ... + ... | $@ flows an expression which might overflow. | test2.cpp:36:9:36:14 | fgets output argument | string read by fgets |
+| test2.cpp:40:3:40:13 | ... += ... | $@ flows an expression which might overflow. | test2.cpp:36:9:36:14 | fgets output argument | string read by fgets |
+| test3.c:12:11:12:34 | * ... | $@ flows an expression which might overflow negatively. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
+| test3.c:12:11:12:34 | * ... | $@ flows an expression which might overflow negatively. | test.c:10:27:10:30 | argv indirection | a command-line argument |
+| test3.c:13:11:13:20 | * ... | $@ flows an expression which might overflow negatively. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
+| test3.c:13:11:13:20 | * ... | $@ flows an expression which might overflow negatively. | test.c:10:27:10:30 | argv indirection | a command-line argument |
+| test4.cpp:13:7:13:20 | access to array | $@ flows an expression which might overflow negatively. | test4.cpp:8:27:8:30 | argv indirection | a command-line argument |
+| test5.cpp:10:9:10:27 | call to strtoul | $@ flows an expression which might overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
+| test5.cpp:17:6:17:27 | ... * ... | $@ flows an expression which might overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
+| test5.cpp:19:6:19:13 | ... * ... | $@ flows an expression which might overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
+| test6.cpp:11:10:11:15 | s | $@ flows an expression which might overflow. | test6.cpp:39:23:39:24 | fscanf output argument | value read by fscanf |
+| test6.cpp:16:10:16:15 | s | $@ flows an expression which might overflow. | test6.cpp:39:23:39:24 | fscanf output argument | value read by fscanf |
+| test6.cpp:30:11:30:16 | s | $@ flows an expression which might overflow. | test6.cpp:39:23:39:24 | fscanf output argument | value read by fscanf |
+| test.c:14:15:14:35 | ... * ... | $@ flows an expression which might overflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
+| test.c:14:15:14:35 | ... * ... | $@ flows an expression which might overflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
+| test.c:44:7:44:12 | ... -- | $@ flows an expression which might overflow negatively. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
+| test.c:44:7:44:12 | ... -- | $@ flows an expression which might overflow negatively. | test.c:10:27:10:30 | argv indirection | a command-line argument |
+| test.c:54:7:54:12 | ... -- | $@ flows an expression which might overflow negatively. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
+| test.c:54:7:54:12 | ... -- | $@ flows an expression which might overflow negatively. | test.c:10:27:10:30 | argv indirection | a command-line argument |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-197/SAMATE/IntegerOverflowTainted/IntegerOverflowTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-197/SAMATE/IntegerOverflowTainted/IntegerOverflowTainted.expected
index 9965c10070d..cb31529859e 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-197/SAMATE/IntegerOverflowTainted/IntegerOverflowTainted.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-197/SAMATE/IntegerOverflowTainted/IntegerOverflowTainted.expected
@@ -1 +1 @@
-| tests.cpp:38:31:38:34 | data | $@ flows an expression which might overflow. | tests.cpp:57:27:57:31 | & ... | User-provided value |
+| tests.cpp:38:25:38:34 | data | $@ flows an expression which might overflow. | tests.cpp:57:27:57:31 | fscanf output argument | value read by fscanf |