mirror of
https://github.com/github/codeql.git
synced 2026-02-11 20:51:06 +01:00
Merge remote-tracking branch 'upstream/main' into mathiasvp/replace-ast-with-ir-use-usedataflow
This commit is contained in:
@@ -26,9 +26,10 @@ runs:
|
||||
echo "merge_base=$MERGE_BASE" >> $GITHUB_ENV
|
||||
- name: Read CodeQL query compilation - PR
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
uses: actions/cache@v3
|
||||
uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6
|
||||
with:
|
||||
path: '**/.cache'
|
||||
read-only: true
|
||||
key: codeql-compile-${{ inputs.key }}-pr-${{ github.sha }} # deliberately not using the `compile-compile-main` keys here.
|
||||
restore-keys: |
|
||||
codeql-compile-${{ inputs.key }}-${{ github.base_ref }}-${{ env.merge_base }}
|
||||
@@ -36,7 +37,7 @@ runs:
|
||||
codeql-compile-${{ inputs.key }}-main-
|
||||
- name: Fill CodeQL query compilation cache - main
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
uses: actions/cache@v3
|
||||
uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6
|
||||
with:
|
||||
path: '**/.cache'
|
||||
key: codeql-compile-${{ inputs.key }}-${{ github.ref_name }}-${{ github.sha }} # just fill on main
|
||||
|
||||
72
.github/workflows/csharp-qltest.yml
vendored
Normal file
72
.github/workflows/csharp-qltest.yml
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
name: "C#: Run QL Tests"
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- "csharp/**"
|
||||
- "shared/**"
|
||||
- .github/actions/fetch-codeql/action.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
- "rc/*"
|
||||
pull_request:
|
||||
paths:
|
||||
- "csharp/**"
|
||||
- "shared/**"
|
||||
- .github/workflows/csharp-qltest.yml
|
||||
- .github/actions/fetch-codeql/action.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
- "rc/*"
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: csharp
|
||||
|
||||
jobs:
|
||||
qlupgrade:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/actions/fetch-codeql
|
||||
- name: Check DB upgrade scripts
|
||||
run: |
|
||||
echo >empty.trap
|
||||
codeql dataset import -S ql/lib/upgrades/initial/semmlecode.csharp.dbscheme testdb empty.trap
|
||||
codeql dataset upgrade testdb --additional-packs ql/lib
|
||||
diff -q testdb/semmlecode.csharp.dbscheme ql/lib/semmlecode.csharp.dbscheme
|
||||
- name: Check DB downgrade scripts
|
||||
run: |
|
||||
echo >empty.trap
|
||||
rm -rf testdb; codeql dataset import -S ql/lib/semmlecode.csharp.dbscheme testdb empty.trap
|
||||
codeql resolve upgrades --format=lines --allow-downgrades --additional-packs downgrades \
|
||||
--dbscheme=ql/lib/semmlecode.csharp.dbscheme --target-dbscheme=downgrades/initial/semmlecode.csharp.dbscheme |
|
||||
xargs codeql execute upgrades testdb
|
||||
diff -q testdb/semmlecode.csharp.dbscheme downgrades/initial/semmlecode.csharp.dbscheme
|
||||
qltest:
|
||||
runs-on: ubuntu-latest-xl
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
slice: ["1/2", "2/2"]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/actions/fetch-codeql
|
||||
- uses: ./csharp/actions/create-extractor-pack
|
||||
- name: Cache compilation cache
|
||||
id: query-cache
|
||||
uses: ./.github/actions/cache-query-compilation
|
||||
with:
|
||||
key: csharp-qltest-${{ matrix.slice }}
|
||||
- name: Run QL tests
|
||||
run: |
|
||||
CODEQL_PATH=$(gh codeql version --format=json | jq -r .unpackedLocation)
|
||||
# The legacy ASP extractor is not in this repo, so take the one from the nightly build
|
||||
mv "$CODEQL_PATH/csharp/tools/extractor-asp.jar" "${{ github.workspace }}/csharp/extractor-pack/tools"
|
||||
# Safe guard against using the bundled extractor
|
||||
rm -rf "$CODEQL_PATH/csharp"
|
||||
codeql test run --threads=0 --ram 52000 --slice ${{ matrix.slice }} --search-path "${{ github.workspace }}/csharp/extractor-pack" --check-databases --check-undefined-labels --check-repeated-labels --check-redefined-labels --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
1
.github/workflows/ruby-build.yml
vendored
1
.github/workflows/ruby-build.yml
vendored
@@ -98,6 +98,7 @@ jobs:
|
||||
key: ruby-build
|
||||
- name: Build Query Pack
|
||||
run: |
|
||||
rm -rf target/packs
|
||||
codeql pack create ../shared/ssa --output target/packs
|
||||
codeql pack create ../misc/suite-helpers --output target/packs
|
||||
codeql pack create ../shared/regex --output target/packs
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -27,8 +27,6 @@
|
||||
# It's useful (though not required) to be able to unpack codeql in the ql checkout itself
|
||||
/codeql/
|
||||
|
||||
csharp/extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json
|
||||
|
||||
# Avoid committing cached package components
|
||||
.codeql
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/javascript/ @github/codeql-javascript
|
||||
/python/ @github/codeql-python
|
||||
/ruby/ @github/codeql-ruby
|
||||
/swift/ @github/codeql-c
|
||||
/swift/ @github/codeql-swift
|
||||
/java/kotlin-extractor/ @github/codeql-kotlin
|
||||
/java/kotlin-explorer/ @github/codeql-kotlin
|
||||
|
||||
@@ -45,4 +45,4 @@ WORKSPACE.bazel @github/codeql-ci-reviewers
|
||||
/.github/workflows/js-ml-tests.yml @github/codeql-ml-powered-queries-reviewers
|
||||
/.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers
|
||||
/.github/workflows/ruby-* @github/codeql-ruby
|
||||
/.github/workflows/swift.yml @github/codeql-c
|
||||
/.github/workflows/swift.yml @github/codeql-swift
|
||||
|
||||
5
csharp/.gitignore
vendored
5
csharp/.gitignore
vendored
@@ -11,4 +11,7 @@ csharp.log
|
||||
*.tlog
|
||||
.vs
|
||||
*.user
|
||||
.vscode/launch.json
|
||||
.vscode/launch.json
|
||||
|
||||
extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json
|
||||
extractor-pack
|
||||
13
csharp/actions/create-extractor-pack/action.yml
Normal file
13
csharp/actions/create-extractor-pack/action.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
name: Build C# CodeQL pack
|
||||
description: Builds the C# CodeQL pack
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: 6.0.202
|
||||
- name: Build Extractor
|
||||
shell: bash
|
||||
run: scripts/create-extractor-pack.sh
|
||||
working-directory: csharp
|
||||
@@ -103,7 +103,6 @@ abstract class Completion extends TCompletion {
|
||||
* otherwise it is a normal non-Boolean completion.
|
||||
*/
|
||||
predicate isValidFor(ControlFlowElement cfe) {
|
||||
cfe instanceof NonReturningCall and
|
||||
this = cfe.(NonReturningCall).getACompletion()
|
||||
or
|
||||
this = TThrowCompletion(cfe.(TriedControlFlowElement).getAThrownException())
|
||||
|
||||
@@ -10,26 +10,26 @@ private predicate trivialPositiveIntValue(string s) {
|
||||
s =
|
||||
[
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16",
|
||||
"17", "18", "19", "20", "16", "32", "64", "128", "256", "512", "1024", "2048", "4096",
|
||||
"16384", "32768", "65536", "1048576", "2147483648", "4294967296", "15", "31", "63", "127",
|
||||
"255", "511", "1023", "2047", "4095", "16383", "32767", "65535", "1048577", "2147483647",
|
||||
"4294967295", "0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010",
|
||||
"0x00000020", "0x00000040", "0x00000080", "0x00000100", "0x00000200", "0x00000400",
|
||||
"0x00000800", "0x00001000", "0x00002000", "0x00004000", "0x00008000", "0x00010000",
|
||||
"0x00020000", "0x00040000", "0x00080000", "0x00100000", "0x00200000", "0x00400000",
|
||||
"0x00800000", "0x01000000", "0x02000000", "0x04000000", "0x08000000", "0x10000000",
|
||||
"0x20000000", "0x40000000", "0x80000000", "0x00000001", "0x00000003", "0x00000007",
|
||||
"0x0000000f", "0x0000001f", "0x0000003f", "0x0000007f", "0x000000ff", "0x000001ff",
|
||||
"0x000003ff", "0x000007ff", "0x00000fff", "0x00001fff", "0x00003fff", "0x00007fff",
|
||||
"0x0000ffff", "0x0001ffff", "0x0003ffff", "0x0007ffff", "0x000fffff", "0x001fffff",
|
||||
"0x003fffff", "0x007fffff", "0x00ffffff", "0x01ffffff", "0x03ffffff", "0x07ffffff",
|
||||
"0x0fffffff", "0x1fffffff", "0x3fffffff", "0x7fffffff", "0xffffffff", "0x0001", "0x0002",
|
||||
"0x0004", "0x0008", "0x0010", "0x0020", "0x0040", "0x0080", "0x0100", "0x0200", "0x0400",
|
||||
"0x0800", "0x1000", "0x2000", "0x4000", "0x8000", "0x0001", "0x0003", "0x0007", "0x000f",
|
||||
"0x001f", "0x003f", "0x007f", "0x00ff", "0x01ff", "0x03ff", "0x07ff", "0x0fff", "0x1fff",
|
||||
"0x3fff", "0x7fff", "0xffff", "0x01", "0x02", "0x04", "0x08", "0x10", "0x20", "0x40", "0x80",
|
||||
"0x01", "0x03", "0x07", "0x0f", "0x1f", "0x3f", "0x7f", "0xff", "0x00", "10", "100", "1000",
|
||||
"10000", "100000", "1000000", "10000000", "100000000", "1000000000"
|
||||
"17", "18", "19", "20", "32", "64", "128", "256", "512", "1024", "2048", "4096", "16384",
|
||||
"32768", "65536", "1048576", "2147483648", "4294967296", "31", "63", "127", "255", "511",
|
||||
"1023", "2047", "4095", "16383", "32767", "65535", "1048577", "2147483647", "4294967295",
|
||||
"0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010", "0x00000020",
|
||||
"0x00000040", "0x00000080", "0x00000100", "0x00000200", "0x00000400", "0x00000800",
|
||||
"0x00001000", "0x00002000", "0x00004000", "0x00008000", "0x00010000", "0x00020000",
|
||||
"0x00040000", "0x00080000", "0x00100000", "0x00200000", "0x00400000", "0x00800000",
|
||||
"0x01000000", "0x02000000", "0x04000000", "0x08000000", "0x10000000", "0x20000000",
|
||||
"0x40000000", "0x80000000", "0x00000003", "0x00000007", "0x0000000f", "0x0000001f",
|
||||
"0x0000003f", "0x0000007f", "0x000000ff", "0x000001ff", "0x000003ff", "0x000007ff",
|
||||
"0x00000fff", "0x00001fff", "0x00003fff", "0x00007fff", "0x0000ffff", "0x0001ffff",
|
||||
"0x0003ffff", "0x0007ffff", "0x000fffff", "0x001fffff", "0x003fffff", "0x007fffff",
|
||||
"0x00ffffff", "0x01ffffff", "0x03ffffff", "0x07ffffff", "0x0fffffff", "0x1fffffff",
|
||||
"0x3fffffff", "0x7fffffff", "0xffffffff", "0x0001", "0x0002", "0x0004", "0x0008", "0x0010",
|
||||
"0x0020", "0x0040", "0x0080", "0x0100", "0x0200", "0x0400", "0x0800", "0x1000", "0x2000",
|
||||
"0x4000", "0x8000", "0x0003", "0x0007", "0x000f", "0x001f", "0x003f", "0x007f", "0x00ff",
|
||||
"0x01ff", "0x03ff", "0x07ff", "0x0fff", "0x1fff", "0x3fff", "0x7fff", "0xffff", "0x02",
|
||||
"0x04", "0x08", "0x10", "0x20", "0x40", "0x80", "0x01", "0x03", "0x07", "0x0f", "0x1f",
|
||||
"0x3f", "0x7f", "0xff", "0x00", "100", "1000", "10000", "100000", "1000000", "10000000",
|
||||
"100000000", "1000000000"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ where
|
||||
f.hasName("f") and
|
||||
g.hasName("g") and
|
||||
a.getDeclaringType() = class1 and
|
||||
a.getDeclaringType() = class1 and
|
||||
b.getDeclaringType() = class1 and
|
||||
c.getDeclaringType() = class1 and
|
||||
not exists(c.getParameter(0).getType().(KnownType)) and
|
||||
|
||||
27
csharp/scripts/create-extractor-pack.sh
Executable file
27
csharp/scripts/create-extractor-pack.sh
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
set -eux
|
||||
|
||||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
platform="linux64"
|
||||
dotnet_platform="linux-x64"
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
platform="osx64"
|
||||
dotnet_platform="osx-x64"
|
||||
else
|
||||
echo "Unknown OS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -rf extractor-pack
|
||||
mkdir -p extractor-pack
|
||||
mkdir -p extractor-pack/tools/${platform}
|
||||
|
||||
function dotnet_publish {
|
||||
dotnet publish --self-contained --configuration Release --runtime ${dotnet_platform} -p:RuntimeFrameworkVersion=6.0.4 $1 --output extractor-pack/tools/${platform}
|
||||
}
|
||||
|
||||
dotnet_publish extractor/Semmle.Extraction.CSharp.Standalone
|
||||
dotnet_publish extractor/Semmle.Extraction.CSharp.Driver
|
||||
dotnet_publish autobuilder/Semmle.Autobuild.CSharp
|
||||
|
||||
cp -r codeql-extractor.yml tools/* downgrades tools ql/lib/semmlecode.csharp.dbscheme ql/lib/semmlecode.csharp.dbscheme.stats extractor-pack/
|
||||
@@ -128,7 +128,7 @@ private class SafeUrlSink extends SafeUrlFlow::Sink {
|
||||
private class UnsafeFieldReadSanitizer extends SafeUrlFlow::SanitizerEdge {
|
||||
UnsafeFieldReadSanitizer() {
|
||||
exists(DataFlow::FieldReadNode frn, string name |
|
||||
name = ["User", "RawQuery", "Fragment", "User"] and
|
||||
name = ["User", "RawQuery", "Fragment"] and
|
||||
frn.getField().hasQualifiedName("net/url", "URL")
|
||||
|
|
||||
this = frn.getBase()
|
||||
|
||||
@@ -250,7 +250,6 @@ private class ContainerFlowSummaries extends SummaryModelCsv {
|
||||
"java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual",
|
||||
"java.util;Scanner;true;findInLine;;;Argument[-1];ReturnValue;taint;manual",
|
||||
"java.util;Scanner;true;findWithinHorizon;;;Argument[-1];ReturnValue;taint;manual",
|
||||
"java.util;Scanner;true;findWithinHorizon;;;Argument[-1];ReturnValue;taint;manual",
|
||||
"java.util;Scanner;true;next;;;Argument[-1];ReturnValue;taint;manual",
|
||||
"java.util;Scanner;true;nextBigDecimal;;;Argument[-1];ReturnValue;taint;manual",
|
||||
"java.util;Scanner;true;nextBigInteger;;;Argument[-1];ReturnValue;taint;manual",
|
||||
|
||||
@@ -56,7 +56,6 @@ private class SummaryModels extends SummaryModelCsv {
|
||||
"android.content;ContentValues;false;putAll;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual",
|
||||
"android.content;ContentResolver;true;acquireContentProviderClient;;;Argument[0];ReturnValue;taint;manual",
|
||||
"android.content;ContentResolver;true;acquireUnstableContentProviderClient;;;Argument[0];ReturnValue;taint;manual",
|
||||
"android.content;ContentResolver;true;acquireUnstableContentProviderClient;;;Argument[0];ReturnValue;taint;manual",
|
||||
"android.content;ContentResolver;true;applyBatch;;;Argument[1];ReturnValue;taint;manual",
|
||||
"android.content;ContentResolver;true;call;;;Argument[0];ReturnValue;taint;manual",
|
||||
"android.content;ContentResolver;true;canonicalize;;;Argument[0];ReturnValue;taint;manual",
|
||||
|
||||
@@ -503,7 +503,6 @@ private class GuavaCollectCsv extends SummaryModelCsv {
|
||||
"com.google.common.collect;Sets;false;filter;(SortedSet,Predicate);;Argument[0].Element;ReturnValue.Element;value;manual",
|
||||
"com.google.common.collect;Sets;false;intersection;(Set,Set);;Argument[0..1].Element;ReturnValue.Element;value;manual",
|
||||
"com.google.common.collect;Sets;false;newConcurrentHashSet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual",
|
||||
"com.google.common.collect;Sets;false;newConcurrentHashSet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual",
|
||||
"com.google.common.collect;Sets;false;newCopyOnWriteArraySet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual",
|
||||
"com.google.common.collect;Sets;false;newHashSet;(Iterable);;Argument[0].Element;ReturnValue.Element;value;manual",
|
||||
"com.google.common.collect;Sets;false;newHashSet;(Iterator);;Argument[0].Element;ReturnValue.Element;value;manual",
|
||||
|
||||
@@ -93,7 +93,6 @@ private class GuavaIoSinkCsv extends SinkModelCsv {
|
||||
"com.google.common.io;Resources;false;asByteSource;(URL);;Argument[0];url-open-stream;manual",
|
||||
"com.google.common.io;Resources;false;asCharSource;(URL,Charset);;Argument[0];url-open-stream;manual",
|
||||
"com.google.common.io;Resources;false;copy;(URL,OutputStream);;Argument[0];url-open-stream;manual",
|
||||
"com.google.common.io;Resources;false;asByteSource;(URL);;Argument[0];url-open-stream;manual",
|
||||
"com.google.common.io;Resources;false;readLines;;;Argument[0];url-open-stream;manual",
|
||||
"com.google.common.io;Resources;false;toByteArray;(URL);;Argument[0];url-open-stream;manual",
|
||||
"com.google.common.io;Resources;false;toString;(URL,Charset);;Argument[0];url-open-stream;manual"
|
||||
|
||||
@@ -85,9 +85,11 @@ private class MutablePendingIntentFlowStep extends ImplicitPendingIntentAddition
|
||||
// unless it is at least sometimes explicitly marked immutable and never marked mutable.
|
||||
// Note: for API level < 31, PendingIntents were mutable by default, whereas since then
|
||||
// they are immutable by default.
|
||||
not TaintTracking::localExprTaint(any(ImmutablePendingIntentFlag flag).getAnAccess(), flagArg)
|
||||
not bitwiseLocalTaintStep*(DataFlow::exprNode(any(ImmutablePendingIntentFlag flag)
|
||||
.getAnAccess()), DataFlow::exprNode(flagArg))
|
||||
or
|
||||
TaintTracking::localExprTaint(any(MutablePendingIntentFlag flag).getAnAccess(), flagArg)
|
||||
bitwiseLocalTaintStep*(DataFlow::exprNode(any(MutablePendingIntentFlag flag).getAnAccess()),
|
||||
DataFlow::exprNode(flagArg))
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -124,3 +126,12 @@ private class PendingIntentSentSinkModels extends SinkModelCsv {
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if taint can flow from `source` to `sink` in one local step,
|
||||
* including bitwise operations.
|
||||
*/
|
||||
private predicate bitwiseLocalTaintStep(DataFlow::Node source, DataFlow::Node sink) {
|
||||
TaintTracking::localTaintStep(source, sink) or
|
||||
source.asExpr() = sink.asExpr().(BitwiseExpr).(BinaryExpr).getAnOperand()
|
||||
}
|
||||
|
||||
@@ -8,26 +8,26 @@ private predicate trivialPositiveIntValue(string s) {
|
||||
s =
|
||||
[
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16",
|
||||
"17", "18", "19", "20", "16", "32", "64", "128", "256", "512", "1024", "2048", "4096",
|
||||
"16384", "32768", "65536", "1048576", "2147483648", "4294967296", "15", "31", "63", "127",
|
||||
"255", "511", "1023", "2047", "4095", "16383", "32767", "65535", "1048577", "2147483647",
|
||||
"4294967295", "0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010",
|
||||
"0x00000020", "0x00000040", "0x00000080", "0x00000100", "0x00000200", "0x00000400",
|
||||
"0x00000800", "0x00001000", "0x00002000", "0x00004000", "0x00008000", "0x00010000",
|
||||
"0x00020000", "0x00040000", "0x00080000", "0x00100000", "0x00200000", "0x00400000",
|
||||
"0x00800000", "0x01000000", "0x02000000", "0x04000000", "0x08000000", "0x10000000",
|
||||
"0x20000000", "0x40000000", "0x80000000", "0x00000001", "0x00000003", "0x00000007",
|
||||
"0x0000000f", "0x0000001f", "0x0000003f", "0x0000007f", "0x000000ff", "0x000001ff",
|
||||
"0x000003ff", "0x000007ff", "0x00000fff", "0x00001fff", "0x00003fff", "0x00007fff",
|
||||
"0x0000ffff", "0x0001ffff", "0x0003ffff", "0x0007ffff", "0x000fffff", "0x001fffff",
|
||||
"0x003fffff", "0x007fffff", "0x00ffffff", "0x01ffffff", "0x03ffffff", "0x07ffffff",
|
||||
"0x0fffffff", "0x1fffffff", "0x3fffffff", "0x7fffffff", "0xffffffff", "0x0001", "0x0002",
|
||||
"0x0004", "0x0008", "0x0010", "0x0020", "0x0040", "0x0080", "0x0100", "0x0200", "0x0400",
|
||||
"0x0800", "0x1000", "0x2000", "0x4000", "0x8000", "0x0001", "0x0003", "0x0007", "0x000f",
|
||||
"0x001f", "0x003f", "0x007f", "0x00ff", "0x01ff", "0x03ff", "0x07ff", "0x0fff", "0x1fff",
|
||||
"0x3fff", "0x7fff", "0xffff", "0x01", "0x02", "0x04", "0x08", "0x10", "0x20", "0x40", "0x80",
|
||||
"0x01", "0x03", "0x07", "0x0f", "0x1f", "0x3f", "0x7f", "0xff", "0x00", "10", "100", "1000",
|
||||
"10000", "100000", "1000000", "10000000", "100000000", "1000000000"
|
||||
"17", "18", "19", "20", "32", "64", "128", "256", "512", "1024", "2048", "4096", "16384",
|
||||
"32768", "65536", "1048576", "2147483648", "4294967296", "31", "63", "127", "255", "511",
|
||||
"1023", "2047", "4095", "16383", "32767", "65535", "1048577", "2147483647", "4294967295",
|
||||
"0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010", "0x00000020",
|
||||
"0x00000040", "0x00000080", "0x00000100", "0x00000200", "0x00000400", "0x00000800",
|
||||
"0x00001000", "0x00002000", "0x00004000", "0x00008000", "0x00010000", "0x00020000",
|
||||
"0x00040000", "0x00080000", "0x00100000", "0x00200000", "0x00400000", "0x00800000",
|
||||
"0x01000000", "0x02000000", "0x04000000", "0x08000000", "0x10000000", "0x20000000",
|
||||
"0x40000000", "0x80000000", "0x00000003", "0x00000007", "0x0000000f", "0x0000001f",
|
||||
"0x0000003f", "0x0000007f", "0x000000ff", "0x000001ff", "0x000003ff", "0x000007ff",
|
||||
"0x00000fff", "0x00001fff", "0x00003fff", "0x00007fff", "0x0000ffff", "0x0001ffff",
|
||||
"0x0003ffff", "0x0007ffff", "0x000fffff", "0x001fffff", "0x003fffff", "0x007fffff",
|
||||
"0x00ffffff", "0x01ffffff", "0x03ffffff", "0x07ffffff", "0x0fffffff", "0x1fffffff",
|
||||
"0x3fffffff", "0x7fffffff", "0xffffffff", "0x0001", "0x0002", "0x0004", "0x0008", "0x0010",
|
||||
"0x0020", "0x0040", "0x0080", "0x0100", "0x0200", "0x0400", "0x0800", "0x1000", "0x2000",
|
||||
"0x4000", "0x8000", "0x0003", "0x0007", "0x000f", "0x001f", "0x003f", "0x007f", "0x00ff",
|
||||
"0x01ff", "0x03ff", "0x07ff", "0x0fff", "0x1fff", "0x3fff", "0x7fff", "0xffff", "0x01",
|
||||
"0x02", "0x04", "0x08", "0x10", "0x20", "0x40", "0x80", "0x03", "0x07", "0x0f", "0x1f",
|
||||
"0x3f", "0x7f", "0xff", "0x00", "100", "1000", "10000", "100000", "1000000", "10000000",
|
||||
"100000000", "1000000000"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Fixed an issue in the query `java/android/implicit-pendingintents` by which an implicit Pending Intent marked as immutable was not correctly recognized as such.
|
||||
@@ -156,7 +156,7 @@ public class ImplicitPendingIntentsTest {
|
||||
PendingIntent pi = PendingIntent.getActivity(ctx, 0, baseIntent, flag); // Sanitizer
|
||||
Intent fwdIntent = new Intent();
|
||||
fwdIntent.putExtra("fwdIntent", pi);
|
||||
ctx.startActivity(fwdIntent); // $ SPURIOUS: $ hasImplicitPendingIntent
|
||||
ctx.startActivity(fwdIntent); // Safe
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ private module Redis {
|
||||
"set", "publish", "append", "bitfield", "decrby", "getset", "hincrby", "hincrbyfloat",
|
||||
"hset", "hsetnx", "incrby", "incrbyfloat", "linsert", "lpush", "lpushx", "lset", "ltrim",
|
||||
"rename", "renamenx", "rpushx", "setbit", "setex", "smove", "zincrby", "zinterstore",
|
||||
"hdel", "lpush", "pfadd", "rpush", "sadd", "sdiffstore", "srem"
|
||||
"hdel", "pfadd", "rpush", "sadd", "sdiffstore", "srem"
|
||||
] and
|
||||
argIndex = 0
|
||||
or
|
||||
|
||||
@@ -122,10 +122,10 @@ module LoopBoundInjection {
|
||||
"flattenDeep", "flattenDepth", "initial", "intersection", "intersectionBy",
|
||||
"intersectionWith", "join", "remove", "reverse", "slice", "sortedUniq", "sortedUniqBy",
|
||||
"tail", "union", "unionBy", "unionWith", "uniqBy", "unzip", "unzipWith", "without", "zip",
|
||||
"zipObject", "zipObjectDeep", "zipWith", "countBy", "each", "forEach", "eachRight",
|
||||
"forEachRight", "filter", "find", "findLast", "flatMap", "flatMapDeep", "flatMapDepth",
|
||||
"forEach", "forEachRight", "groupBy", "invokeMap", "keyBy", "map", "orderBy", "partition",
|
||||
"reduce", "reduceRight", "reject", "sortBy"
|
||||
"zipObject", "zipObjectDeep", "zipWith", "countBy", "each", "eachRight", "forEachRight",
|
||||
"filter", "find", "findLast", "flatMap", "flatMapDeep", "flatMapDepth", "forEach",
|
||||
"groupBy", "invokeMap", "keyBy", "map", "orderBy", "partition", "reduce", "reduceRight",
|
||||
"reject", "sortBy"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -156,14 +156,9 @@ module UnsafeShellCommandConstruction {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a node that ends up in an array that is ultimately executed as a shell script by `sys`.
|
||||
* Holds if the arguments array given to `sys` is joined as a string because `shell` is set to true.
|
||||
*/
|
||||
private DataFlow::SourceNode endsInShellExecutedArray(
|
||||
DataFlow::TypeBackTracker t, SystemCommandExecution sys
|
||||
) {
|
||||
t.start() and
|
||||
result = sys.getArgumentList().getALocalSource() and
|
||||
// the array gets joined to a string when `shell` is set to true.
|
||||
predicate executesArrayAsShell(SystemCommandExecution sys) {
|
||||
sys.getOptionsArg()
|
||||
.getALocalSource()
|
||||
.getAPropertyWrite("shell")
|
||||
@@ -171,6 +166,17 @@ module UnsafeShellCommandConstruction {
|
||||
.asExpr()
|
||||
.(BooleanLiteral)
|
||||
.getValue() = "true"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a node that ends up in an array that is ultimately executed as a shell script by `sys`.
|
||||
*/
|
||||
private DataFlow::SourceNode endsInShellExecutedArray(
|
||||
DataFlow::TypeBackTracker t, SystemCommandExecution sys
|
||||
) {
|
||||
t.start() and
|
||||
result = sys.getArgumentList().getALocalSource() and
|
||||
executesArrayAsShell(sys)
|
||||
or
|
||||
exists(DataFlow::TypeBackTracker t2 |
|
||||
result = endsInShellExecutedArray(t2, sys).backtrack(t2, t)
|
||||
@@ -193,6 +199,10 @@ module UnsafeShellCommandConstruction {
|
||||
or
|
||||
this = arr.getAMethodCall(["push", "unshift"]).getAnArgument()
|
||||
)
|
||||
or
|
||||
this = sys.getArgumentList() and
|
||||
not this instanceof DataFlow::ArrayCreationNode and
|
||||
executesArrayAsShell(sys)
|
||||
}
|
||||
|
||||
override string getSinkType() { result = "shell argument" }
|
||||
|
||||
@@ -90,7 +90,8 @@ module PolynomialReDoS {
|
||||
isCharClassLike(root)
|
||||
)
|
||||
or
|
||||
this.(DataFlow::MethodCallNode).getMethodName() = StringOps::substringMethodName()
|
||||
this.(DataFlow::MethodCallNode).getMethodName() = StringOps::substringMethodName() and
|
||||
not this.(DataFlow::MethodCallNode).getNumArgument() = 1 // with one argument it just slices off the beginning
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -227,8 +227,14 @@ nodes
|
||||
| lib/lib.js:420:29:420:32 | name |
|
||||
| lib/lib.js:424:24:424:27 | name |
|
||||
| lib/lib.js:424:24:424:27 | name |
|
||||
| lib/lib.js:425:6:425:13 | arr |
|
||||
| lib/lib.js:425:12:425:13 | [] |
|
||||
| lib/lib.js:426:11:426:14 | name |
|
||||
| lib/lib.js:426:11:426:14 | name |
|
||||
| lib/lib.js:427:14:427:16 | arr |
|
||||
| lib/lib.js:427:14:427:16 | arr |
|
||||
| lib/lib.js:428:14:428:58 | build(" ... + '-') |
|
||||
| lib/lib.js:428:14:428:58 | build(" ... + '-') |
|
||||
| lib/lib.js:428:28:428:51 | (name ? ... ' : '') |
|
||||
| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' |
|
||||
| lib/lib.js:428:29:428:50 | name ? ... :' : '' |
|
||||
@@ -306,6 +312,10 @@ nodes
|
||||
| lib/subLib/index.js:7:32:7:35 | name |
|
||||
| lib/subLib/index.js:8:22:8:25 | name |
|
||||
| lib/subLib/index.js:8:22:8:25 | name |
|
||||
| lib/subLib/index.js:13:44:13:46 | arr |
|
||||
| lib/subLib/index.js:13:44:13:46 | arr |
|
||||
| lib/subLib/index.js:14:22:14:24 | arr |
|
||||
| lib/subLib/index.js:14:22:14:24 | arr |
|
||||
edges
|
||||
| lib/isImported.js:5:49:5:52 | name | lib/isImported.js:6:22:6:25 | name |
|
||||
| lib/isImported.js:5:49:5:52 | name | lib/isImported.js:6:22:6:25 | name |
|
||||
@@ -584,7 +594,13 @@ edges
|
||||
| lib/lib.js:414:40:414:43 | name | lib/lib.js:426:11:426:14 | name |
|
||||
| lib/lib.js:414:40:414:43 | name | lib/lib.js:428:36:428:39 | name |
|
||||
| lib/lib.js:414:40:414:43 | name | lib/lib.js:428:36:428:39 | name |
|
||||
| lib/lib.js:425:6:425:13 | arr | lib/lib.js:427:14:427:16 | arr |
|
||||
| lib/lib.js:425:6:425:13 | arr | lib/lib.js:427:14:427:16 | arr |
|
||||
| lib/lib.js:425:12:425:13 | [] | lib/lib.js:425:6:425:13 | arr |
|
||||
| lib/lib.js:426:11:426:14 | name | lib/lib.js:425:12:425:13 | [] |
|
||||
| lib/lib.js:428:28:428:51 | (name ? ... ' : '') | lib/lib.js:428:28:428:57 | (name ? ... ) + '-' |
|
||||
| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:428:14:428:58 | build(" ... + '-') |
|
||||
| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:428:14:428:58 | build(" ... + '-') |
|
||||
| lib/lib.js:428:28:428:57 | (name ? ... ) + '-' | lib/lib.js:431:23:431:26 | last |
|
||||
| lib/lib.js:428:29:428:50 | name ? ... :' : '' | lib/lib.js:428:28:428:51 | (name ? ... ' : '') |
|
||||
| lib/lib.js:428:36:428:39 | name | lib/lib.js:428:36:428:45 | name + ':' |
|
||||
@@ -672,6 +688,10 @@ edges
|
||||
| lib/subLib/index.js:7:32:7:35 | name | lib/subLib/index.js:8:22:8:25 | name |
|
||||
| lib/subLib/index.js:7:32:7:35 | name | lib/subLib/index.js:8:22:8:25 | name |
|
||||
| lib/subLib/index.js:7:32:7:35 | name | lib/subLib/index.js:8:22:8:25 | name |
|
||||
| lib/subLib/index.js:13:44:13:46 | arr | lib/subLib/index.js:14:22:14:24 | arr |
|
||||
| lib/subLib/index.js:13:44:13:46 | arr | lib/subLib/index.js:14:22:14:24 | arr |
|
||||
| lib/subLib/index.js:13:44:13:46 | arr | lib/subLib/index.js:14:22:14:24 | arr |
|
||||
| lib/subLib/index.js:13:44:13:46 | arr | lib/subLib/index.js:14:22:14:24 | arr |
|
||||
#select
|
||||
| lib/isImported.js:6:10:6:25 | "rm -rf " + name | lib/isImported.js:5:49:5:52 | name | lib/isImported.js:6:22:6:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/isImported.js:5:49:5:52 | name | library input | lib/isImported.js:6:2:6:26 | cp.exec ... + name) | shell command |
|
||||
| lib/lib2.js:4:10:4:25 | "rm -rf " + name | lib/lib2.js:3:28:3:31 | name | lib/lib2.js:4:22:4:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib2.js:3:28:3:31 | name | library input | lib/lib2.js:4:2:4:26 | cp.exec ... + name) | shell command |
|
||||
@@ -739,6 +759,8 @@ edges
|
||||
| lib/lib.js:420:29:420:32 | name | lib/lib.js:414:40:414:43 | name | lib/lib.js:420:29:420:32 | name | This shell argument which depends on $@ is later used in a $@. | lib/lib.js:414:40:414:43 | name | library input | lib/lib.js:420:2:420:49 | cp.spaw ... true}) | shell command |
|
||||
| lib/lib.js:424:24:424:27 | name | lib/lib.js:414:40:414:43 | name | lib/lib.js:424:24:424:27 | name | This shell argument which depends on $@ is later used in a $@. | lib/lib.js:414:40:414:43 | name | library input | lib/lib.js:424:2:424:40 | spawn(" ... WN_OPT) | shell command |
|
||||
| lib/lib.js:426:11:426:14 | name | lib/lib.js:414:40:414:43 | name | lib/lib.js:426:11:426:14 | name | This shell argument which depends on $@ is later used in a $@. | lib/lib.js:414:40:414:43 | name | library input | lib/lib.js:427:2:427:28 | spawn(" ... WN_OPT) | shell command |
|
||||
| lib/lib.js:427:14:427:16 | arr | lib/lib.js:414:40:414:43 | name | lib/lib.js:427:14:427:16 | arr | This shell argument which depends on $@ is later used in a $@. | lib/lib.js:414:40:414:43 | name | library input | lib/lib.js:427:2:427:28 | spawn(" ... WN_OPT) | shell command |
|
||||
| lib/lib.js:428:14:428:58 | build(" ... + '-') | lib/lib.js:414:40:414:43 | name | lib/lib.js:428:14:428:58 | build(" ... + '-') | This shell argument which depends on $@ is later used in a $@. | lib/lib.js:414:40:414:43 | name | library input | lib/lib.js:428:2:428:70 | spawn(" ... WN_OPT) | shell command |
|
||||
| lib/lib.js:436:19:436:22 | last | lib/lib.js:414:40:414:43 | name | lib/lib.js:436:19:436:22 | last | This shell argument which depends on $@ is later used in a $@. | lib/lib.js:414:40:414:43 | name | library input | lib/lib.js:428:2:428:70 | spawn(" ... WN_OPT) | shell command |
|
||||
| lib/lib.js:442:12:442:27 | "rm -rf " + name | lib/lib.js:441:39:441:42 | name | lib/lib.js:442:24:442:27 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:441:39:441:42 | name | library input | lib/lib.js:442:2:442:28 | asyncEx ... + name) | shell command |
|
||||
| lib/lib.js:447:13:447:28 | "rm -rf " + name | lib/lib.js:446:20:446:23 | name | lib/lib.js:447:25:447:28 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:446:20:446:23 | name | library input | lib/lib.js:447:3:447:29 | asyncEx ... + name) | shell command |
|
||||
@@ -760,3 +782,4 @@ edges
|
||||
| lib/subLib/amdSub.js:4:10:4:25 | "rm -rf " + name | lib/subLib/amdSub.js:3:28:3:31 | name | lib/subLib/amdSub.js:4:22:4:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/subLib/amdSub.js:3:28:3:31 | name | library input | lib/subLib/amdSub.js:4:2:4:26 | cp.exec ... + name) | shell command |
|
||||
| lib/subLib/index.js:4:10:4:25 | "rm -rf " + name | lib/subLib/index.js:3:28:3:31 | name | lib/subLib/index.js:4:22:4:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/subLib/index.js:3:28:3:31 | name | library input | lib/subLib/index.js:4:2:4:26 | cp.exec ... + name) | shell command |
|
||||
| lib/subLib/index.js:8:10:8:25 | "rm -rf " + name | lib/subLib/index.js:7:32:7:35 | name | lib/subLib/index.js:8:22:8:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/subLib/index.js:7:32:7:35 | name | library input | lib/subLib/index.js:8:2:8:26 | cp.exec ... + name) | shell command |
|
||||
| lib/subLib/index.js:14:22:14:24 | arr | lib/subLib/index.js:13:44:13:46 | arr | lib/subLib/index.js:14:22:14:24 | arr | This shell argument which depends on $@ is later used in a $@. | lib/subLib/index.js:13:44:13:46 | arr | library input | lib/subLib/index.js:14:5:14:40 | cp.spaw ... true}) | shell command |
|
||||
|
||||
@@ -8,4 +8,8 @@ module.exports.foo = function (name) {
|
||||
cp.exec("rm -rf " + name); // NOT OK - this is being called explicitly from child_process-test.js
|
||||
};
|
||||
|
||||
module.exports.amd = require("./amd.js");
|
||||
module.exports.amd = require("./amd.js");
|
||||
|
||||
module.exports.arrToShell = function (cmd, arr) {
|
||||
cp.spawn("echo", arr, {shell: true}); // NOT OK
|
||||
}
|
||||
@@ -33,6 +33,8 @@
|
||||
| lib/lib.js:8:3:8:4 | f* | Strings with many repetitions of 'f' can start matching anywhere after the start of the preceeding f*g |
|
||||
| lib/lib.js:28:3:28:4 | f* | Strings with many repetitions of 'f' can start matching anywhere after the start of the preceeding f*g |
|
||||
| lib/lib.js:36:3:36:4 | f* | Strings with many repetitions of 'f' can start matching anywhere after the start of the preceeding f*g |
|
||||
| lib/lib.js:42:29:42:30 | f* | Strings with many repetitions of 'f' can start matching anywhere after the start of the preceeding f*g |
|
||||
| lib/lib.js:45:29:45:30 | f* | Strings with many repetitions of 'f' can start matching anywhere after the start of the preceeding f*g |
|
||||
| lib/moduleLib/moduleLib.js:2:3:2:4 | a* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding a*b |
|
||||
| lib/otherLib/js/src/index.js:2:3:2:4 | a* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding a*b |
|
||||
| lib/snapdragon.js:7:28:7:29 | a* | Strings starting with 'a' and with many repetitions of 'a' can start matching anywhere after the start of the preceeding aa*$ |
|
||||
|
||||
@@ -28,6 +28,15 @@ nodes
|
||||
| lib/lib.js:35:28:35:31 | name |
|
||||
| lib/lib.js:36:13:36:16 | name |
|
||||
| lib/lib.js:36:13:36:16 | name |
|
||||
| lib/lib.js:41:32:41:35 | name |
|
||||
| lib/lib.js:41:32:41:35 | name |
|
||||
| lib/lib.js:42:17:42:20 | name |
|
||||
| lib/lib.js:42:17:42:20 | name |
|
||||
| lib/lib.js:44:5:44:25 | name |
|
||||
| lib/lib.js:44:12:44:15 | name |
|
||||
| lib/lib.js:44:12:44:25 | name.substr(1) |
|
||||
| lib/lib.js:45:17:45:20 | name |
|
||||
| lib/lib.js:45:17:45:20 | name |
|
||||
| lib/moduleLib/moduleLib.js:1:28:1:31 | name |
|
||||
| lib/moduleLib/moduleLib.js:1:28:1:31 | name |
|
||||
| lib/moduleLib/moduleLib.js:2:13:2:16 | name |
|
||||
@@ -249,6 +258,16 @@ edges
|
||||
| lib/lib.js:35:1:37:1 | 'arguments' object of function usedWithArguments | lib/lib.js:35:28:35:31 | name |
|
||||
| lib/lib.js:35:28:35:31 | name | lib/lib.js:36:13:36:16 | name |
|
||||
| lib/lib.js:35:28:35:31 | name | lib/lib.js:36:13:36:16 | name |
|
||||
| lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name |
|
||||
| lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name |
|
||||
| lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name |
|
||||
| lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name |
|
||||
| lib/lib.js:41:32:41:35 | name | lib/lib.js:44:12:44:15 | name |
|
||||
| lib/lib.js:41:32:41:35 | name | lib/lib.js:44:12:44:15 | name |
|
||||
| lib/lib.js:44:5:44:25 | name | lib/lib.js:45:17:45:20 | name |
|
||||
| lib/lib.js:44:5:44:25 | name | lib/lib.js:45:17:45:20 | name |
|
||||
| lib/lib.js:44:12:44:15 | name | lib/lib.js:44:12:44:25 | name.substr(1) |
|
||||
| lib/lib.js:44:12:44:25 | name.substr(1) | lib/lib.js:44:5:44:25 | name |
|
||||
| lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name |
|
||||
| lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name |
|
||||
| lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name |
|
||||
@@ -440,6 +459,8 @@ edges
|
||||
| lib/lib.js:4:2:4:18 | regexp.test(name) | lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'a'. | lib/lib.js:1:15:1:16 | a* | regular expression | lib/lib.js:3:28:3:31 | name | library input |
|
||||
| lib/lib.js:8:2:8:17 | /f*g/.test(name) | lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/lib.js:8:3:8:4 | f* | regular expression | lib/lib.js:7:19:7:22 | name | library input |
|
||||
| lib/lib.js:36:2:36:17 | /f*g/.test(name) | lib/lib.js:32:32:32:40 | arguments | lib/lib.js:36:13:36:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/lib.js:36:3:36:4 | f* | regular expression | lib/lib.js:32:32:32:40 | arguments | library input |
|
||||
| lib/lib.js:42:17:42:33 | name.match(/f*g/) | lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/lib.js:42:29:42:30 | f* | regular expression | lib/lib.js:41:32:41:35 | name | library input |
|
||||
| lib/lib.js:45:17:45:33 | name.match(/f*g/) | lib/lib.js:41:32:41:35 | name | lib/lib.js:45:17:45:20 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/lib.js:45:29:45:30 | f* | regular expression | lib/lib.js:41:32:41:35 | name | library input |
|
||||
| lib/moduleLib/moduleLib.js:2:2:2:17 | /a*b/.test(name) | lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'a'. | lib/moduleLib/moduleLib.js:2:3:2:4 | a* | regular expression | lib/moduleLib/moduleLib.js:1:28:1:31 | name | library input |
|
||||
| lib/otherLib/js/src/index.js:2:2:2:17 | /a*b/.test(name) | lib/otherLib/js/src/index.js:1:28:1:31 | name | lib/otherLib/js/src/index.js:2:13:2:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'a'. | lib/otherLib/js/src/index.js:2:3:2:4 | a* | regular expression | lib/otherLib/js/src/index.js:1:28:1:31 | name | library input |
|
||||
| lib/snapdragon.js:7:15:7:32 | this.match(/aa*$/) | lib/snapdragon.js:3:34:3:38 | input | lib/snapdragon.js:7:15:7:18 | this | This $@ that depends on $@ may run slow on strings starting with 'a' and with many repetitions of 'a'. | lib/snapdragon.js:7:28:7:29 | a* | regular expression | lib/snapdragon.js:3:34:3:38 | input | library input |
|
||||
|
||||
@@ -36,4 +36,11 @@ function usedWithArguments(name) {
|
||||
/f*g/.test(name); // NOT OK
|
||||
}
|
||||
|
||||
module.exports.snapdragon = require("./snapdragon")
|
||||
module.exports.snapdragon = require("./snapdragon")
|
||||
|
||||
module.exports.foo = function (name) {
|
||||
var data1 = name.match(/f*g/); // NOT OK
|
||||
|
||||
name = name.substr(1);
|
||||
var data2 = name.match(/f*g/); // NOT OK
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The data-flow library has been rewritten to no longer rely on the points-to analysis in order to
|
||||
resolve references to modules. Improvements in the module resolution can lead to more results.
|
||||
@@ -8,6 +8,7 @@ private import semmle.python.dataflow.new.DataFlow
|
||||
// Need to import `semmle.python.Frameworks` since frameworks can extend `SensitiveDataSource::Range`
|
||||
private import semmle.python.Frameworks
|
||||
private import semmle.python.security.internal.SensitiveDataHeuristics as SensitiveDataHeuristics
|
||||
private import semmle.python.ApiGraphs
|
||||
|
||||
// We export these explicitly, so we don't also export the `HeuristicNames` module.
|
||||
class SensitiveDataClassification = SensitiveDataHeuristics::SensitiveDataClassification;
|
||||
@@ -23,7 +24,17 @@ module SensitiveDataClassification = SensitiveDataHeuristics::SensitiveDataClass
|
||||
class SensitiveDataSource extends DataFlow::Node {
|
||||
SensitiveDataSource::Range range;
|
||||
|
||||
SensitiveDataSource() { this = range }
|
||||
SensitiveDataSource() {
|
||||
this = range and
|
||||
// ignore sensitive password sources in getpass.py, that can escape through `getpass.getpass()` return value,
|
||||
// since `getpass.getpass()` is considered a source itself.
|
||||
not exists(Module getpass |
|
||||
getpass.getName() = "getpass" and
|
||||
this.getScope().getEnclosingModule() = getpass and
|
||||
// do allow this call if we're analyzing getpass.py as part of CPython though
|
||||
not exists(getpass.getFile().getRelativePath())
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the classification of the sensitive data.
|
||||
@@ -312,6 +323,17 @@ private module SensitiveDataModeling {
|
||||
|
||||
override SensitiveDataClassification getClassification() { result = classification }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `getpass.getpass`, see https://docs.python.org/3.10/library/getpass.html#getpass.getpass
|
||||
*/
|
||||
class GetPassCall extends SensitiveDataSource::Range, API::CallNode {
|
||||
GetPassCall() { this = API::moduleImport("getpass").getMember("getpass").getACall() }
|
||||
|
||||
override SensitiveDataClassification getClassification() {
|
||||
result = SensitiveDataClassification::password()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
predicate sensitiveDataExtraStepForCalls = SensitiveDataModeling::extraStepForCalls/2;
|
||||
|
||||
4
python/ql/src/change-notes/2022-11-22-getpass.md
Normal file
4
python/ql/src/change-notes/2022-11-22-getpass.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added modeling of `getpass.getpass` as a source of passwords, which will be an additional source for `py/clear-text-logging-sensitive-data`, `py/clear-text-storage-sensitive-data`, and `py/weak-sensitive-data-hashing`.
|
||||
@@ -16,8 +16,9 @@ class DataFlowTest extends FlowTest {
|
||||
query predicate missingAnnotationOnSink(Location location, string error, string element) {
|
||||
error = "ERROR, you should add `# $ MISSING: flow` annotation" and
|
||||
exists(DataFlow::Node sink |
|
||||
any(TestConfiguration config).isSink(sink) and
|
||||
// note: we only care about `SINK` and not `SINK_F`, so we have to reconstruct manually.
|
||||
exists(DataFlow::CallCfgNode call |
|
||||
// note: we only care about `SINK` and not `SINK_F`, so we have to reconstruct manually.
|
||||
call.getFunction().asCfgNode().(NameNode).getId() = "SINK" and
|
||||
(sink = call.getArg(_) or sink = call.getArgByName(_))
|
||||
) and
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
| classes.py:14:17:14:60 | ControlFlowNode for Attribute() | classes.py:14:17:14:60 | ControlFlowNode for Attribute() |
|
||||
| classes.py:45:16:45:35 | ControlFlowNode for Attribute() | classes.py:45:16:45:35 | ControlFlowNode for Attribute() |
|
||||
| classes.py:60:17:60:27 | [pre objCreate] ControlFlowNode for With_init() | classes.py:54:18:54:21 | ControlFlowNode for self |
|
||||
| classes.py:242:9:242:24 | ControlFlowNode for set() | classes.py:242:9:242:24 | ControlFlowNode for set() |
|
||||
| classes.py:247:9:247:30 | ControlFlowNode for frozenset() | classes.py:247:9:247:30 | ControlFlowNode for frozenset() |
|
||||
| classes.py:252:9:252:28 | ControlFlowNode for dict() | classes.py:252:9:252:28 | ControlFlowNode for dict() |
|
||||
| classes.py:559:16:559:17 | ControlFlowNode for Str | classes.py:565:5:565:22 | ControlFlowNode for Subscript |
|
||||
| classes.py:565:5:565:16 | ControlFlowNode for with_getitem | classes.py:555:21:555:24 | ControlFlowNode for self |
|
||||
| classes.py:565:18:565:21 | ControlFlowNode for arg2 | classes.py:555:27:555:29 | ControlFlowNode for key |
|
||||
| classes.py:581:5:581:16 | ControlFlowNode for with_setitem | classes.py:570:21:570:24 | ControlFlowNode for self |
|
||||
| classes.py:581:18:581:21 | ControlFlowNode for arg2 | classes.py:570:27:570:29 | ControlFlowNode for key |
|
||||
| classes.py:581:26:581:29 | ControlFlowNode for arg3 | classes.py:570:32:570:36 | ControlFlowNode for value |
|
||||
| classes.py:595:9:595:20 | ControlFlowNode for with_delitem | classes.py:586:21:586:24 | ControlFlowNode for self |
|
||||
| classes.py:595:22:595:25 | ControlFlowNode for arg2 | classes.py:586:27:586:29 | ControlFlowNode for key |
|
||||
| classes.py:618:16:618:28 | ControlFlowNode for Attribute() | classes.py:618:16:618:28 | ControlFlowNode for Attribute() |
|
||||
| classes.py:659:15:659:18 | ControlFlowNode for self | classes.py:667:5:667:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:661:16:661:19 | ControlFlowNode for self | classes.py:667:5:667:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:667:5:667:12 | ControlFlowNode for with_add | classes.py:657:17:657:20 | ControlFlowNode for self |
|
||||
| classes.py:667:5:667:12 | ControlFlowNode for with_add | classes.py:667:5:667:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:667:16:667:19 | ControlFlowNode for arg2 | classes.py:657:23:657:27 | ControlFlowNode for other |
|
||||
| classes.py:674:15:674:18 | ControlFlowNode for self | classes.py:682:5:682:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:676:16:676:19 | ControlFlowNode for self | classes.py:682:5:682:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:682:5:682:12 | ControlFlowNode for with_sub | classes.py:672:17:672:20 | ControlFlowNode for self |
|
||||
| classes.py:682:5:682:12 | ControlFlowNode for with_sub | classes.py:682:5:682:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:682:16:682:19 | ControlFlowNode for arg2 | classes.py:672:23:672:27 | ControlFlowNode for other |
|
||||
| classes.py:689:15:689:18 | ControlFlowNode for self | classes.py:697:5:697:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:691:16:691:19 | ControlFlowNode for self | classes.py:697:5:697:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:697:5:697:12 | ControlFlowNode for with_mul | classes.py:687:17:687:20 | ControlFlowNode for self |
|
||||
| classes.py:697:5:697:12 | ControlFlowNode for with_mul | classes.py:697:5:697:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:697:16:697:19 | ControlFlowNode for arg2 | classes.py:687:23:687:27 | ControlFlowNode for other |
|
||||
| classes.py:704:15:704:18 | ControlFlowNode for self | classes.py:712:5:712:22 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:706:16:706:19 | ControlFlowNode for self | classes.py:712:5:712:22 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:712:5:712:15 | ControlFlowNode for with_matmul | classes.py:702:20:702:23 | ControlFlowNode for self |
|
||||
| classes.py:712:5:712:15 | ControlFlowNode for with_matmul | classes.py:712:5:712:22 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:712:19:712:22 | ControlFlowNode for arg2 | classes.py:702:26:702:30 | ControlFlowNode for other |
|
||||
| classes.py:719:15:719:18 | ControlFlowNode for self | classes.py:727:5:727:23 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:721:16:721:19 | ControlFlowNode for self | classes.py:727:5:727:23 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:727:5:727:16 | ControlFlowNode for with_truediv | classes.py:717:21:717:24 | ControlFlowNode for self |
|
||||
| classes.py:727:5:727:16 | ControlFlowNode for with_truediv | classes.py:727:5:727:23 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:727:20:727:23 | ControlFlowNode for arg2 | classes.py:717:27:717:31 | ControlFlowNode for other |
|
||||
| classes.py:734:15:734:18 | ControlFlowNode for self | classes.py:742:5:742:25 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:736:16:736:19 | ControlFlowNode for self | classes.py:742:5:742:25 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:742:5:742:17 | ControlFlowNode for with_floordiv | classes.py:732:22:732:25 | ControlFlowNode for self |
|
||||
| classes.py:742:5:742:17 | ControlFlowNode for with_floordiv | classes.py:742:5:742:25 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:742:22:742:25 | ControlFlowNode for arg2 | classes.py:732:28:732:32 | ControlFlowNode for other |
|
||||
| classes.py:749:15:749:18 | ControlFlowNode for self | classes.py:757:5:757:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:751:16:751:19 | ControlFlowNode for self | classes.py:757:5:757:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:757:5:757:12 | ControlFlowNode for with_mod | classes.py:747:17:747:20 | ControlFlowNode for self |
|
||||
| classes.py:757:5:757:12 | ControlFlowNode for with_mod | classes.py:757:5:757:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:757:16:757:19 | ControlFlowNode for arg2 | classes.py:747:23:747:27 | ControlFlowNode for other |
|
||||
| classes.py:779:15:779:18 | ControlFlowNode for self | classes.py:793:5:793:20 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:781:16:781:19 | ControlFlowNode for self | classes.py:793:5:793:20 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:793:5:793:12 | ControlFlowNode for with_pow | classes.py:777:17:777:20 | ControlFlowNode for self |
|
||||
| classes.py:793:5:793:12 | ControlFlowNode for with_pow | classes.py:793:5:793:20 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:793:17:793:20 | ControlFlowNode for arg2 | classes.py:777:23:777:27 | ControlFlowNode for other |
|
||||
| classes.py:800:15:800:18 | ControlFlowNode for self | classes.py:808:5:808:23 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:802:16:802:19 | ControlFlowNode for self | classes.py:808:5:808:23 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:808:5:808:15 | ControlFlowNode for with_lshift | classes.py:798:20:798:23 | ControlFlowNode for self |
|
||||
| classes.py:808:5:808:15 | ControlFlowNode for with_lshift | classes.py:808:5:808:23 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:808:20:808:23 | ControlFlowNode for arg2 | classes.py:798:26:798:30 | ControlFlowNode for other |
|
||||
| classes.py:815:15:815:18 | ControlFlowNode for self | classes.py:823:5:823:23 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:817:16:817:19 | ControlFlowNode for self | classes.py:823:5:823:23 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:823:5:823:15 | ControlFlowNode for with_rshift | classes.py:813:20:813:23 | ControlFlowNode for self |
|
||||
| classes.py:823:5:823:15 | ControlFlowNode for with_rshift | classes.py:823:5:823:23 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:823:20:823:23 | ControlFlowNode for arg2 | classes.py:813:26:813:30 | ControlFlowNode for other |
|
||||
| classes.py:830:15:830:18 | ControlFlowNode for self | classes.py:838:5:838:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:832:16:832:19 | ControlFlowNode for self | classes.py:838:5:838:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:838:5:838:12 | ControlFlowNode for with_and | classes.py:828:17:828:20 | ControlFlowNode for self |
|
||||
| classes.py:838:5:838:12 | ControlFlowNode for with_and | classes.py:838:5:838:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:838:16:838:19 | ControlFlowNode for arg2 | classes.py:828:23:828:27 | ControlFlowNode for other |
|
||||
| classes.py:845:15:845:18 | ControlFlowNode for self | classes.py:853:5:853:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:847:16:847:19 | ControlFlowNode for self | classes.py:853:5:853:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:853:5:853:12 | ControlFlowNode for with_xor | classes.py:843:17:843:20 | ControlFlowNode for self |
|
||||
| classes.py:853:5:853:12 | ControlFlowNode for with_xor | classes.py:853:5:853:19 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:853:16:853:19 | ControlFlowNode for arg2 | classes.py:843:23:843:27 | ControlFlowNode for other |
|
||||
| classes.py:860:15:860:18 | ControlFlowNode for self | classes.py:868:5:868:18 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:862:16:862:19 | ControlFlowNode for self | classes.py:868:5:868:18 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:868:5:868:11 | ControlFlowNode for with_or | classes.py:858:16:858:19 | ControlFlowNode for self |
|
||||
| classes.py:868:5:868:11 | ControlFlowNode for with_or | classes.py:868:5:868:18 | ControlFlowNode for BinaryExpr |
|
||||
| classes.py:868:15:868:18 | ControlFlowNode for arg2 | classes.py:858:22:858:26 | ControlFlowNode for other |
|
||||
@@ -1,37 +0,0 @@
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPrivate
|
||||
|
||||
/**
|
||||
* A configuration to find the call graph edges.
|
||||
*/
|
||||
class CallGraphConfig extends DataFlow::Configuration {
|
||||
CallGraphConfig() { this = "CallGraphConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node node) {
|
||||
node instanceof DataFlowPrivate::ReturnNode
|
||||
or
|
||||
// These sources should allow for the non-standard call syntax
|
||||
node instanceof DataFlow::ArgumentNode
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node node) {
|
||||
node instanceof DataFlowPrivate::OutNode
|
||||
or
|
||||
node instanceof DataFlow::ParameterNode and
|
||||
// exclude parameters to the SINK-functions
|
||||
not exists(DataFlowPrivate::DataFlowCallable c |
|
||||
c.getParameter(_) = node.asCfgNode() and
|
||||
c.getName().matches("SINK_")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from DataFlow::Node source, DataFlow::Node sink
|
||||
where
|
||||
source.getLocation().getFile().getBaseName() = "classes.py" and
|
||||
sink.getLocation().getFile().getBaseName() = "classes.py" and
|
||||
exists(CallGraphConfig cfg | cfg.hasFlow(source, sink))
|
||||
select source, sink
|
||||
// Ideally, we would just have 1-step paths either from argument to parameter
|
||||
// or from return to call. This gives a bit more, so should be rewritten.
|
||||
// We should also consider splitting this into two, one for each direction.
|
||||
@@ -1,970 +0,0 @@
|
||||
edges
|
||||
| datamodel.py:35:7:35:7 | ControlFlowNode for a | datamodel.py:36:10:36:10 | ControlFlowNode for a |
|
||||
| datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:35:7:35:7 | ControlFlowNode for a |
|
||||
| datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:38:6:38:17 | ControlFlowNode for f() |
|
||||
| datamodel.py:44:22:44:22 | ControlFlowNode for x | datamodel.py:46:16:46:16 | ControlFlowNode for x |
|
||||
| datamodel.py:49:26:49:26 | ControlFlowNode for x | datamodel.py:50:16:50:16 | ControlFlowNode for x |
|
||||
| datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:44:22:44:22 | ControlFlowNode for x |
|
||||
| datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:44:22:44:22 | ControlFlowNode for x |
|
||||
| datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:49:26:49:26 | ControlFlowNode for x |
|
||||
| datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:49:26:49:26 | ControlFlowNode for x |
|
||||
| datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:152:5:152:8 | [post store] ControlFlowNode for self [Attribute b] | datamodel.py:155:14:155:25 | ControlFlowNode for Customized() [Attribute b] |
|
||||
| datamodel.py:152:14:152:19 | ControlFlowNode for SOURCE | datamodel.py:152:5:152:8 | [post store] ControlFlowNode for self [Attribute b] |
|
||||
| datamodel.py:155:14:155:25 | ControlFlowNode for Customized() [Attribute b] | datamodel.py:159:6:159:15 | ControlFlowNode for customized [Attribute b] |
|
||||
| datamodel.py:159:6:159:15 | ControlFlowNode for customized [Attribute b] | datamodel.py:159:6:159:17 | ControlFlowNode for Attribute |
|
||||
| test.py:42:10:42:26 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:43:9:43:9 | ControlFlowNode for x [Tuple element at index 1] |
|
||||
| test.py:42:21:42:26 | ControlFlowNode for SOURCE | test.py:42:10:42:26 | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:43:9:43:9 | ControlFlowNode for x [Tuple element at index 1] | test.py:43:9:43:12 | ControlFlowNode for Subscript |
|
||||
| test.py:43:9:43:12 | ControlFlowNode for Subscript | test.py:44:10:44:10 | ControlFlowNode for y |
|
||||
| test.py:55:9:55:14 | ControlFlowNode for SOURCE | test.py:56:10:56:10 | ControlFlowNode for x |
|
||||
| test.py:61:9:61:16 | ControlFlowNode for Str | test.py:62:10:62:10 | ControlFlowNode for x |
|
||||
| test.py:66:9:66:17 | ControlFlowNode for Str | test.py:67:10:67:10 | ControlFlowNode for x |
|
||||
| test.py:71:9:71:10 | ControlFlowNode for IntegerLiteral | test.py:72:10:72:10 | ControlFlowNode for x |
|
||||
| test.py:76:9:76:12 | ControlFlowNode for FloatLiteral | test.py:77:10:77:10 | ControlFlowNode for x |
|
||||
| test.py:87:10:87:15 | ControlFlowNode for SOURCE | test.py:88:10:88:10 | ControlFlowNode for x |
|
||||
| test.py:93:9:93:16 | ControlFlowNode for List [List element] | test.py:94:10:94:10 | ControlFlowNode for x [List element] |
|
||||
| test.py:93:10:93:15 | ControlFlowNode for SOURCE | test.py:93:9:93:16 | ControlFlowNode for List [List element] |
|
||||
| test.py:94:10:94:10 | ControlFlowNode for x [List element] | test.py:94:10:94:13 | ControlFlowNode for Subscript |
|
||||
| test.py:103:9:103:37 | ControlFlowNode for ListComp [List element] | test.py:104:10:104:10 | ControlFlowNode for x [List element] |
|
||||
| test.py:103:10:103:15 | ControlFlowNode for SOURCE | test.py:103:9:103:37 | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:104:10:104:10 | ControlFlowNode for x [List element] | test.py:104:10:104:13 | ControlFlowNode for Subscript |
|
||||
| test.py:108:9:108:29 | ControlFlowNode for ListComp [List element] | test.py:109:10:109:10 | ControlFlowNode for x [List element] |
|
||||
| test.py:108:10:108:10 | ControlFlowNode for y | test.py:108:9:108:29 | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:108:16:108:16 | SSA variable y | test.py:108:10:108:10 | ControlFlowNode for y |
|
||||
| test.py:108:21:108:28 | ControlFlowNode for List [List element] | test.py:108:16:108:16 | SSA variable y |
|
||||
| test.py:108:22:108:27 | ControlFlowNode for SOURCE | test.py:108:21:108:28 | ControlFlowNode for List [List element] |
|
||||
| test.py:109:10:109:10 | ControlFlowNode for x [List element] | test.py:109:10:109:13 | ControlFlowNode for Subscript |
|
||||
| test.py:113:9:113:16 | ControlFlowNode for List [List element] | test.py:114:21:114:21 | ControlFlowNode for l [List element] |
|
||||
| test.py:113:10:113:15 | ControlFlowNode for SOURCE | test.py:113:9:113:16 | ControlFlowNode for List [List element] |
|
||||
| test.py:114:9:114:22 | ControlFlowNode for ListComp [List element] | test.py:115:10:115:10 | ControlFlowNode for x [List element] |
|
||||
| test.py:114:10:114:10 | ControlFlowNode for y | test.py:114:9:114:22 | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:114:16:114:16 | SSA variable y | test.py:114:10:114:10 | ControlFlowNode for y |
|
||||
| test.py:114:21:114:21 | ControlFlowNode for l [List element] | test.py:114:16:114:16 | SSA variable y |
|
||||
| test.py:115:10:115:10 | ControlFlowNode for x [List element] | test.py:115:10:115:13 | ControlFlowNode for Subscript |
|
||||
| test.py:125:9:125:16 | ControlFlowNode for Set [Set element] | test.py:126:10:126:10 | ControlFlowNode for x [Set element] |
|
||||
| test.py:125:10:125:15 | ControlFlowNode for SOURCE | test.py:125:9:125:16 | ControlFlowNode for Set [Set element] |
|
||||
| test.py:126:10:126:10 | ControlFlowNode for x [Set element] | test.py:126:10:126:16 | ControlFlowNode for Attribute() |
|
||||
| test.py:130:9:130:37 | ControlFlowNode for SetComp [Set element] | test.py:131:10:131:10 | ControlFlowNode for x [Set element] |
|
||||
| test.py:130:10:130:15 | ControlFlowNode for SOURCE | test.py:130:9:130:37 | ControlFlowNode for SetComp [Set element] |
|
||||
| test.py:131:10:131:10 | ControlFlowNode for x [Set element] | test.py:131:10:131:16 | ControlFlowNode for Attribute() |
|
||||
| test.py:135:9:135:29 | ControlFlowNode for SetComp [Set element] | test.py:136:10:136:10 | ControlFlowNode for x [Set element] |
|
||||
| test.py:135:10:135:10 | ControlFlowNode for y | test.py:135:9:135:29 | ControlFlowNode for SetComp [Set element] |
|
||||
| test.py:135:16:135:16 | SSA variable y | test.py:135:10:135:10 | ControlFlowNode for y |
|
||||
| test.py:135:21:135:28 | ControlFlowNode for List [List element] | test.py:135:16:135:16 | SSA variable y |
|
||||
| test.py:135:22:135:27 | ControlFlowNode for SOURCE | test.py:135:21:135:28 | ControlFlowNode for List [List element] |
|
||||
| test.py:136:10:136:10 | ControlFlowNode for x [Set element] | test.py:136:10:136:16 | ControlFlowNode for Attribute() |
|
||||
| test.py:140:9:140:16 | ControlFlowNode for Set [Set element] | test.py:141:21:141:21 | ControlFlowNode for l [Set element] |
|
||||
| test.py:140:10:140:15 | ControlFlowNode for SOURCE | test.py:140:9:140:16 | ControlFlowNode for Set [Set element] |
|
||||
| test.py:141:9:141:22 | ControlFlowNode for SetComp [Set element] | test.py:142:10:142:10 | ControlFlowNode for x [Set element] |
|
||||
| test.py:141:10:141:10 | ControlFlowNode for y | test.py:141:9:141:22 | ControlFlowNode for SetComp [Set element] |
|
||||
| test.py:141:16:141:16 | SSA variable y | test.py:141:10:141:10 | ControlFlowNode for y |
|
||||
| test.py:141:21:141:21 | ControlFlowNode for l [Set element] | test.py:141:16:141:16 | SSA variable y |
|
||||
| test.py:142:10:142:10 | ControlFlowNode for x [Set element] | test.py:142:10:142:16 | ControlFlowNode for Attribute() |
|
||||
| test.py:152:9:152:21 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:153:10:153:10 | ControlFlowNode for x [Dictionary element at key s] |
|
||||
| test.py:152:15:152:20 | ControlFlowNode for SOURCE | test.py:152:9:152:21 | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:153:10:153:10 | ControlFlowNode for x [Dictionary element at key s] | test.py:153:10:153:15 | ControlFlowNode for Subscript |
|
||||
| test.py:157:9:157:21 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:158:10:158:10 | ControlFlowNode for x [Dictionary element at key s] |
|
||||
| test.py:157:15:157:20 | ControlFlowNode for SOURCE | test.py:157:9:157:21 | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:158:10:158:10 | ControlFlowNode for x [Dictionary element at key s] | test.py:158:10:158:19 | ControlFlowNode for Attribute() |
|
||||
| test.py:183:9:183:42 | ControlFlowNode for ListComp [List element] | test.py:184:10:184:10 | ControlFlowNode for x [List element] |
|
||||
| test.py:183:10:183:10 | ControlFlowNode for y | test.py:183:9:183:42 | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:183:16:183:16 | SSA variable z [List element] | test.py:183:41:183:41 | ControlFlowNode for z [List element] |
|
||||
| test.py:183:21:183:30 | ControlFlowNode for List [List element, List element] | test.py:183:16:183:16 | SSA variable z [List element] |
|
||||
| test.py:183:22:183:29 | ControlFlowNode for List [List element] | test.py:183:21:183:30 | ControlFlowNode for List [List element, List element] |
|
||||
| test.py:183:23:183:28 | ControlFlowNode for SOURCE | test.py:183:22:183:29 | ControlFlowNode for List [List element] |
|
||||
| test.py:183:36:183:36 | SSA variable y | test.py:183:10:183:10 | ControlFlowNode for y |
|
||||
| test.py:183:41:183:41 | ControlFlowNode for z [List element] | test.py:183:36:183:36 | SSA variable y |
|
||||
| test.py:184:10:184:10 | ControlFlowNode for x [List element] | test.py:184:10:184:13 | ControlFlowNode for Subscript |
|
||||
| test.py:188:9:188:68 | ControlFlowNode for ListComp [List element] | test.py:189:10:189:10 | ControlFlowNode for x [List element] |
|
||||
| test.py:188:10:188:10 | ControlFlowNode for y | test.py:188:9:188:68 | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:188:16:188:16 | SSA variable v [List element, List element, List element] | test.py:188:45:188:45 | ControlFlowNode for v [List element, List element, List element] |
|
||||
| test.py:188:21:188:34 | ControlFlowNode for List [List element, List element, List element, List element] | test.py:188:16:188:16 | SSA variable v [List element, List element, List element] |
|
||||
| test.py:188:22:188:33 | ControlFlowNode for List [List element, List element, List element] | test.py:188:21:188:34 | ControlFlowNode for List [List element, List element, List element, List element] |
|
||||
| test.py:188:23:188:32 | ControlFlowNode for List [List element, List element] | test.py:188:22:188:33 | ControlFlowNode for List [List element, List element, List element] |
|
||||
| test.py:188:24:188:31 | ControlFlowNode for List [List element] | test.py:188:23:188:32 | ControlFlowNode for List [List element, List element] |
|
||||
| test.py:188:25:188:30 | ControlFlowNode for SOURCE | test.py:188:24:188:31 | ControlFlowNode for List [List element] |
|
||||
| test.py:188:40:188:40 | SSA variable u [List element, List element] | test.py:188:56:188:56 | ControlFlowNode for u [List element, List element] |
|
||||
| test.py:188:45:188:45 | ControlFlowNode for v [List element, List element, List element] | test.py:188:40:188:40 | SSA variable u [List element, List element] |
|
||||
| test.py:188:51:188:51 | SSA variable z [List element] | test.py:188:67:188:67 | ControlFlowNode for z [List element] |
|
||||
| test.py:188:56:188:56 | ControlFlowNode for u [List element, List element] | test.py:188:51:188:51 | SSA variable z [List element] |
|
||||
| test.py:188:62:188:62 | SSA variable y | test.py:188:10:188:10 | ControlFlowNode for y |
|
||||
| test.py:188:67:188:67 | ControlFlowNode for z [List element] | test.py:188:62:188:62 | SSA variable y |
|
||||
| test.py:189:10:189:10 | ControlFlowNode for x [List element] | test.py:189:10:189:13 | ControlFlowNode for Subscript |
|
||||
| test.py:199:9:199:42 | ControlFlowNode for ListComp [List element] | test.py:200:10:200:10 | ControlFlowNode for x [List element] |
|
||||
| test.py:199:10:199:10 | ControlFlowNode for y | test.py:199:9:199:42 | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:199:16:199:16 | SSA variable y | test.py:199:10:199:10 | ControlFlowNode for y |
|
||||
| test.py:199:22:199:22 | ControlFlowNode for z | test.py:199:22:199:40 | ControlFlowNode for GeneratorExp [List element] |
|
||||
| test.py:199:22:199:40 | ControlFlowNode for GeneratorExp [List element] | test.py:199:16:199:16 | SSA variable y |
|
||||
| test.py:199:28:199:28 | SSA variable z | test.py:199:22:199:22 | ControlFlowNode for z |
|
||||
| test.py:199:33:199:40 | ControlFlowNode for List [List element] | test.py:199:28:199:28 | SSA variable z |
|
||||
| test.py:199:34:199:39 | ControlFlowNode for SOURCE | test.py:199:33:199:40 | ControlFlowNode for List [List element] |
|
||||
| test.py:200:10:200:10 | ControlFlowNode for x [List element] | test.py:200:10:200:13 | ControlFlowNode for Subscript |
|
||||
| test.py:205:9:205:47 | ControlFlowNode for ListComp [List element] | test.py:206:10:206:10 | ControlFlowNode for x [List element] |
|
||||
| test.py:205:10:205:10 | ControlFlowNode for a | test.py:205:9:205:47 | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:205:17:205:17 | SSA variable a | test.py:205:10:205:10 | ControlFlowNode for a |
|
||||
| test.py:205:17:205:20 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:205:17:205:17 | SSA variable a |
|
||||
| test.py:205:17:205:20 | IterableSequence [Tuple element at index 0] | test.py:205:17:205:20 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:205:26:205:46 | ControlFlowNode for List [List element, Tuple element at index 0] | test.py:205:17:205:20 | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:205:28:205:33 | ControlFlowNode for SOURCE | test.py:205:28:205:44 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:205:28:205:44 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:205:26:205:46 | ControlFlowNode for List [List element, Tuple element at index 0] |
|
||||
| test.py:206:10:206:10 | ControlFlowNode for x [List element] | test.py:206:10:206:13 | ControlFlowNode for Subscript |
|
||||
| test.py:210:9:210:51 | ControlFlowNode for ListComp [List element] | test.py:211:10:211:10 | ControlFlowNode for x [List element] |
|
||||
| test.py:210:10:210:10 | ControlFlowNode for a [List element] | test.py:210:10:210:13 | ControlFlowNode for Subscript |
|
||||
| test.py:210:10:210:13 | ControlFlowNode for Subscript | test.py:210:9:210:51 | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:210:20:210:21 | IterableElement | test.py:210:20:210:21 | SSA variable a [List element] |
|
||||
| test.py:210:20:210:21 | SSA variable a [List element] | test.py:210:10:210:10 | ControlFlowNode for a [List element] |
|
||||
| test.py:210:20:210:24 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:210:20:210:21 | IterableElement |
|
||||
| test.py:210:20:210:24 | IterableSequence [Tuple element at index 0] | test.py:210:20:210:24 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:210:30:210:50 | ControlFlowNode for List [List element, Tuple element at index 0] | test.py:210:20:210:24 | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:210:32:210:37 | ControlFlowNode for SOURCE | test.py:210:32:210:48 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:210:32:210:48 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:210:30:210:50 | ControlFlowNode for List [List element, Tuple element at index 0] |
|
||||
| test.py:211:10:211:10 | ControlFlowNode for x [List element] | test.py:211:10:211:13 | ControlFlowNode for Subscript |
|
||||
| test.py:349:11:349:16 | ControlFlowNode for SOURCE | test.py:349:11:349:17 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:349:11:349:17 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:349:10:349:21 | ControlFlowNode for Subscript |
|
||||
| test.py:353:10:353:17 | ControlFlowNode for List [List element] | test.py:353:10:353:20 | ControlFlowNode for Subscript |
|
||||
| test.py:353:11:353:16 | ControlFlowNode for SOURCE | test.py:353:10:353:17 | ControlFlowNode for List [List element] |
|
||||
| test.py:357:10:357:22 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:357:10:357:27 | ControlFlowNode for Subscript |
|
||||
| test.py:357:16:357:21 | ControlFlowNode for SOURCE | test.py:357:10:357:22 | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:375:15:375:15 | ControlFlowNode for b | test.py:376:12:376:12 | ControlFlowNode for b |
|
||||
| test.py:380:28:380:33 | ControlFlowNode for SOURCE | test.py:375:15:375:15 | ControlFlowNode for b |
|
||||
| test.py:380:28:380:33 | ControlFlowNode for SOURCE | test.py:380:10:380:34 | ControlFlowNode for second() |
|
||||
| test.py:388:30:388:35 | ControlFlowNode for SOURCE | test.py:375:15:375:15 | ControlFlowNode for b |
|
||||
| test.py:388:30:388:35 | ControlFlowNode for SOURCE | test.py:388:10:388:36 | ControlFlowNode for second() |
|
||||
| test.py:396:10:396:43 | KwUnpacked b | test.py:375:15:375:15 | ControlFlowNode for b |
|
||||
| test.py:396:10:396:43 | KwUnpacked b | test.py:396:10:396:43 | ControlFlowNode for second() |
|
||||
| test.py:396:30:396:42 | ControlFlowNode for Dict [Dictionary element at key b] | test.py:396:10:396:43 | KwUnpacked b |
|
||||
| test.py:396:36:396:41 | ControlFlowNode for SOURCE | test.py:396:30:396:42 | ControlFlowNode for Dict [Dictionary element at key b] |
|
||||
| test.py:399:21:399:21 | ControlFlowNode for b [Tuple element at index 0] | test.py:400:12:400:12 | ControlFlowNode for b [Tuple element at index 0] |
|
||||
| test.py:400:12:400:12 | ControlFlowNode for b [Tuple element at index 0] | test.py:400:12:400:15 | ControlFlowNode for Subscript |
|
||||
| test.py:404:10:404:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:399:21:399:21 | ControlFlowNode for b [Tuple element at index 0] |
|
||||
| test.py:404:10:404:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:404:10:404:39 | ControlFlowNode for f_extra_pos() |
|
||||
| test.py:404:33:404:38 | ControlFlowNode for SOURCE | test.py:404:10:404:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] |
|
||||
| test.py:407:26:407:26 | ControlFlowNode for b [Dictionary element at key b] | test.py:408:12:408:12 | ControlFlowNode for b [Dictionary element at key b] |
|
||||
| test.py:408:12:408:12 | ControlFlowNode for b [Dictionary element at key b] | test.py:408:12:408:17 | ControlFlowNode for Subscript |
|
||||
| test.py:412:10:412:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:407:26:407:26 | ControlFlowNode for b [Dictionary element at key b] |
|
||||
| test.py:412:10:412:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:412:10:412:45 | ControlFlowNode for f_extra_keyword() |
|
||||
| test.py:412:39:412:44 | ControlFlowNode for SOURCE | test.py:412:10:412:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] |
|
||||
| test.py:429:15:429:20 | ControlFlowNode for SOURCE | test.py:429:10:429:20 | ControlFlowNode for BoolExpr |
|
||||
| test.py:434:16:434:21 | ControlFlowNode for SOURCE | test.py:434:10:434:21 | ControlFlowNode for BoolExpr |
|
||||
| test.py:445:10:445:15 | ControlFlowNode for SOURCE | test.py:445:10:445:38 | ControlFlowNode for IfExp |
|
||||
| test.py:453:34:453:39 | ControlFlowNode for SOURCE | test.py:453:10:453:39 | ControlFlowNode for IfExp |
|
||||
| test.py:474:11:474:11 | ControlFlowNode for x | test.py:475:16:475:16 | ControlFlowNode for x |
|
||||
| test.py:477:12:477:17 | ControlFlowNode for SOURCE | test.py:474:11:474:11 | ControlFlowNode for x |
|
||||
| test.py:477:12:477:17 | ControlFlowNode for SOURCE | test.py:477:10:477:18 | ControlFlowNode for f() |
|
||||
| test.py:481:19:481:19 | ControlFlowNode for b | test.py:482:16:482:16 | ControlFlowNode for b |
|
||||
| test.py:484:28:484:33 | ControlFlowNode for SOURCE | test.py:481:19:481:19 | ControlFlowNode for b |
|
||||
| test.py:484:28:484:33 | ControlFlowNode for SOURCE | test.py:484:10:484:34 | ControlFlowNode for second() |
|
||||
| test.py:495:19:495:19 | ControlFlowNode for b | test.py:496:16:496:16 | ControlFlowNode for b |
|
||||
| test.py:498:30:498:35 | ControlFlowNode for SOURCE | test.py:495:19:495:19 | ControlFlowNode for b |
|
||||
| test.py:498:30:498:35 | ControlFlowNode for SOURCE | test.py:498:10:498:36 | ControlFlowNode for second() |
|
||||
| test.py:509:19:509:19 | ControlFlowNode for b | test.py:510:16:510:16 | ControlFlowNode for b |
|
||||
| test.py:512:10:512:43 | KwUnpacked b | test.py:509:19:509:19 | ControlFlowNode for b |
|
||||
| test.py:512:10:512:43 | KwUnpacked b | test.py:512:10:512:43 | ControlFlowNode for second() |
|
||||
| test.py:512:30:512:42 | ControlFlowNode for Dict [Dictionary element at key b] | test.py:512:10:512:43 | KwUnpacked b |
|
||||
| test.py:512:36:512:41 | ControlFlowNode for SOURCE | test.py:512:30:512:42 | ControlFlowNode for Dict [Dictionary element at key b] |
|
||||
| test.py:516:30:516:30 | ControlFlowNode for b [Tuple element at index 0] | test.py:516:33:516:33 | ControlFlowNode for b [Tuple element at index 0] |
|
||||
| test.py:516:33:516:33 | ControlFlowNode for b [Tuple element at index 0] | test.py:516:33:516:36 | ControlFlowNode for Subscript |
|
||||
| test.py:517:10:517:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:516:30:516:30 | ControlFlowNode for b [Tuple element at index 0] |
|
||||
| test.py:517:10:517:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:517:10:517:39 | ControlFlowNode for f_extra_pos() |
|
||||
| test.py:517:33:517:38 | ControlFlowNode for SOURCE | test.py:517:10:517:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] |
|
||||
| test.py:521:35:521:35 | ControlFlowNode for b [Dictionary element at key b] | test.py:521:38:521:38 | ControlFlowNode for b [Dictionary element at key b] |
|
||||
| test.py:521:38:521:38 | ControlFlowNode for b [Dictionary element at key b] | test.py:521:38:521:43 | ControlFlowNode for Subscript |
|
||||
| test.py:522:10:522:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:521:35:521:35 | ControlFlowNode for b [Dictionary element at key b] |
|
||||
| test.py:522:10:522:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:522:10:522:45 | ControlFlowNode for f_extra_keyword() |
|
||||
| test.py:522:39:522:44 | ControlFlowNode for SOURCE | test.py:522:10:522:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] |
|
||||
| test.py:534:9:534:14 | ControlFlowNode for SOURCE | test.py:536:10:536:10 | ControlFlowNode for a |
|
||||
| test.py:534:9:534:14 | ControlFlowNode for SOURCE | test.py:541:10:541:10 | ControlFlowNode for b |
|
||||
| test.py:546:10:546:15 | ControlFlowNode for SOURCE | test.py:546:10:546:26 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:546:10:546:26 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:547:5:547:8 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:547:5:547:5 | SSA variable a | test.py:548:10:548:10 | ControlFlowNode for a |
|
||||
| test.py:547:5:547:8 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:547:5:547:5 | SSA variable a |
|
||||
| test.py:554:10:554:15 | ControlFlowNode for SOURCE | test.py:554:10:554:36 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:554:10:554:36 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:555:5:555:13 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:554:10:554:36 | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 1] | test.py:555:5:555:13 | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 1] |
|
||||
| test.py:554:19:554:35 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:554:10:554:36 | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 1] |
|
||||
| test.py:554:30:554:35 | ControlFlowNode for SOURCE | test.py:554:19:554:35 | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:555:5:555:5 | SSA variable a | test.py:556:10:556:10 | ControlFlowNode for a |
|
||||
| test.py:555:5:555:13 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:555:5:555:5 | SSA variable a |
|
||||
| test.py:555:5:555:13 | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 1] | test.py:555:9:555:12 | IterableSequence [Tuple element at index 1] |
|
||||
| test.py:555:9:555:12 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:555:12:555:12 | SSA variable c |
|
||||
| test.py:555:9:555:12 | IterableSequence [Tuple element at index 1] | test.py:555:9:555:12 | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:555:12:555:12 | SSA variable c | test.py:558:10:558:10 | ControlFlowNode for c |
|
||||
| test.py:563:9:563:33 | ControlFlowNode for List [List element, List element, List element, List element] | test.py:564:5:564:14 | IterableSequence [List element, List element, List element, List element] |
|
||||
| test.py:563:10:563:21 | ControlFlowNode for List [List element, List element, List element] | test.py:563:9:563:33 | ControlFlowNode for List [List element, List element, List element, List element] |
|
||||
| test.py:563:11:563:20 | ControlFlowNode for List [List element, List element] | test.py:563:10:563:21 | ControlFlowNode for List [List element, List element, List element] |
|
||||
| test.py:563:12:563:19 | ControlFlowNode for List [List element] | test.py:563:11:563:20 | ControlFlowNode for List [List element, List element] |
|
||||
| test.py:563:13:563:18 | ControlFlowNode for SOURCE | test.py:563:12:563:19 | ControlFlowNode for List [List element] |
|
||||
| test.py:564:5:564:11 | ControlFlowNode for List [Tuple element at index 0, List element, List element] | test.py:564:6:564:10 | IterableSequence [List element, List element] |
|
||||
| test.py:564:5:564:11 | IterableElement [List element, List element] | test.py:564:5:564:11 | ControlFlowNode for List [Tuple element at index 0, List element, List element] |
|
||||
| test.py:564:5:564:11 | IterableSequence [List element, List element, List element] | test.py:564:5:564:11 | IterableElement [List element, List element] |
|
||||
| test.py:564:5:564:14 | ControlFlowNode for Tuple [Tuple element at index 0, List element, List element, List element] | test.py:564:5:564:11 | IterableSequence [List element, List element, List element] |
|
||||
| test.py:564:5:564:14 | IterableElement [List element, List element, List element] | test.py:564:5:564:14 | ControlFlowNode for Tuple [Tuple element at index 0, List element, List element, List element] |
|
||||
| test.py:564:5:564:14 | IterableSequence [List element, List element, List element, List element] | test.py:564:5:564:14 | IterableElement [List element, List element, List element] |
|
||||
| test.py:564:6:564:10 | ControlFlowNode for List [Tuple element at index 0, List element] | test.py:564:7:564:9 | IterableSequence [List element] |
|
||||
| test.py:564:6:564:10 | IterableElement [List element] | test.py:564:6:564:10 | ControlFlowNode for List [Tuple element at index 0, List element] |
|
||||
| test.py:564:6:564:10 | IterableSequence [List element, List element] | test.py:564:6:564:10 | IterableElement [List element] |
|
||||
| test.py:564:7:564:9 | ControlFlowNode for List [Tuple element at index 0] | test.py:564:8:564:8 | SSA variable a |
|
||||
| test.py:564:7:564:9 | IterableElement | test.py:564:7:564:9 | ControlFlowNode for List [Tuple element at index 0] |
|
||||
| test.py:564:7:564:9 | IterableSequence [List element] | test.py:564:7:564:9 | IterableElement |
|
||||
| test.py:564:8:564:8 | SSA variable a | test.py:565:10:565:10 | ControlFlowNode for a |
|
||||
| test.py:571:10:571:15 | ControlFlowNode for SOURCE | test.py:571:10:571:34 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:571:10:571:34 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:572:5:572:12 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:571:10:571:34 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:572:5:572:12 | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:571:18:571:23 | ControlFlowNode for SOURCE | test.py:571:10:571:34 | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:572:5:572:5 | SSA variable a | test.py:573:10:573:10 | ControlFlowNode for a |
|
||||
| test.py:572:5:572:12 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:572:5:572:5 | SSA variable a |
|
||||
| test.py:572:5:572:12 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:572:8:572:9 | IterableElement |
|
||||
| test.py:572:5:572:12 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:572:12:572:12 | SSA variable c |
|
||||
| test.py:572:8:572:9 | IterableElement | test.py:572:8:572:9 | SSA variable b [List element] |
|
||||
| test.py:572:8:572:9 | SSA variable b [List element] | test.py:575:10:575:10 | ControlFlowNode for b [List element] |
|
||||
| test.py:572:12:572:12 | SSA variable c | test.py:576:12:576:12 | ControlFlowNode for c |
|
||||
| test.py:575:10:575:10 | ControlFlowNode for b [List element] | test.py:575:10:575:13 | ControlFlowNode for Subscript |
|
||||
| test.py:581:10:581:15 | ControlFlowNode for SOURCE | test.py:581:10:581:23 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:581:10:581:23 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:582:5:582:12 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:581:10:581:23 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:582:5:582:12 | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:581:18:581:23 | ControlFlowNode for SOURCE | test.py:581:10:581:23 | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:582:5:582:5 | SSA variable a | test.py:583:10:583:10 | ControlFlowNode for a |
|
||||
| test.py:582:5:582:12 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:582:5:582:5 | SSA variable a |
|
||||
| test.py:582:5:582:12 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:582:12:582:12 | SSA variable c |
|
||||
| test.py:582:12:582:12 | SSA variable c | test.py:585:10:585:10 | ControlFlowNode for c |
|
||||
| test.py:590:10:590:61 | ControlFlowNode for List [List element, List element] | test.py:593:6:593:23 | IterableSequence [List element, List element] |
|
||||
| test.py:590:10:590:61 | ControlFlowNode for List [List element, List element] | test.py:601:5:601:24 | IterableSequence [List element, List element] |
|
||||
| test.py:590:10:590:61 | ControlFlowNode for List [List element, List element] | test.py:609:6:609:23 | IterableSequence [List element, List element] |
|
||||
| test.py:590:11:590:37 | ControlFlowNode for List [List element] | test.py:590:10:590:61 | ControlFlowNode for List [List element, List element] |
|
||||
| test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:590:11:590:37 | ControlFlowNode for List [List element] |
|
||||
| test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:590:11:590:37 | ControlFlowNode for List [List element] |
|
||||
| test.py:590:40:590:47 | ControlFlowNode for List [List element] | test.py:590:10:590:61 | ControlFlowNode for List [List element, List element] |
|
||||
| test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:590:40:590:47 | ControlFlowNode for List [List element] |
|
||||
| test.py:593:6:593:23 | ControlFlowNode for Tuple [Tuple element at index 0, List element] | test.py:593:7:593:16 | IterableSequence [List element] |
|
||||
| test.py:593:6:593:23 | IterableElement [List element] | test.py:593:6:593:23 | ControlFlowNode for Tuple [Tuple element at index 0, List element] |
|
||||
| test.py:593:6:593:23 | IterableSequence [List element, List element] | test.py:593:6:593:23 | IterableElement [List element] |
|
||||
| test.py:593:7:593:8 | SSA variable a1 | test.py:594:10:594:11 | ControlFlowNode for a1 |
|
||||
| test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:593:7:593:8 | SSA variable a1 |
|
||||
| test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:593:11:593:12 | SSA variable a2 |
|
||||
| test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 2] | test.py:593:15:593:16 | SSA variable a3 |
|
||||
| test.py:593:7:593:16 | IterableElement | test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:593:7:593:16 | IterableElement | test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:593:7:593:16 | IterableElement | test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 2] |
|
||||
| test.py:593:7:593:16 | IterableSequence [List element] | test.py:593:7:593:16 | IterableElement |
|
||||
| test.py:593:11:593:12 | SSA variable a2 | test.py:595:12:595:13 | ControlFlowNode for a2 |
|
||||
| test.py:593:15:593:16 | SSA variable a3 | test.py:596:10:596:11 | ControlFlowNode for a3 |
|
||||
| test.py:601:5:601:24 | ControlFlowNode for List [Tuple element at index 0, List element] | test.py:601:7:601:16 | IterableSequence [List element] |
|
||||
| test.py:601:5:601:24 | IterableElement [List element] | test.py:601:5:601:24 | ControlFlowNode for List [Tuple element at index 0, List element] |
|
||||
| test.py:601:5:601:24 | IterableSequence [List element, List element] | test.py:601:5:601:24 | IterableElement [List element] |
|
||||
| test.py:601:7:601:8 | SSA variable a1 | test.py:602:10:602:11 | ControlFlowNode for a1 |
|
||||
| test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:601:7:601:8 | SSA variable a1 |
|
||||
| test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:601:11:601:12 | SSA variable a2 |
|
||||
| test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 2] | test.py:601:15:601:16 | SSA variable a3 |
|
||||
| test.py:601:7:601:16 | IterableElement | test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:601:7:601:16 | IterableElement | test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:601:7:601:16 | IterableElement | test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 2] |
|
||||
| test.py:601:7:601:16 | IterableSequence [List element] | test.py:601:7:601:16 | IterableElement |
|
||||
| test.py:601:11:601:12 | SSA variable a2 | test.py:603:12:603:13 | ControlFlowNode for a2 |
|
||||
| test.py:601:15:601:16 | SSA variable a3 | test.py:604:10:604:11 | ControlFlowNode for a3 |
|
||||
| test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 0] | test.py:609:7:609:8 | SSA variable a1 |
|
||||
| test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 1] | test.py:609:11:609:12 | SSA variable a2 |
|
||||
| test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 2] | test.py:609:15:609:16 | SSA variable a3 |
|
||||
| test.py:609:6:609:17 | IterableElement | test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 0] |
|
||||
| test.py:609:6:609:17 | IterableElement | test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 1] |
|
||||
| test.py:609:6:609:17 | IterableElement | test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 2] |
|
||||
| test.py:609:6:609:17 | IterableSequence [List element] | test.py:609:6:609:17 | IterableElement |
|
||||
| test.py:609:6:609:23 | ControlFlowNode for Tuple [Tuple element at index 0, List element] | test.py:609:6:609:17 | IterableSequence [List element] |
|
||||
| test.py:609:6:609:23 | IterableElement [List element] | test.py:609:6:609:23 | ControlFlowNode for Tuple [Tuple element at index 0, List element] |
|
||||
| test.py:609:6:609:23 | IterableSequence [List element, List element] | test.py:609:6:609:23 | IterableElement [List element] |
|
||||
| test.py:609:7:609:8 | SSA variable a1 | test.py:610:10:610:11 | ControlFlowNode for a1 |
|
||||
| test.py:609:11:609:12 | SSA variable a2 | test.py:611:12:611:13 | ControlFlowNode for a2 |
|
||||
| test.py:609:15:609:16 | SSA variable a3 | test.py:612:10:612:11 | ControlFlowNode for a3 |
|
||||
| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | test.py:621:5:621:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 0] |
|
||||
| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | test.py:630:6:630:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] |
|
||||
| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | test.py:639:5:639:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 0] |
|
||||
| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | test.py:648:6:648:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] |
|
||||
| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | test.py:621:5:621:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 2] |
|
||||
| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | test.py:630:6:630:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] |
|
||||
| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | test.py:639:5:639:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 2] |
|
||||
| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | test.py:648:6:648:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] |
|
||||
| test.py:618:12:618:17 | ControlFlowNode for SOURCE | test.py:618:12:618:36 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:618:12:618:36 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] |
|
||||
| test.py:618:12:618:36 | ControlFlowNode for Tuple [Tuple element at index 2] | test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] |
|
||||
| test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:618:12:618:36 | ControlFlowNode for Tuple [Tuple element at index 2] |
|
||||
| test.py:621:5:621:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 0] | test.py:621:6:621:14 | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:621:5:621:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 2] | test.py:621:6:621:14 | IterableSequence [Tuple element at index 2] |
|
||||
| test.py:621:6:621:14 | ControlFlowNode for List [Tuple element at index 0] | test.py:621:7:621:8 | SSA variable a1 |
|
||||
| test.py:621:6:621:14 | ControlFlowNode for List [Tuple element at index 2] | test.py:621:11:621:13 | IterableElement |
|
||||
| test.py:621:6:621:14 | IterableSequence [Tuple element at index 0] | test.py:621:6:621:14 | ControlFlowNode for List [Tuple element at index 0] |
|
||||
| test.py:621:6:621:14 | IterableSequence [Tuple element at index 2] | test.py:621:6:621:14 | ControlFlowNode for List [Tuple element at index 2] |
|
||||
| test.py:621:7:621:8 | SSA variable a1 | test.py:622:10:622:11 | ControlFlowNode for a1 |
|
||||
| test.py:621:11:621:13 | IterableElement | test.py:621:11:621:13 | SSA variable a2 [List element] |
|
||||
| test.py:621:11:621:13 | SSA variable a2 [List element] | test.py:624:12:624:13 | ControlFlowNode for a2 [List element] |
|
||||
| test.py:621:11:621:13 | SSA variable a2 [List element] | test.py:625:10:625:11 | ControlFlowNode for a2 [List element] |
|
||||
| test.py:624:12:624:13 | ControlFlowNode for a2 [List element] | test.py:624:12:624:16 | ControlFlowNode for Subscript |
|
||||
| test.py:625:10:625:11 | ControlFlowNode for a2 [List element] | test.py:625:10:625:14 | ControlFlowNode for Subscript |
|
||||
| test.py:630:6:630:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | test.py:630:7:630:13 | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:630:6:630:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | test.py:630:7:630:13 | IterableSequence [Tuple element at index 2] |
|
||||
| test.py:630:7:630:8 | SSA variable a1 | test.py:631:10:631:11 | ControlFlowNode for a1 |
|
||||
| test.py:630:7:630:13 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:630:7:630:8 | SSA variable a1 |
|
||||
| test.py:630:7:630:13 | ControlFlowNode for Tuple [Tuple element at index 2] | test.py:630:11:630:13 | IterableElement |
|
||||
| test.py:630:7:630:13 | IterableSequence [Tuple element at index 0] | test.py:630:7:630:13 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:630:7:630:13 | IterableSequence [Tuple element at index 2] | test.py:630:7:630:13 | ControlFlowNode for Tuple [Tuple element at index 2] |
|
||||
| test.py:630:11:630:13 | IterableElement | test.py:630:11:630:13 | SSA variable a2 [List element] |
|
||||
| test.py:630:11:630:13 | SSA variable a2 [List element] | test.py:633:12:633:13 | ControlFlowNode for a2 [List element] |
|
||||
| test.py:630:11:630:13 | SSA variable a2 [List element] | test.py:634:10:634:11 | ControlFlowNode for a2 [List element] |
|
||||
| test.py:633:12:633:13 | ControlFlowNode for a2 [List element] | test.py:633:12:633:16 | ControlFlowNode for Subscript |
|
||||
| test.py:634:10:634:11 | ControlFlowNode for a2 [List element] | test.py:634:10:634:14 | ControlFlowNode for Subscript |
|
||||
| test.py:639:5:639:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 0] | test.py:639:7:639:13 | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:639:5:639:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 2] | test.py:639:7:639:13 | IterableSequence [Tuple element at index 2] |
|
||||
| test.py:639:7:639:8 | SSA variable a1 | test.py:640:10:640:11 | ControlFlowNode for a1 |
|
||||
| test.py:639:7:639:13 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:639:7:639:8 | SSA variable a1 |
|
||||
| test.py:639:7:639:13 | ControlFlowNode for Tuple [Tuple element at index 2] | test.py:639:11:639:13 | IterableElement |
|
||||
| test.py:639:7:639:13 | IterableSequence [Tuple element at index 0] | test.py:639:7:639:13 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:639:7:639:13 | IterableSequence [Tuple element at index 2] | test.py:639:7:639:13 | ControlFlowNode for Tuple [Tuple element at index 2] |
|
||||
| test.py:639:11:639:13 | IterableElement | test.py:639:11:639:13 | SSA variable a2 [List element] |
|
||||
| test.py:639:11:639:13 | SSA variable a2 [List element] | test.py:642:12:642:13 | ControlFlowNode for a2 [List element] |
|
||||
| test.py:639:11:639:13 | SSA variable a2 [List element] | test.py:643:10:643:11 | ControlFlowNode for a2 [List element] |
|
||||
| test.py:642:12:642:13 | ControlFlowNode for a2 [List element] | test.py:642:12:642:16 | ControlFlowNode for Subscript |
|
||||
| test.py:643:10:643:11 | ControlFlowNode for a2 [List element] | test.py:643:10:643:14 | ControlFlowNode for Subscript |
|
||||
| test.py:648:6:648:14 | ControlFlowNode for List [Tuple element at index 0] | test.py:648:7:648:8 | SSA variable a1 |
|
||||
| test.py:648:6:648:14 | ControlFlowNode for List [Tuple element at index 2] | test.py:648:11:648:13 | IterableElement |
|
||||
| test.py:648:6:648:14 | IterableSequence [Tuple element at index 0] | test.py:648:6:648:14 | ControlFlowNode for List [Tuple element at index 0] |
|
||||
| test.py:648:6:648:14 | IterableSequence [Tuple element at index 2] | test.py:648:6:648:14 | ControlFlowNode for List [Tuple element at index 2] |
|
||||
| test.py:648:6:648:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | test.py:648:6:648:14 | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:648:6:648:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | test.py:648:6:648:14 | IterableSequence [Tuple element at index 2] |
|
||||
| test.py:648:7:648:8 | SSA variable a1 | test.py:649:10:649:11 | ControlFlowNode for a1 |
|
||||
| test.py:648:11:648:13 | IterableElement | test.py:648:11:648:13 | SSA variable a2 [List element] |
|
||||
| test.py:648:11:648:13 | SSA variable a2 [List element] | test.py:651:12:651:13 | ControlFlowNode for a2 [List element] |
|
||||
| test.py:648:11:648:13 | SSA variable a2 [List element] | test.py:652:10:652:11 | ControlFlowNode for a2 [List element] |
|
||||
| test.py:651:12:651:13 | ControlFlowNode for a2 [List element] | test.py:651:12:651:16 | ControlFlowNode for Subscript |
|
||||
| test.py:652:10:652:11 | ControlFlowNode for a2 [List element] | test.py:652:10:652:14 | ControlFlowNode for Subscript |
|
||||
| test.py:659:19:659:24 | ControlFlowNode for SOURCE | test.py:660:10:660:10 | ControlFlowNode for a |
|
||||
| test.py:667:10:667:51 | ControlFlowNode for List [List element, Tuple element at index 0] | test.py:668:16:668:17 | ControlFlowNode for tl [List element, Tuple element at index 0] |
|
||||
| test.py:667:12:667:17 | ControlFlowNode for SOURCE | test.py:667:12:667:28 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:667:12:667:28 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:667:10:667:51 | ControlFlowNode for List [List element, Tuple element at index 0] |
|
||||
| test.py:667:33:667:38 | ControlFlowNode for SOURCE | test.py:667:33:667:49 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:667:33:667:49 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:667:10:667:51 | ControlFlowNode for List [List element, Tuple element at index 0] |
|
||||
| test.py:668:9:668:9 | SSA variable x | test.py:669:14:669:14 | ControlFlowNode for x |
|
||||
| test.py:668:9:668:11 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:668:9:668:9 | SSA variable x |
|
||||
| test.py:668:9:668:11 | IterableSequence [Tuple element at index 0] | test.py:668:9:668:11 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:668:16:668:17 | ControlFlowNode for tl [List element, Tuple element at index 0] | test.py:668:9:668:11 | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:675:10:675:51 | ControlFlowNode for List [List element, Tuple element at index 0] | test.py:676:17:676:18 | ControlFlowNode for tl [List element, Tuple element at index 0] |
|
||||
| test.py:675:12:675:17 | ControlFlowNode for SOURCE | test.py:675:12:675:28 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:675:12:675:28 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:675:10:675:51 | ControlFlowNode for List [List element, Tuple element at index 0] |
|
||||
| test.py:675:33:675:38 | ControlFlowNode for SOURCE | test.py:675:33:675:49 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:675:33:675:49 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:675:10:675:51 | ControlFlowNode for List [List element, Tuple element at index 0] |
|
||||
| test.py:676:9:676:10 | IterableElement | test.py:676:9:676:10 | SSA variable x [List element] |
|
||||
| test.py:676:9:676:10 | SSA variable x [List element] | test.py:678:14:678:14 | ControlFlowNode for x [List element] |
|
||||
| test.py:676:9:676:12 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:676:9:676:10 | IterableElement |
|
||||
| test.py:676:9:676:12 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:676:12:676:12 | SSA variable y |
|
||||
| test.py:676:9:676:12 | IterableSequence [Tuple element at index 0] | test.py:676:9:676:12 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:676:12:676:12 | SSA variable y | test.py:679:16:679:16 | ControlFlowNode for y |
|
||||
| test.py:676:17:676:18 | ControlFlowNode for tl [List element, Tuple element at index 0] | test.py:676:9:676:12 | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:678:14:678:14 | ControlFlowNode for x [List element] | test.py:678:14:678:17 | ControlFlowNode for Subscript |
|
||||
| test.py:684:10:684:51 | ControlFlowNode for List [List element, Tuple element at index 0] | test.py:685:19:685:20 | ControlFlowNode for tl [List element, Tuple element at index 0] |
|
||||
| test.py:684:12:684:17 | ControlFlowNode for SOURCE | test.py:684:12:684:28 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:684:12:684:28 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:684:10:684:51 | ControlFlowNode for List [List element, Tuple element at index 0] |
|
||||
| test.py:684:33:684:38 | ControlFlowNode for SOURCE | test.py:684:33:684:49 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:684:33:684:49 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:684:10:684:51 | ControlFlowNode for List [List element, Tuple element at index 0] |
|
||||
| test.py:685:9:685:9 | SSA variable x | test.py:686:14:686:14 | ControlFlowNode for x |
|
||||
| test.py:685:9:685:14 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:685:9:685:9 | SSA variable x |
|
||||
| test.py:685:9:685:14 | IterableSequence [Tuple element at index 0] | test.py:685:9:685:14 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:685:19:685:20 | ControlFlowNode for tl [List element, Tuple element at index 0] | test.py:685:9:685:14 | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:690:39:690:42 | ControlFlowNode for args [Tuple element at index 0] | test.py:691:14:691:17 | ControlFlowNode for args [Tuple element at index 0] |
|
||||
| test.py:690:39:690:42 | ControlFlowNode for args [Tuple element at index 1] | test.py:691:14:691:17 | ControlFlowNode for args [Tuple element at index 1] |
|
||||
| test.py:691:7:691:9 | SSA variable arg | test.py:692:10:692:12 | ControlFlowNode for arg |
|
||||
| test.py:691:14:691:17 | ControlFlowNode for args [Tuple element at index 0] | test.py:691:7:691:9 | SSA variable arg |
|
||||
| test.py:691:14:691:17 | ControlFlowNode for args [Tuple element at index 1] | test.py:691:7:691:9 | SSA variable arg |
|
||||
| test.py:697:7:697:12 | ControlFlowNode for SOURCE | test.py:698:51:698:51 | ControlFlowNode for s |
|
||||
| test.py:698:3:698:52 | PosOverflowNode for iterate_star_args() [Tuple element at index 0] | test.py:690:39:690:42 | ControlFlowNode for args [Tuple element at index 0] |
|
||||
| test.py:698:3:698:52 | PosOverflowNode for iterate_star_args() [Tuple element at index 1] | test.py:690:39:690:42 | ControlFlowNode for args [Tuple element at index 1] |
|
||||
| test.py:698:43:698:48 | ControlFlowNode for SOURCE | test.py:698:3:698:52 | PosOverflowNode for iterate_star_args() [Tuple element at index 0] |
|
||||
| test.py:698:51:698:51 | ControlFlowNode for s | test.py:698:3:698:52 | PosOverflowNode for iterate_star_args() [Tuple element at index 1] |
|
||||
| test.py:769:16:769:21 | ControlFlowNode for SOURCE | test.py:772:10:772:36 | ControlFlowNode for return_from_inner_scope() |
|
||||
| test.py:807:35:807:35 | ControlFlowNode for x | test.py:808:10:808:10 | ControlFlowNode for x |
|
||||
| test.py:807:37:807:42 | ControlFlowNode for SOURCE | test.py:807:35:807:35 | ControlFlowNode for x |
|
||||
| test.py:807:48:807:48 | ControlFlowNode for y | test.py:809:10:809:10 | ControlFlowNode for y |
|
||||
| test.py:807:50:807:55 | ControlFlowNode for SOURCE | test.py:807:48:807:48 | ControlFlowNode for y |
|
||||
| test.py:807:61:807:61 | ControlFlowNode for z | test.py:810:10:810:10 | ControlFlowNode for z |
|
||||
| test.py:807:63:807:68 | ControlFlowNode for SOURCE | test.py:807:61:807:61 | ControlFlowNode for z |
|
||||
nodes
|
||||
| datamodel.py:35:7:35:7 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
|
||||
| datamodel.py:36:10:36:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
|
||||
| datamodel.py:38:6:38:17 | ControlFlowNode for f() | semmle.label | ControlFlowNode for f() |
|
||||
| datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:44:22:44:22 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| datamodel.py:46:16:46:16 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| datamodel.py:49:26:49:26 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| datamodel.py:50:16:50:16 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:152:5:152:8 | [post store] ControlFlowNode for self [Attribute b] | semmle.label | [post store] ControlFlowNode for self [Attribute b] |
|
||||
| datamodel.py:152:14:152:19 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:155:14:155:25 | ControlFlowNode for Customized() [Attribute b] | semmle.label | ControlFlowNode for Customized() [Attribute b] |
|
||||
| datamodel.py:159:6:159:15 | ControlFlowNode for customized [Attribute b] | semmle.label | ControlFlowNode for customized [Attribute b] |
|
||||
| datamodel.py:159:6:159:17 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test.py:42:10:42:26 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:42:21:42:26 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:43:9:43:9 | ControlFlowNode for x [Tuple element at index 1] | semmle.label | ControlFlowNode for x [Tuple element at index 1] |
|
||||
| test.py:43:9:43:12 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:44:10:44:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:55:9:55:14 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:56:10:56:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:61:9:61:16 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
|
||||
| test.py:62:10:62:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:66:9:66:17 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
|
||||
| test.py:67:10:67:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:71:9:71:10 | ControlFlowNode for IntegerLiteral | semmle.label | ControlFlowNode for IntegerLiteral |
|
||||
| test.py:72:10:72:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:76:9:76:12 | ControlFlowNode for FloatLiteral | semmle.label | ControlFlowNode for FloatLiteral |
|
||||
| test.py:77:10:77:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:87:10:87:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:88:10:88:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:93:9:93:16 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:93:10:93:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:94:10:94:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
|
||||
| test.py:94:10:94:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:103:9:103:37 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:103:10:103:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:104:10:104:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
|
||||
| test.py:104:10:104:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:108:9:108:29 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:108:10:108:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:108:16:108:16 | SSA variable y | semmle.label | SSA variable y |
|
||||
| test.py:108:21:108:28 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:108:22:108:27 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:109:10:109:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
|
||||
| test.py:109:10:109:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:113:9:113:16 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:113:10:113:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:114:9:114:22 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:114:10:114:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:114:16:114:16 | SSA variable y | semmle.label | SSA variable y |
|
||||
| test.py:114:21:114:21 | ControlFlowNode for l [List element] | semmle.label | ControlFlowNode for l [List element] |
|
||||
| test.py:115:10:115:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
|
||||
| test.py:115:10:115:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:125:9:125:16 | ControlFlowNode for Set [Set element] | semmle.label | ControlFlowNode for Set [Set element] |
|
||||
| test.py:125:10:125:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:126:10:126:10 | ControlFlowNode for x [Set element] | semmle.label | ControlFlowNode for x [Set element] |
|
||||
| test.py:126:10:126:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:130:9:130:37 | ControlFlowNode for SetComp [Set element] | semmle.label | ControlFlowNode for SetComp [Set element] |
|
||||
| test.py:130:10:130:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:131:10:131:10 | ControlFlowNode for x [Set element] | semmle.label | ControlFlowNode for x [Set element] |
|
||||
| test.py:131:10:131:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:135:9:135:29 | ControlFlowNode for SetComp [Set element] | semmle.label | ControlFlowNode for SetComp [Set element] |
|
||||
| test.py:135:10:135:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:135:16:135:16 | SSA variable y | semmle.label | SSA variable y |
|
||||
| test.py:135:21:135:28 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:135:22:135:27 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:136:10:136:10 | ControlFlowNode for x [Set element] | semmle.label | ControlFlowNode for x [Set element] |
|
||||
| test.py:136:10:136:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:140:9:140:16 | ControlFlowNode for Set [Set element] | semmle.label | ControlFlowNode for Set [Set element] |
|
||||
| test.py:140:10:140:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:141:9:141:22 | ControlFlowNode for SetComp [Set element] | semmle.label | ControlFlowNode for SetComp [Set element] |
|
||||
| test.py:141:10:141:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:141:16:141:16 | SSA variable y | semmle.label | SSA variable y |
|
||||
| test.py:141:21:141:21 | ControlFlowNode for l [Set element] | semmle.label | ControlFlowNode for l [Set element] |
|
||||
| test.py:142:10:142:10 | ControlFlowNode for x [Set element] | semmle.label | ControlFlowNode for x [Set element] |
|
||||
| test.py:142:10:142:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:152:9:152:21 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:152:15:152:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:153:10:153:10 | ControlFlowNode for x [Dictionary element at key s] | semmle.label | ControlFlowNode for x [Dictionary element at key s] |
|
||||
| test.py:153:10:153:15 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:157:9:157:21 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:157:15:157:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:158:10:158:10 | ControlFlowNode for x [Dictionary element at key s] | semmle.label | ControlFlowNode for x [Dictionary element at key s] |
|
||||
| test.py:158:10:158:19 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:183:9:183:42 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:183:10:183:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:183:16:183:16 | SSA variable z [List element] | semmle.label | SSA variable z [List element] |
|
||||
| test.py:183:21:183:30 | ControlFlowNode for List [List element, List element] | semmle.label | ControlFlowNode for List [List element, List element] |
|
||||
| test.py:183:22:183:29 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:183:23:183:28 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:183:36:183:36 | SSA variable y | semmle.label | SSA variable y |
|
||||
| test.py:183:41:183:41 | ControlFlowNode for z [List element] | semmle.label | ControlFlowNode for z [List element] |
|
||||
| test.py:184:10:184:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
|
||||
| test.py:184:10:184:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:188:9:188:68 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:188:10:188:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:188:16:188:16 | SSA variable v [List element, List element, List element] | semmle.label | SSA variable v [List element, List element, List element] |
|
||||
| test.py:188:21:188:34 | ControlFlowNode for List [List element, List element, List element, List element] | semmle.label | ControlFlowNode for List [List element, List element, List element, List element] |
|
||||
| test.py:188:22:188:33 | ControlFlowNode for List [List element, List element, List element] | semmle.label | ControlFlowNode for List [List element, List element, List element] |
|
||||
| test.py:188:23:188:32 | ControlFlowNode for List [List element, List element] | semmle.label | ControlFlowNode for List [List element, List element] |
|
||||
| test.py:188:24:188:31 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:188:25:188:30 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:188:40:188:40 | SSA variable u [List element, List element] | semmle.label | SSA variable u [List element, List element] |
|
||||
| test.py:188:45:188:45 | ControlFlowNode for v [List element, List element, List element] | semmle.label | ControlFlowNode for v [List element, List element, List element] |
|
||||
| test.py:188:51:188:51 | SSA variable z [List element] | semmle.label | SSA variable z [List element] |
|
||||
| test.py:188:56:188:56 | ControlFlowNode for u [List element, List element] | semmle.label | ControlFlowNode for u [List element, List element] |
|
||||
| test.py:188:62:188:62 | SSA variable y | semmle.label | SSA variable y |
|
||||
| test.py:188:67:188:67 | ControlFlowNode for z [List element] | semmle.label | ControlFlowNode for z [List element] |
|
||||
| test.py:189:10:189:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
|
||||
| test.py:189:10:189:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:199:9:199:42 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:199:10:199:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:199:16:199:16 | SSA variable y | semmle.label | SSA variable y |
|
||||
| test.py:199:22:199:22 | ControlFlowNode for z | semmle.label | ControlFlowNode for z |
|
||||
| test.py:199:22:199:40 | ControlFlowNode for GeneratorExp [List element] | semmle.label | ControlFlowNode for GeneratorExp [List element] |
|
||||
| test.py:199:28:199:28 | SSA variable z | semmle.label | SSA variable z |
|
||||
| test.py:199:33:199:40 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:199:34:199:39 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:200:10:200:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
|
||||
| test.py:200:10:200:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:205:9:205:47 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:205:10:205:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
|
||||
| test.py:205:17:205:17 | SSA variable a | semmle.label | SSA variable a |
|
||||
| test.py:205:17:205:20 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:205:17:205:20 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:205:26:205:46 | ControlFlowNode for List [List element, Tuple element at index 0] | semmle.label | ControlFlowNode for List [List element, Tuple element at index 0] |
|
||||
| test.py:205:28:205:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:205:28:205:44 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:206:10:206:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
|
||||
| test.py:206:10:206:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:210:9:210:51 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:210:10:210:10 | ControlFlowNode for a [List element] | semmle.label | ControlFlowNode for a [List element] |
|
||||
| test.py:210:10:210:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:210:20:210:21 | IterableElement | semmle.label | IterableElement |
|
||||
| test.py:210:20:210:21 | SSA variable a [List element] | semmle.label | SSA variable a [List element] |
|
||||
| test.py:210:20:210:24 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:210:20:210:24 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:210:30:210:50 | ControlFlowNode for List [List element, Tuple element at index 0] | semmle.label | ControlFlowNode for List [List element, Tuple element at index 0] |
|
||||
| test.py:210:32:210:37 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:210:32:210:48 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:211:10:211:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
|
||||
| test.py:211:10:211:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:349:10:349:21 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:349:11:349:16 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:349:11:349:17 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:353:10:353:17 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:353:10:353:20 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:353:11:353:16 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:357:10:357:22 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:357:10:357:27 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:357:16:357:21 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:375:15:375:15 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
|
||||
| test.py:376:12:376:12 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
|
||||
| test.py:380:10:380:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
|
||||
| test.py:380:28:380:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:388:10:388:36 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
|
||||
| test.py:388:30:388:35 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:396:10:396:43 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
|
||||
| test.py:396:10:396:43 | KwUnpacked b | semmle.label | KwUnpacked b |
|
||||
| test.py:396:30:396:42 | ControlFlowNode for Dict [Dictionary element at key b] | semmle.label | ControlFlowNode for Dict [Dictionary element at key b] |
|
||||
| test.py:396:36:396:41 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:399:21:399:21 | ControlFlowNode for b [Tuple element at index 0] | semmle.label | ControlFlowNode for b [Tuple element at index 0] |
|
||||
| test.py:400:12:400:12 | ControlFlowNode for b [Tuple element at index 0] | semmle.label | ControlFlowNode for b [Tuple element at index 0] |
|
||||
| test.py:400:12:400:15 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:404:10:404:39 | ControlFlowNode for f_extra_pos() | semmle.label | ControlFlowNode for f_extra_pos() |
|
||||
| test.py:404:10:404:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | semmle.label | PosOverflowNode for f_extra_pos() [Tuple element at index 0] |
|
||||
| test.py:404:33:404:38 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:407:26:407:26 | ControlFlowNode for b [Dictionary element at key b] | semmle.label | ControlFlowNode for b [Dictionary element at key b] |
|
||||
| test.py:408:12:408:12 | ControlFlowNode for b [Dictionary element at key b] | semmle.label | ControlFlowNode for b [Dictionary element at key b] |
|
||||
| test.py:408:12:408:17 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:412:10:412:45 | ControlFlowNode for f_extra_keyword() | semmle.label | ControlFlowNode for f_extra_keyword() |
|
||||
| test.py:412:10:412:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | semmle.label | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] |
|
||||
| test.py:412:39:412:44 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:429:10:429:20 | ControlFlowNode for BoolExpr | semmle.label | ControlFlowNode for BoolExpr |
|
||||
| test.py:429:15:429:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:434:10:434:21 | ControlFlowNode for BoolExpr | semmle.label | ControlFlowNode for BoolExpr |
|
||||
| test.py:434:16:434:21 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:445:10:445:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:445:10:445:38 | ControlFlowNode for IfExp | semmle.label | ControlFlowNode for IfExp |
|
||||
| test.py:453:10:453:39 | ControlFlowNode for IfExp | semmle.label | ControlFlowNode for IfExp |
|
||||
| test.py:453:34:453:39 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:474:11:474:11 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:475:16:475:16 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:477:10:477:18 | ControlFlowNode for f() | semmle.label | ControlFlowNode for f() |
|
||||
| test.py:477:12:477:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:481:19:481:19 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
|
||||
| test.py:482:16:482:16 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
|
||||
| test.py:484:10:484:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
|
||||
| test.py:484:28:484:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:495:19:495:19 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
|
||||
| test.py:496:16:496:16 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
|
||||
| test.py:498:10:498:36 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
|
||||
| test.py:498:30:498:35 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:509:19:509:19 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
|
||||
| test.py:510:16:510:16 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
|
||||
| test.py:512:10:512:43 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
|
||||
| test.py:512:10:512:43 | KwUnpacked b | semmle.label | KwUnpacked b |
|
||||
| test.py:512:30:512:42 | ControlFlowNode for Dict [Dictionary element at key b] | semmle.label | ControlFlowNode for Dict [Dictionary element at key b] |
|
||||
| test.py:512:36:512:41 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:516:30:516:30 | ControlFlowNode for b [Tuple element at index 0] | semmle.label | ControlFlowNode for b [Tuple element at index 0] |
|
||||
| test.py:516:33:516:33 | ControlFlowNode for b [Tuple element at index 0] | semmle.label | ControlFlowNode for b [Tuple element at index 0] |
|
||||
| test.py:516:33:516:36 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:517:10:517:39 | ControlFlowNode for f_extra_pos() | semmle.label | ControlFlowNode for f_extra_pos() |
|
||||
| test.py:517:10:517:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | semmle.label | PosOverflowNode for f_extra_pos() [Tuple element at index 0] |
|
||||
| test.py:517:33:517:38 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:521:35:521:35 | ControlFlowNode for b [Dictionary element at key b] | semmle.label | ControlFlowNode for b [Dictionary element at key b] |
|
||||
| test.py:521:38:521:38 | ControlFlowNode for b [Dictionary element at key b] | semmle.label | ControlFlowNode for b [Dictionary element at key b] |
|
||||
| test.py:521:38:521:43 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:522:10:522:45 | ControlFlowNode for f_extra_keyword() | semmle.label | ControlFlowNode for f_extra_keyword() |
|
||||
| test.py:522:10:522:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | semmle.label | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] |
|
||||
| test.py:522:39:522:44 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:534:9:534:14 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:536:10:536:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
|
||||
| test.py:541:10:541:10 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
|
||||
| test.py:546:10:546:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:546:10:546:26 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:547:5:547:5 | SSA variable a | semmle.label | SSA variable a |
|
||||
| test.py:547:5:547:8 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:548:10:548:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
|
||||
| test.py:554:10:554:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:554:10:554:36 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:554:10:554:36 | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 1] |
|
||||
| test.py:554:19:554:35 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:554:30:554:35 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:555:5:555:5 | SSA variable a | semmle.label | SSA variable a |
|
||||
| test.py:555:5:555:13 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:555:5:555:13 | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1, Tuple element at index 1] |
|
||||
| test.py:555:9:555:12 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:555:9:555:12 | IterableSequence [Tuple element at index 1] | semmle.label | IterableSequence [Tuple element at index 1] |
|
||||
| test.py:555:12:555:12 | SSA variable c | semmle.label | SSA variable c |
|
||||
| test.py:556:10:556:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
|
||||
| test.py:558:10:558:10 | ControlFlowNode for c | semmle.label | ControlFlowNode for c |
|
||||
| test.py:563:9:563:33 | ControlFlowNode for List [List element, List element, List element, List element] | semmle.label | ControlFlowNode for List [List element, List element, List element, List element] |
|
||||
| test.py:563:10:563:21 | ControlFlowNode for List [List element, List element, List element] | semmle.label | ControlFlowNode for List [List element, List element, List element] |
|
||||
| test.py:563:11:563:20 | ControlFlowNode for List [List element, List element] | semmle.label | ControlFlowNode for List [List element, List element] |
|
||||
| test.py:563:12:563:19 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:563:13:563:18 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:564:5:564:11 | ControlFlowNode for List [Tuple element at index 0, List element, List element] | semmle.label | ControlFlowNode for List [Tuple element at index 0, List element, List element] |
|
||||
| test.py:564:5:564:11 | IterableElement [List element, List element] | semmle.label | IterableElement [List element, List element] |
|
||||
| test.py:564:5:564:11 | IterableSequence [List element, List element, List element] | semmle.label | IterableSequence [List element, List element, List element] |
|
||||
| test.py:564:5:564:14 | ControlFlowNode for Tuple [Tuple element at index 0, List element, List element, List element] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, List element, List element, List element] |
|
||||
| test.py:564:5:564:14 | IterableElement [List element, List element, List element] | semmle.label | IterableElement [List element, List element, List element] |
|
||||
| test.py:564:5:564:14 | IterableSequence [List element, List element, List element, List element] | semmle.label | IterableSequence [List element, List element, List element, List element] |
|
||||
| test.py:564:6:564:10 | ControlFlowNode for List [Tuple element at index 0, List element] | semmle.label | ControlFlowNode for List [Tuple element at index 0, List element] |
|
||||
| test.py:564:6:564:10 | IterableElement [List element] | semmle.label | IterableElement [List element] |
|
||||
| test.py:564:6:564:10 | IterableSequence [List element, List element] | semmle.label | IterableSequence [List element, List element] |
|
||||
| test.py:564:7:564:9 | ControlFlowNode for List [Tuple element at index 0] | semmle.label | ControlFlowNode for List [Tuple element at index 0] |
|
||||
| test.py:564:7:564:9 | IterableElement | semmle.label | IterableElement |
|
||||
| test.py:564:7:564:9 | IterableSequence [List element] | semmle.label | IterableSequence [List element] |
|
||||
| test.py:564:8:564:8 | SSA variable a | semmle.label | SSA variable a |
|
||||
| test.py:565:10:565:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
|
||||
| test.py:571:10:571:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:571:10:571:34 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:571:10:571:34 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:571:18:571:23 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:572:5:572:5 | SSA variable a | semmle.label | SSA variable a |
|
||||
| test.py:572:5:572:12 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:572:5:572:12 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:572:8:572:9 | IterableElement | semmle.label | IterableElement |
|
||||
| test.py:572:8:572:9 | SSA variable b [List element] | semmle.label | SSA variable b [List element] |
|
||||
| test.py:572:12:572:12 | SSA variable c | semmle.label | SSA variable c |
|
||||
| test.py:573:10:573:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
|
||||
| test.py:575:10:575:10 | ControlFlowNode for b [List element] | semmle.label | ControlFlowNode for b [List element] |
|
||||
| test.py:575:10:575:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:576:12:576:12 | ControlFlowNode for c | semmle.label | ControlFlowNode for c |
|
||||
| test.py:581:10:581:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:581:10:581:23 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:581:10:581:23 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:581:18:581:23 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:582:5:582:5 | SSA variable a | semmle.label | SSA variable a |
|
||||
| test.py:582:5:582:12 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:582:5:582:12 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:582:12:582:12 | SSA variable c | semmle.label | SSA variable c |
|
||||
| test.py:583:10:583:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
|
||||
| test.py:585:10:585:10 | ControlFlowNode for c | semmle.label | ControlFlowNode for c |
|
||||
| test.py:590:10:590:61 | ControlFlowNode for List [List element, List element] | semmle.label | ControlFlowNode for List [List element, List element] |
|
||||
| test.py:590:11:590:37 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:590:12:590:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:590:31:590:36 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:590:40:590:47 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:590:41:590:46 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:593:6:593:23 | ControlFlowNode for Tuple [Tuple element at index 0, List element] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, List element] |
|
||||
| test.py:593:6:593:23 | IterableElement [List element] | semmle.label | IterableElement [List element] |
|
||||
| test.py:593:6:593:23 | IterableSequence [List element, List element] | semmle.label | IterableSequence [List element, List element] |
|
||||
| test.py:593:7:593:8 | SSA variable a1 | semmle.label | SSA variable a1 |
|
||||
| test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:593:7:593:16 | ControlFlowNode for Tuple [Tuple element at index 2] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 2] |
|
||||
| test.py:593:7:593:16 | IterableElement | semmle.label | IterableElement |
|
||||
| test.py:593:7:593:16 | IterableSequence [List element] | semmle.label | IterableSequence [List element] |
|
||||
| test.py:593:11:593:12 | SSA variable a2 | semmle.label | SSA variable a2 |
|
||||
| test.py:593:15:593:16 | SSA variable a3 | semmle.label | SSA variable a3 |
|
||||
| test.py:594:10:594:11 | ControlFlowNode for a1 | semmle.label | ControlFlowNode for a1 |
|
||||
| test.py:595:12:595:13 | ControlFlowNode for a2 | semmle.label | ControlFlowNode for a2 |
|
||||
| test.py:596:10:596:11 | ControlFlowNode for a3 | semmle.label | ControlFlowNode for a3 |
|
||||
| test.py:601:5:601:24 | ControlFlowNode for List [Tuple element at index 0, List element] | semmle.label | ControlFlowNode for List [Tuple element at index 0, List element] |
|
||||
| test.py:601:5:601:24 | IterableElement [List element] | semmle.label | IterableElement [List element] |
|
||||
| test.py:601:5:601:24 | IterableSequence [List element, List element] | semmle.label | IterableSequence [List element, List element] |
|
||||
| test.py:601:7:601:8 | SSA variable a1 | semmle.label | SSA variable a1 |
|
||||
| test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:601:7:601:16 | ControlFlowNode for Tuple [Tuple element at index 2] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 2] |
|
||||
| test.py:601:7:601:16 | IterableElement | semmle.label | IterableElement |
|
||||
| test.py:601:7:601:16 | IterableSequence [List element] | semmle.label | IterableSequence [List element] |
|
||||
| test.py:601:11:601:12 | SSA variable a2 | semmle.label | SSA variable a2 |
|
||||
| test.py:601:15:601:16 | SSA variable a3 | semmle.label | SSA variable a3 |
|
||||
| test.py:602:10:602:11 | ControlFlowNode for a1 | semmle.label | ControlFlowNode for a1 |
|
||||
| test.py:603:12:603:13 | ControlFlowNode for a2 | semmle.label | ControlFlowNode for a2 |
|
||||
| test.py:604:10:604:11 | ControlFlowNode for a3 | semmle.label | ControlFlowNode for a3 |
|
||||
| test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 0] | semmle.label | ControlFlowNode for List [Tuple element at index 0] |
|
||||
| test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 1] | semmle.label | ControlFlowNode for List [Tuple element at index 1] |
|
||||
| test.py:609:6:609:17 | ControlFlowNode for List [Tuple element at index 2] | semmle.label | ControlFlowNode for List [Tuple element at index 2] |
|
||||
| test.py:609:6:609:17 | IterableElement | semmle.label | IterableElement |
|
||||
| test.py:609:6:609:17 | IterableSequence [List element] | semmle.label | IterableSequence [List element] |
|
||||
| test.py:609:6:609:23 | ControlFlowNode for Tuple [Tuple element at index 0, List element] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, List element] |
|
||||
| test.py:609:6:609:23 | IterableElement [List element] | semmle.label | IterableElement [List element] |
|
||||
| test.py:609:6:609:23 | IterableSequence [List element, List element] | semmle.label | IterableSequence [List element, List element] |
|
||||
| test.py:609:7:609:8 | SSA variable a1 | semmle.label | SSA variable a1 |
|
||||
| test.py:609:11:609:12 | SSA variable a2 | semmle.label | SSA variable a2 |
|
||||
| test.py:609:15:609:16 | SSA variable a3 | semmle.label | SSA variable a3 |
|
||||
| test.py:610:10:610:11 | ControlFlowNode for a1 | semmle.label | ControlFlowNode for a1 |
|
||||
| test.py:611:12:611:13 | ControlFlowNode for a2 | semmle.label | ControlFlowNode for a2 |
|
||||
| test.py:612:10:612:11 | ControlFlowNode for a3 | semmle.label | ControlFlowNode for a3 |
|
||||
| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] |
|
||||
| test.py:618:11:618:47 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] |
|
||||
| test.py:618:12:618:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:618:12:618:36 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:618:12:618:36 | ControlFlowNode for Tuple [Tuple element at index 2] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 2] |
|
||||
| test.py:618:31:618:36 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:621:5:621:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 0] | semmle.label | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 0] |
|
||||
| test.py:621:5:621:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 2] | semmle.label | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 2] |
|
||||
| test.py:621:6:621:14 | ControlFlowNode for List [Tuple element at index 0] | semmle.label | ControlFlowNode for List [Tuple element at index 0] |
|
||||
| test.py:621:6:621:14 | ControlFlowNode for List [Tuple element at index 2] | semmle.label | ControlFlowNode for List [Tuple element at index 2] |
|
||||
| test.py:621:6:621:14 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:621:6:621:14 | IterableSequence [Tuple element at index 2] | semmle.label | IterableSequence [Tuple element at index 2] |
|
||||
| test.py:621:7:621:8 | SSA variable a1 | semmle.label | SSA variable a1 |
|
||||
| test.py:621:11:621:13 | IterableElement | semmle.label | IterableElement |
|
||||
| test.py:621:11:621:13 | SSA variable a2 [List element] | semmle.label | SSA variable a2 [List element] |
|
||||
| test.py:622:10:622:11 | ControlFlowNode for a1 | semmle.label | ControlFlowNode for a1 |
|
||||
| test.py:624:12:624:13 | ControlFlowNode for a2 [List element] | semmle.label | ControlFlowNode for a2 [List element] |
|
||||
| test.py:624:12:624:16 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:625:10:625:11 | ControlFlowNode for a2 [List element] | semmle.label | ControlFlowNode for a2 [List element] |
|
||||
| test.py:625:10:625:14 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:630:6:630:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] |
|
||||
| test.py:630:6:630:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] |
|
||||
| test.py:630:7:630:8 | SSA variable a1 | semmle.label | SSA variable a1 |
|
||||
| test.py:630:7:630:13 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:630:7:630:13 | ControlFlowNode for Tuple [Tuple element at index 2] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 2] |
|
||||
| test.py:630:7:630:13 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:630:7:630:13 | IterableSequence [Tuple element at index 2] | semmle.label | IterableSequence [Tuple element at index 2] |
|
||||
| test.py:630:11:630:13 | IterableElement | semmle.label | IterableElement |
|
||||
| test.py:630:11:630:13 | SSA variable a2 [List element] | semmle.label | SSA variable a2 [List element] |
|
||||
| test.py:631:10:631:11 | ControlFlowNode for a1 | semmle.label | ControlFlowNode for a1 |
|
||||
| test.py:633:12:633:13 | ControlFlowNode for a2 [List element] | semmle.label | ControlFlowNode for a2 [List element] |
|
||||
| test.py:633:12:633:16 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:634:10:634:11 | ControlFlowNode for a2 [List element] | semmle.label | ControlFlowNode for a2 [List element] |
|
||||
| test.py:634:10:634:14 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:639:5:639:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 0] | semmle.label | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 0] |
|
||||
| test.py:639:5:639:19 | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 2] | semmle.label | ControlFlowNode for List [Tuple element at index 0, Tuple element at index 2] |
|
||||
| test.py:639:7:639:8 | SSA variable a1 | semmle.label | SSA variable a1 |
|
||||
| test.py:639:7:639:13 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:639:7:639:13 | ControlFlowNode for Tuple [Tuple element at index 2] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 2] |
|
||||
| test.py:639:7:639:13 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:639:7:639:13 | IterableSequence [Tuple element at index 2] | semmle.label | IterableSequence [Tuple element at index 2] |
|
||||
| test.py:639:11:639:13 | IterableElement | semmle.label | IterableElement |
|
||||
| test.py:639:11:639:13 | SSA variable a2 [List element] | semmle.label | SSA variable a2 [List element] |
|
||||
| test.py:640:10:640:11 | ControlFlowNode for a1 | semmle.label | ControlFlowNode for a1 |
|
||||
| test.py:642:12:642:13 | ControlFlowNode for a2 [List element] | semmle.label | ControlFlowNode for a2 [List element] |
|
||||
| test.py:642:12:642:16 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:643:10:643:11 | ControlFlowNode for a2 [List element] | semmle.label | ControlFlowNode for a2 [List element] |
|
||||
| test.py:643:10:643:14 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:648:6:648:14 | ControlFlowNode for List [Tuple element at index 0] | semmle.label | ControlFlowNode for List [Tuple element at index 0] |
|
||||
| test.py:648:6:648:14 | ControlFlowNode for List [Tuple element at index 2] | semmle.label | ControlFlowNode for List [Tuple element at index 2] |
|
||||
| test.py:648:6:648:14 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:648:6:648:14 | IterableSequence [Tuple element at index 2] | semmle.label | IterableSequence [Tuple element at index 2] |
|
||||
| test.py:648:6:648:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 0] |
|
||||
| test.py:648:6:648:18 | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0, Tuple element at index 2] |
|
||||
| test.py:648:7:648:8 | SSA variable a1 | semmle.label | SSA variable a1 |
|
||||
| test.py:648:11:648:13 | IterableElement | semmle.label | IterableElement |
|
||||
| test.py:648:11:648:13 | SSA variable a2 [List element] | semmle.label | SSA variable a2 [List element] |
|
||||
| test.py:649:10:649:11 | ControlFlowNode for a1 | semmle.label | ControlFlowNode for a1 |
|
||||
| test.py:651:12:651:13 | ControlFlowNode for a2 [List element] | semmle.label | ControlFlowNode for a2 [List element] |
|
||||
| test.py:651:12:651:16 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:652:10:652:11 | ControlFlowNode for a2 [List element] | semmle.label | ControlFlowNode for a2 [List element] |
|
||||
| test.py:652:10:652:14 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:659:19:659:24 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:660:10:660:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
|
||||
| test.py:667:10:667:51 | ControlFlowNode for List [List element, Tuple element at index 0] | semmle.label | ControlFlowNode for List [List element, Tuple element at index 0] |
|
||||
| test.py:667:12:667:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:667:12:667:28 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:667:33:667:38 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:667:33:667:49 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:668:9:668:9 | SSA variable x | semmle.label | SSA variable x |
|
||||
| test.py:668:9:668:11 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:668:9:668:11 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:668:16:668:17 | ControlFlowNode for tl [List element, Tuple element at index 0] | semmle.label | ControlFlowNode for tl [List element, Tuple element at index 0] |
|
||||
| test.py:669:14:669:14 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:675:10:675:51 | ControlFlowNode for List [List element, Tuple element at index 0] | semmle.label | ControlFlowNode for List [List element, Tuple element at index 0] |
|
||||
| test.py:675:12:675:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:675:12:675:28 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:675:33:675:38 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:675:33:675:49 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:676:9:676:10 | IterableElement | semmle.label | IterableElement |
|
||||
| test.py:676:9:676:10 | SSA variable x [List element] | semmle.label | SSA variable x [List element] |
|
||||
| test.py:676:9:676:12 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:676:9:676:12 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:676:12:676:12 | SSA variable y | semmle.label | SSA variable y |
|
||||
| test.py:676:17:676:18 | ControlFlowNode for tl [List element, Tuple element at index 0] | semmle.label | ControlFlowNode for tl [List element, Tuple element at index 0] |
|
||||
| test.py:678:14:678:14 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
|
||||
| test.py:678:14:678:17 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:679:16:679:16 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:684:10:684:51 | ControlFlowNode for List [List element, Tuple element at index 0] | semmle.label | ControlFlowNode for List [List element, Tuple element at index 0] |
|
||||
| test.py:684:12:684:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:684:12:684:28 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:684:33:684:38 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:684:33:684:49 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:685:9:685:9 | SSA variable x | semmle.label | SSA variable x |
|
||||
| test.py:685:9:685:14 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:685:9:685:14 | IterableSequence [Tuple element at index 0] | semmle.label | IterableSequence [Tuple element at index 0] |
|
||||
| test.py:685:19:685:20 | ControlFlowNode for tl [List element, Tuple element at index 0] | semmle.label | ControlFlowNode for tl [List element, Tuple element at index 0] |
|
||||
| test.py:686:14:686:14 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:690:39:690:42 | ControlFlowNode for args [Tuple element at index 0] | semmle.label | ControlFlowNode for args [Tuple element at index 0] |
|
||||
| test.py:690:39:690:42 | ControlFlowNode for args [Tuple element at index 1] | semmle.label | ControlFlowNode for args [Tuple element at index 1] |
|
||||
| test.py:691:7:691:9 | SSA variable arg | semmle.label | SSA variable arg |
|
||||
| test.py:691:14:691:17 | ControlFlowNode for args [Tuple element at index 0] | semmle.label | ControlFlowNode for args [Tuple element at index 0] |
|
||||
| test.py:691:14:691:17 | ControlFlowNode for args [Tuple element at index 1] | semmle.label | ControlFlowNode for args [Tuple element at index 1] |
|
||||
| test.py:692:10:692:12 | ControlFlowNode for arg | semmle.label | ControlFlowNode for arg |
|
||||
| test.py:697:7:697:12 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:698:3:698:52 | PosOverflowNode for iterate_star_args() [Tuple element at index 0] | semmle.label | PosOverflowNode for iterate_star_args() [Tuple element at index 0] |
|
||||
| test.py:698:3:698:52 | PosOverflowNode for iterate_star_args() [Tuple element at index 1] | semmle.label | PosOverflowNode for iterate_star_args() [Tuple element at index 1] |
|
||||
| test.py:698:43:698:48 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:698:51:698:51 | ControlFlowNode for s | semmle.label | ControlFlowNode for s |
|
||||
| test.py:769:16:769:21 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:772:10:772:36 | ControlFlowNode for return_from_inner_scope() | semmle.label | ControlFlowNode for return_from_inner_scope() |
|
||||
| test.py:807:35:807:35 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:807:37:807:42 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:807:48:807:48 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:807:50:807:55 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:807:61:807:61 | ControlFlowNode for z | semmle.label | ControlFlowNode for z |
|
||||
| test.py:807:63:807:68 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:808:10:808:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:809:10:809:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:810:10:810:10 | ControlFlowNode for z | semmle.label | ControlFlowNode for z |
|
||||
subpaths
|
||||
| datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:35:7:35:7 | ControlFlowNode for a | datamodel.py:36:10:36:10 | ControlFlowNode for a | datamodel.py:38:6:38:17 | ControlFlowNode for f() |
|
||||
| datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:44:22:44:22 | ControlFlowNode for x | datamodel.py:46:16:46:16 | ControlFlowNode for x | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:44:22:44:22 | ControlFlowNode for x | datamodel.py:46:16:46:16 | ControlFlowNode for x | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:49:26:49:26 | ControlFlowNode for x | datamodel.py:50:16:50:16 | ControlFlowNode for x | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:49:26:49:26 | ControlFlowNode for x | datamodel.py:50:16:50:16 | ControlFlowNode for x | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() |
|
||||
| test.py:380:28:380:33 | ControlFlowNode for SOURCE | test.py:375:15:375:15 | ControlFlowNode for b | test.py:376:12:376:12 | ControlFlowNode for b | test.py:380:10:380:34 | ControlFlowNode for second() |
|
||||
| test.py:388:30:388:35 | ControlFlowNode for SOURCE | test.py:375:15:375:15 | ControlFlowNode for b | test.py:376:12:376:12 | ControlFlowNode for b | test.py:388:10:388:36 | ControlFlowNode for second() |
|
||||
| test.py:396:10:396:43 | KwUnpacked b | test.py:375:15:375:15 | ControlFlowNode for b | test.py:376:12:376:12 | ControlFlowNode for b | test.py:396:10:396:43 | ControlFlowNode for second() |
|
||||
| test.py:404:10:404:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:399:21:399:21 | ControlFlowNode for b [Tuple element at index 0] | test.py:400:12:400:15 | ControlFlowNode for Subscript | test.py:404:10:404:39 | ControlFlowNode for f_extra_pos() |
|
||||
| test.py:412:10:412:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:407:26:407:26 | ControlFlowNode for b [Dictionary element at key b] | test.py:408:12:408:17 | ControlFlowNode for Subscript | test.py:412:10:412:45 | ControlFlowNode for f_extra_keyword() |
|
||||
| test.py:477:12:477:17 | ControlFlowNode for SOURCE | test.py:474:11:474:11 | ControlFlowNode for x | test.py:475:16:475:16 | ControlFlowNode for x | test.py:477:10:477:18 | ControlFlowNode for f() |
|
||||
| test.py:484:28:484:33 | ControlFlowNode for SOURCE | test.py:481:19:481:19 | ControlFlowNode for b | test.py:482:16:482:16 | ControlFlowNode for b | test.py:484:10:484:34 | ControlFlowNode for second() |
|
||||
| test.py:498:30:498:35 | ControlFlowNode for SOURCE | test.py:495:19:495:19 | ControlFlowNode for b | test.py:496:16:496:16 | ControlFlowNode for b | test.py:498:10:498:36 | ControlFlowNode for second() |
|
||||
| test.py:512:10:512:43 | KwUnpacked b | test.py:509:19:509:19 | ControlFlowNode for b | test.py:510:16:510:16 | ControlFlowNode for b | test.py:512:10:512:43 | ControlFlowNode for second() |
|
||||
| test.py:517:10:517:39 | PosOverflowNode for f_extra_pos() [Tuple element at index 0] | test.py:516:30:516:30 | ControlFlowNode for b [Tuple element at index 0] | test.py:516:33:516:36 | ControlFlowNode for Subscript | test.py:517:10:517:39 | ControlFlowNode for f_extra_pos() |
|
||||
| test.py:522:10:522:45 | KwOverflowNode for f_extra_keyword() [Dictionary element at key b] | test.py:521:35:521:35 | ControlFlowNode for b [Dictionary element at key b] | test.py:521:38:521:43 | ControlFlowNode for Subscript | test.py:522:10:522:45 | ControlFlowNode for f_extra_keyword() |
|
||||
#select
|
||||
| datamodel.py:38:6:38:17 | ControlFlowNode for f() | datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:38:6:38:17 | ControlFlowNode for f() | Flow found |
|
||||
| datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | Flow found |
|
||||
| datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | Flow found |
|
||||
| datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | Flow found |
|
||||
| datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | Flow found |
|
||||
| datamodel.py:159:6:159:17 | ControlFlowNode for Attribute | datamodel.py:152:14:152:19 | ControlFlowNode for SOURCE | datamodel.py:159:6:159:17 | ControlFlowNode for Attribute | Flow found |
|
||||
| test.py:44:10:44:10 | ControlFlowNode for y | test.py:42:21:42:26 | ControlFlowNode for SOURCE | test.py:44:10:44:10 | ControlFlowNode for y | Flow found |
|
||||
| test.py:56:10:56:10 | ControlFlowNode for x | test.py:55:9:55:14 | ControlFlowNode for SOURCE | test.py:56:10:56:10 | ControlFlowNode for x | Flow found |
|
||||
| test.py:62:10:62:10 | ControlFlowNode for x | test.py:61:9:61:16 | ControlFlowNode for Str | test.py:62:10:62:10 | ControlFlowNode for x | Flow found |
|
||||
| test.py:67:10:67:10 | ControlFlowNode for x | test.py:66:9:66:17 | ControlFlowNode for Str | test.py:67:10:67:10 | ControlFlowNode for x | Flow found |
|
||||
| test.py:72:10:72:10 | ControlFlowNode for x | test.py:71:9:71:10 | ControlFlowNode for IntegerLiteral | test.py:72:10:72:10 | ControlFlowNode for x | Flow found |
|
||||
| test.py:77:10:77:10 | ControlFlowNode for x | test.py:76:9:76:12 | ControlFlowNode for FloatLiteral | test.py:77:10:77:10 | ControlFlowNode for x | Flow found |
|
||||
| test.py:88:10:88:10 | ControlFlowNode for x | test.py:87:10:87:15 | ControlFlowNode for SOURCE | test.py:88:10:88:10 | ControlFlowNode for x | Flow found |
|
||||
| test.py:94:10:94:13 | ControlFlowNode for Subscript | test.py:93:10:93:15 | ControlFlowNode for SOURCE | test.py:94:10:94:13 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:104:10:104:13 | ControlFlowNode for Subscript | test.py:103:10:103:15 | ControlFlowNode for SOURCE | test.py:104:10:104:13 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:109:10:109:13 | ControlFlowNode for Subscript | test.py:108:22:108:27 | ControlFlowNode for SOURCE | test.py:109:10:109:13 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:115:10:115:13 | ControlFlowNode for Subscript | test.py:113:10:113:15 | ControlFlowNode for SOURCE | test.py:115:10:115:13 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:126:10:126:16 | ControlFlowNode for Attribute() | test.py:125:10:125:15 | ControlFlowNode for SOURCE | test.py:126:10:126:16 | ControlFlowNode for Attribute() | Flow found |
|
||||
| test.py:131:10:131:16 | ControlFlowNode for Attribute() | test.py:130:10:130:15 | ControlFlowNode for SOURCE | test.py:131:10:131:16 | ControlFlowNode for Attribute() | Flow found |
|
||||
| test.py:136:10:136:16 | ControlFlowNode for Attribute() | test.py:135:22:135:27 | ControlFlowNode for SOURCE | test.py:136:10:136:16 | ControlFlowNode for Attribute() | Flow found |
|
||||
| test.py:142:10:142:16 | ControlFlowNode for Attribute() | test.py:140:10:140:15 | ControlFlowNode for SOURCE | test.py:142:10:142:16 | ControlFlowNode for Attribute() | Flow found |
|
||||
| test.py:153:10:153:15 | ControlFlowNode for Subscript | test.py:152:15:152:20 | ControlFlowNode for SOURCE | test.py:153:10:153:15 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:158:10:158:19 | ControlFlowNode for Attribute() | test.py:157:15:157:20 | ControlFlowNode for SOURCE | test.py:158:10:158:19 | ControlFlowNode for Attribute() | Flow found |
|
||||
| test.py:184:10:184:13 | ControlFlowNode for Subscript | test.py:183:23:183:28 | ControlFlowNode for SOURCE | test.py:184:10:184:13 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:189:10:189:13 | ControlFlowNode for Subscript | test.py:188:25:188:30 | ControlFlowNode for SOURCE | test.py:189:10:189:13 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:200:10:200:13 | ControlFlowNode for Subscript | test.py:199:34:199:39 | ControlFlowNode for SOURCE | test.py:200:10:200:13 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:206:10:206:13 | ControlFlowNode for Subscript | test.py:205:28:205:33 | ControlFlowNode for SOURCE | test.py:206:10:206:13 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:211:10:211:13 | ControlFlowNode for Subscript | test.py:210:32:210:37 | ControlFlowNode for SOURCE | test.py:211:10:211:13 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:349:10:349:21 | ControlFlowNode for Subscript | test.py:349:11:349:16 | ControlFlowNode for SOURCE | test.py:349:10:349:21 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:353:10:353:20 | ControlFlowNode for Subscript | test.py:353:11:353:16 | ControlFlowNode for SOURCE | test.py:353:10:353:20 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:357:10:357:27 | ControlFlowNode for Subscript | test.py:357:16:357:21 | ControlFlowNode for SOURCE | test.py:357:10:357:27 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:380:10:380:34 | ControlFlowNode for second() | test.py:380:28:380:33 | ControlFlowNode for SOURCE | test.py:380:10:380:34 | ControlFlowNode for second() | Flow found |
|
||||
| test.py:388:10:388:36 | ControlFlowNode for second() | test.py:388:30:388:35 | ControlFlowNode for SOURCE | test.py:388:10:388:36 | ControlFlowNode for second() | Flow found |
|
||||
| test.py:396:10:396:43 | ControlFlowNode for second() | test.py:396:36:396:41 | ControlFlowNode for SOURCE | test.py:396:10:396:43 | ControlFlowNode for second() | Flow found |
|
||||
| test.py:404:10:404:39 | ControlFlowNode for f_extra_pos() | test.py:404:33:404:38 | ControlFlowNode for SOURCE | test.py:404:10:404:39 | ControlFlowNode for f_extra_pos() | Flow found |
|
||||
| test.py:412:10:412:45 | ControlFlowNode for f_extra_keyword() | test.py:412:39:412:44 | ControlFlowNode for SOURCE | test.py:412:10:412:45 | ControlFlowNode for f_extra_keyword() | Flow found |
|
||||
| test.py:429:10:429:20 | ControlFlowNode for BoolExpr | test.py:429:15:429:20 | ControlFlowNode for SOURCE | test.py:429:10:429:20 | ControlFlowNode for BoolExpr | Flow found |
|
||||
| test.py:434:10:434:21 | ControlFlowNode for BoolExpr | test.py:434:16:434:21 | ControlFlowNode for SOURCE | test.py:434:10:434:21 | ControlFlowNode for BoolExpr | Flow found |
|
||||
| test.py:445:10:445:38 | ControlFlowNode for IfExp | test.py:445:10:445:15 | ControlFlowNode for SOURCE | test.py:445:10:445:38 | ControlFlowNode for IfExp | Flow found |
|
||||
| test.py:453:10:453:39 | ControlFlowNode for IfExp | test.py:453:34:453:39 | ControlFlowNode for SOURCE | test.py:453:10:453:39 | ControlFlowNode for IfExp | Flow found |
|
||||
| test.py:477:10:477:18 | ControlFlowNode for f() | test.py:477:12:477:17 | ControlFlowNode for SOURCE | test.py:477:10:477:18 | ControlFlowNode for f() | Flow found |
|
||||
| test.py:484:10:484:34 | ControlFlowNode for second() | test.py:484:28:484:33 | ControlFlowNode for SOURCE | test.py:484:10:484:34 | ControlFlowNode for second() | Flow found |
|
||||
| test.py:498:10:498:36 | ControlFlowNode for second() | test.py:498:30:498:35 | ControlFlowNode for SOURCE | test.py:498:10:498:36 | ControlFlowNode for second() | Flow found |
|
||||
| test.py:512:10:512:43 | ControlFlowNode for second() | test.py:512:36:512:41 | ControlFlowNode for SOURCE | test.py:512:10:512:43 | ControlFlowNode for second() | Flow found |
|
||||
| test.py:517:10:517:39 | ControlFlowNode for f_extra_pos() | test.py:517:33:517:38 | ControlFlowNode for SOURCE | test.py:517:10:517:39 | ControlFlowNode for f_extra_pos() | Flow found |
|
||||
| test.py:522:10:522:45 | ControlFlowNode for f_extra_keyword() | test.py:522:39:522:44 | ControlFlowNode for SOURCE | test.py:522:10:522:45 | ControlFlowNode for f_extra_keyword() | Flow found |
|
||||
| test.py:536:10:536:10 | ControlFlowNode for a | test.py:534:9:534:14 | ControlFlowNode for SOURCE | test.py:536:10:536:10 | ControlFlowNode for a | Flow found |
|
||||
| test.py:541:10:541:10 | ControlFlowNode for b | test.py:534:9:534:14 | ControlFlowNode for SOURCE | test.py:541:10:541:10 | ControlFlowNode for b | Flow found |
|
||||
| test.py:548:10:548:10 | ControlFlowNode for a | test.py:546:10:546:15 | ControlFlowNode for SOURCE | test.py:548:10:548:10 | ControlFlowNode for a | Flow found |
|
||||
| test.py:556:10:556:10 | ControlFlowNode for a | test.py:554:10:554:15 | ControlFlowNode for SOURCE | test.py:556:10:556:10 | ControlFlowNode for a | Flow found |
|
||||
| test.py:558:10:558:10 | ControlFlowNode for c | test.py:554:30:554:35 | ControlFlowNode for SOURCE | test.py:558:10:558:10 | ControlFlowNode for c | Flow found |
|
||||
| test.py:565:10:565:10 | ControlFlowNode for a | test.py:563:13:563:18 | ControlFlowNode for SOURCE | test.py:565:10:565:10 | ControlFlowNode for a | Flow found |
|
||||
| test.py:573:10:573:10 | ControlFlowNode for a | test.py:571:10:571:15 | ControlFlowNode for SOURCE | test.py:573:10:573:10 | ControlFlowNode for a | Flow found |
|
||||
| test.py:575:10:575:13 | ControlFlowNode for Subscript | test.py:571:18:571:23 | ControlFlowNode for SOURCE | test.py:575:10:575:13 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:576:12:576:12 | ControlFlowNode for c | test.py:571:18:571:23 | ControlFlowNode for SOURCE | test.py:576:12:576:12 | ControlFlowNode for c | Flow found |
|
||||
| test.py:583:10:583:10 | ControlFlowNode for a | test.py:581:10:581:15 | ControlFlowNode for SOURCE | test.py:583:10:583:10 | ControlFlowNode for a | Flow found |
|
||||
| test.py:585:10:585:10 | ControlFlowNode for c | test.py:581:18:581:23 | ControlFlowNode for SOURCE | test.py:585:10:585:10 | ControlFlowNode for c | Flow found |
|
||||
| test.py:594:10:594:11 | ControlFlowNode for a1 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:594:10:594:11 | ControlFlowNode for a1 | Flow found |
|
||||
| test.py:594:10:594:11 | ControlFlowNode for a1 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:594:10:594:11 | ControlFlowNode for a1 | Flow found |
|
||||
| test.py:594:10:594:11 | ControlFlowNode for a1 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:594:10:594:11 | ControlFlowNode for a1 | Flow found |
|
||||
| test.py:595:12:595:13 | ControlFlowNode for a2 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:595:12:595:13 | ControlFlowNode for a2 | Flow found |
|
||||
| test.py:595:12:595:13 | ControlFlowNode for a2 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:595:12:595:13 | ControlFlowNode for a2 | Flow found |
|
||||
| test.py:595:12:595:13 | ControlFlowNode for a2 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:595:12:595:13 | ControlFlowNode for a2 | Flow found |
|
||||
| test.py:596:10:596:11 | ControlFlowNode for a3 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:596:10:596:11 | ControlFlowNode for a3 | Flow found |
|
||||
| test.py:596:10:596:11 | ControlFlowNode for a3 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:596:10:596:11 | ControlFlowNode for a3 | Flow found |
|
||||
| test.py:596:10:596:11 | ControlFlowNode for a3 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:596:10:596:11 | ControlFlowNode for a3 | Flow found |
|
||||
| test.py:602:10:602:11 | ControlFlowNode for a1 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:602:10:602:11 | ControlFlowNode for a1 | Flow found |
|
||||
| test.py:602:10:602:11 | ControlFlowNode for a1 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:602:10:602:11 | ControlFlowNode for a1 | Flow found |
|
||||
| test.py:602:10:602:11 | ControlFlowNode for a1 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:602:10:602:11 | ControlFlowNode for a1 | Flow found |
|
||||
| test.py:603:12:603:13 | ControlFlowNode for a2 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:603:12:603:13 | ControlFlowNode for a2 | Flow found |
|
||||
| test.py:603:12:603:13 | ControlFlowNode for a2 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:603:12:603:13 | ControlFlowNode for a2 | Flow found |
|
||||
| test.py:603:12:603:13 | ControlFlowNode for a2 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:603:12:603:13 | ControlFlowNode for a2 | Flow found |
|
||||
| test.py:604:10:604:11 | ControlFlowNode for a3 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:604:10:604:11 | ControlFlowNode for a3 | Flow found |
|
||||
| test.py:604:10:604:11 | ControlFlowNode for a3 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:604:10:604:11 | ControlFlowNode for a3 | Flow found |
|
||||
| test.py:604:10:604:11 | ControlFlowNode for a3 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:604:10:604:11 | ControlFlowNode for a3 | Flow found |
|
||||
| test.py:610:10:610:11 | ControlFlowNode for a1 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:610:10:610:11 | ControlFlowNode for a1 | Flow found |
|
||||
| test.py:610:10:610:11 | ControlFlowNode for a1 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:610:10:610:11 | ControlFlowNode for a1 | Flow found |
|
||||
| test.py:610:10:610:11 | ControlFlowNode for a1 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:610:10:610:11 | ControlFlowNode for a1 | Flow found |
|
||||
| test.py:611:12:611:13 | ControlFlowNode for a2 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:611:12:611:13 | ControlFlowNode for a2 | Flow found |
|
||||
| test.py:611:12:611:13 | ControlFlowNode for a2 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:611:12:611:13 | ControlFlowNode for a2 | Flow found |
|
||||
| test.py:611:12:611:13 | ControlFlowNode for a2 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:611:12:611:13 | ControlFlowNode for a2 | Flow found |
|
||||
| test.py:612:10:612:11 | ControlFlowNode for a3 | test.py:590:12:590:17 | ControlFlowNode for SOURCE | test.py:612:10:612:11 | ControlFlowNode for a3 | Flow found |
|
||||
| test.py:612:10:612:11 | ControlFlowNode for a3 | test.py:590:31:590:36 | ControlFlowNode for SOURCE | test.py:612:10:612:11 | ControlFlowNode for a3 | Flow found |
|
||||
| test.py:612:10:612:11 | ControlFlowNode for a3 | test.py:590:41:590:46 | ControlFlowNode for SOURCE | test.py:612:10:612:11 | ControlFlowNode for a3 | Flow found |
|
||||
| test.py:622:10:622:11 | ControlFlowNode for a1 | test.py:618:12:618:17 | ControlFlowNode for SOURCE | test.py:622:10:622:11 | ControlFlowNode for a1 | Flow found |
|
||||
| test.py:624:12:624:16 | ControlFlowNode for Subscript | test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:624:12:624:16 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:625:10:625:14 | ControlFlowNode for Subscript | test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:625:10:625:14 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:631:10:631:11 | ControlFlowNode for a1 | test.py:618:12:618:17 | ControlFlowNode for SOURCE | test.py:631:10:631:11 | ControlFlowNode for a1 | Flow found |
|
||||
| test.py:633:12:633:16 | ControlFlowNode for Subscript | test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:633:12:633:16 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:634:10:634:14 | ControlFlowNode for Subscript | test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:634:10:634:14 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:640:10:640:11 | ControlFlowNode for a1 | test.py:618:12:618:17 | ControlFlowNode for SOURCE | test.py:640:10:640:11 | ControlFlowNode for a1 | Flow found |
|
||||
| test.py:642:12:642:16 | ControlFlowNode for Subscript | test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:642:12:642:16 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:643:10:643:14 | ControlFlowNode for Subscript | test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:643:10:643:14 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:649:10:649:11 | ControlFlowNode for a1 | test.py:618:12:618:17 | ControlFlowNode for SOURCE | test.py:649:10:649:11 | ControlFlowNode for a1 | Flow found |
|
||||
| test.py:651:12:651:16 | ControlFlowNode for Subscript | test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:651:12:651:16 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:652:10:652:14 | ControlFlowNode for Subscript | test.py:618:31:618:36 | ControlFlowNode for SOURCE | test.py:652:10:652:14 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:660:10:660:10 | ControlFlowNode for a | test.py:659:19:659:24 | ControlFlowNode for SOURCE | test.py:660:10:660:10 | ControlFlowNode for a | Flow found |
|
||||
| test.py:669:14:669:14 | ControlFlowNode for x | test.py:667:12:667:17 | ControlFlowNode for SOURCE | test.py:669:14:669:14 | ControlFlowNode for x | Flow found |
|
||||
| test.py:669:14:669:14 | ControlFlowNode for x | test.py:667:33:667:38 | ControlFlowNode for SOURCE | test.py:669:14:669:14 | ControlFlowNode for x | Flow found |
|
||||
| test.py:678:14:678:17 | ControlFlowNode for Subscript | test.py:675:12:675:17 | ControlFlowNode for SOURCE | test.py:678:14:678:17 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:678:14:678:17 | ControlFlowNode for Subscript | test.py:675:33:675:38 | ControlFlowNode for SOURCE | test.py:678:14:678:17 | ControlFlowNode for Subscript | Flow found |
|
||||
| test.py:679:16:679:16 | ControlFlowNode for y | test.py:675:12:675:17 | ControlFlowNode for SOURCE | test.py:679:16:679:16 | ControlFlowNode for y | Flow found |
|
||||
| test.py:679:16:679:16 | ControlFlowNode for y | test.py:675:33:675:38 | ControlFlowNode for SOURCE | test.py:679:16:679:16 | ControlFlowNode for y | Flow found |
|
||||
| test.py:686:14:686:14 | ControlFlowNode for x | test.py:684:12:684:17 | ControlFlowNode for SOURCE | test.py:686:14:686:14 | ControlFlowNode for x | Flow found |
|
||||
| test.py:686:14:686:14 | ControlFlowNode for x | test.py:684:33:684:38 | ControlFlowNode for SOURCE | test.py:686:14:686:14 | ControlFlowNode for x | Flow found |
|
||||
| test.py:692:10:692:12 | ControlFlowNode for arg | test.py:697:7:697:12 | ControlFlowNode for SOURCE | test.py:692:10:692:12 | ControlFlowNode for arg | Flow found |
|
||||
| test.py:692:10:692:12 | ControlFlowNode for arg | test.py:698:43:698:48 | ControlFlowNode for SOURCE | test.py:692:10:692:12 | ControlFlowNode for arg | Flow found |
|
||||
| test.py:772:10:772:36 | ControlFlowNode for return_from_inner_scope() | test.py:769:16:769:21 | ControlFlowNode for SOURCE | test.py:772:10:772:36 | ControlFlowNode for return_from_inner_scope() | Flow found |
|
||||
| test.py:808:10:808:10 | ControlFlowNode for x | test.py:807:37:807:42 | ControlFlowNode for SOURCE | test.py:808:10:808:10 | ControlFlowNode for x | Flow found |
|
||||
| test.py:809:10:809:10 | ControlFlowNode for y | test.py:807:50:807:55 | ControlFlowNode for SOURCE | test.py:809:10:809:10 | ControlFlowNode for y | Flow found |
|
||||
| test.py:810:10:810:10 | ControlFlowNode for z | test.py:807:63:807:68 | ControlFlowNode for SOURCE | test.py:810:10:810:10 | ControlFlowNode for z | Flow found |
|
||||
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* @kind path-problem
|
||||
*/
|
||||
|
||||
import python
|
||||
import experimental.dataflow.testConfig
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from TestConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where config.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "Flow found"
|
||||
@@ -8,15 +8,30 @@
|
||||
# Intended sources should be the variable `SOURCE` and intended sinks should be
|
||||
# arguments to the function `SINK` (see python/ql/test/experimental/dataflow/testConfig.qll).
|
||||
|
||||
import sys
|
||||
import os
|
||||
import functools
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.dirname((__file__))))
|
||||
from testlib import expects
|
||||
|
||||
# These are defined so that we can evaluate the test code.
|
||||
NONSOURCE = "not a source"
|
||||
SOURCE = "source"
|
||||
|
||||
arg1 = "source1"
|
||||
arg2 = "source2"
|
||||
arg3 = "source3"
|
||||
arg4 = "source4"
|
||||
arg5 = "source5"
|
||||
arg6 = "source6"
|
||||
arg7 = "source7"
|
||||
|
||||
def is_source(x):
|
||||
return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j
|
||||
|
||||
def SINK(x):
|
||||
if is_source(x):
|
||||
def SINK(x, expected=SOURCE):
|
||||
if is_source(x) or x == expected:
|
||||
print("OK")
|
||||
else:
|
||||
print("Unexpected flow", x)
|
||||
@@ -27,6 +42,14 @@ def SINK_F(x):
|
||||
else:
|
||||
print("OK")
|
||||
|
||||
SINK1 = functools.partial(SINK, expected=arg1)
|
||||
SINK2 = functools.partial(SINK, expected=arg2)
|
||||
SINK3 = functools.partial(SINK, expected=arg3)
|
||||
SINK4 = functools.partial(SINK, expected=arg4)
|
||||
SINK5 = functools.partial(SINK, expected=arg5)
|
||||
SINK6 = functools.partial(SINK, expected=arg6)
|
||||
SINK7 = functools.partial(SINK, expected=arg7)
|
||||
|
||||
# Callable types
|
||||
# These are the types to which the function call operation (see section Calls) can be applied:
|
||||
|
||||
@@ -41,17 +64,19 @@ SINK(f(SOURCE, 3)) #$ flow="SOURCE -> f(..)"
|
||||
# An instance method object combines a class, a class instance and any callable object (normally a user-defined function).
|
||||
class C(object):
|
||||
|
||||
def method(self, x, cls):
|
||||
assert cls is self.__class__
|
||||
return x
|
||||
def method(self, x, y):
|
||||
SINK1(x)
|
||||
SINK2(y)
|
||||
|
||||
@classmethod
|
||||
def classmethod(cls, x):
|
||||
return x
|
||||
def classmethod(cls, x, y):
|
||||
SINK1(x)
|
||||
SINK2(y)
|
||||
|
||||
@staticmethod
|
||||
def staticmethod(x):
|
||||
return x
|
||||
def staticmethod(x, y):
|
||||
SINK1(x)
|
||||
SINK2(y)
|
||||
|
||||
def gen(self, x, count):
|
||||
n = count
|
||||
@@ -64,22 +89,40 @@ class C(object):
|
||||
|
||||
c = C()
|
||||
|
||||
# When an instance method object is created by retrieving a user-defined function object from a class via one of its instances, its __self__ attribute is the instance, and the method object is said to be bound. The new method’s __func__ attribute is the original function object.
|
||||
func_obj = c.method.__func__
|
||||
@expects(6)
|
||||
def test_method_call():
|
||||
# When an instance method object is created by retrieving a user-defined function object from a class via one of its instances, its __self__ attribute is the instance, and the method object is said to be bound. The new method’s __func__ attribute is the original function object.
|
||||
func_obj = c.method.__func__
|
||||
|
||||
# When an instance method object is called, the underlying function (__func__) is called, inserting the class instance (__self__) in front of the argument list. For instance, when C is a class which contains a definition for a function f(), and x is an instance of C, calling x.f(1) is equivalent to calling C.f(x, 1).
|
||||
SINK(c.method(SOURCE, C)) #$ flow="SOURCE -> c.method(..)"
|
||||
SINK(C.method(c, SOURCE, C)) #$ flow="SOURCE -> C.method(..)"
|
||||
SINK(func_obj(c, SOURCE, C)) #$ MISSING: flow="SOURCE -> func_obj(..)"
|
||||
# When an instance method object is called, the underlying function (__func__) is called, inserting the class instance (__self__) in front of the argument list. For instance, when C is a class which contains a definition for a function f(), and x is an instance of C, calling x.f(1) is equivalent to calling C.f(x, 1).
|
||||
c.method(arg1, arg2) # $ func=C.method arg1 arg2
|
||||
C.method(c, arg1, arg2) # $ func=C.method arg1 arg2
|
||||
func_obj(c, arg1, arg2) # $ MISSING: func=C.method arg1 arg2
|
||||
|
||||
|
||||
# When an instance method object is created by retrieving a class method object from a class or instance, its __self__ attribute is the class itself, and its __func__ attribute is the function object underlying the class method.
|
||||
c_func_obj = C.classmethod.__func__
|
||||
@expects(6)
|
||||
def test_classmethod_call():
|
||||
# When an instance method object is created by retrieving a class method object from a class or instance, its __self__ attribute is the class itself, and its __func__ attribute is the function object underlying the class method.
|
||||
c_func_obj = C.classmethod.__func__
|
||||
|
||||
# When an instance method object is derived from a class method object, the “class instance” stored in __self__ will actually be the class itself, so that calling either x.f(1) or C.f(1) is equivalent to calling f(C,1) where f is the underlying function.
|
||||
c.classmethod(arg1, arg2) # $ func=C.classmethod arg1 arg2
|
||||
C.classmethod(arg1, arg2) # $ func=C.classmethod arg1 arg2
|
||||
c_func_obj(C, arg1, arg2) # $ MISSING: func=C.classmethod arg1 arg2
|
||||
|
||||
|
||||
@expects(5)
|
||||
def test_staticmethod_call():
|
||||
# staticmethods does not have a __func__ attribute
|
||||
try:
|
||||
C.staticmethod.__func__
|
||||
except AttributeError:
|
||||
print("OK")
|
||||
|
||||
# When an instance method object is derived from a class method object, the “class instance” stored in __self__ will actually be the class itself, so that calling either x.f(1) or C.f(1) is equivalent to calling f(C,1) where f is the underlying function.
|
||||
c.staticmethod(arg1, arg2) # $ func=C.staticmethod arg1 arg2
|
||||
C.staticmethod(arg1, arg2) # $ func=C.staticmethod arg1 arg2
|
||||
|
||||
# When an instance method object is derived from a class method object, the “class instance” stored in __self__ will actually be the class itself, so that calling either x.f(1) or C.f(1) is equivalent to calling f(C,1) where f is the underlying function.
|
||||
SINK(c.classmethod(SOURCE)) #$ flow="SOURCE -> c.classmethod(..)"
|
||||
SINK(C.classmethod(SOURCE)) #$ flow="SOURCE -> C.classmethod(..)"
|
||||
SINK(c_func_obj(C, SOURCE)) #$ MISSING: flow="SOURCE -> c_func_obj(..)"
|
||||
|
||||
# Generator functions
|
||||
# A function or method which uses the yield statement (see section The yield statement) is called a generator function. Such a function, when called, always returns an iterator object which can be used to execute the body of the function: calling the iterator’s iterator.__next__() method will cause the function to execute until it provides a value using the yield statement. When the function executes a return statement or falls off the end, a StopIteration exception is raised and the iterator will have reached the end of the set of values to be returned.
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
| file://:0:0:0:0 | Function generator_func | generator.py:1:20:1:21 | ControlFlowNode for xs |
|
||||
| file://:0:0:0:0 | Function generator_func | generator.py:2:12:2:26 | ControlFlowNode for .0 |
|
||||
| file://:0:0:0:0 | Function generator_func | generator.py:2:12:2:26 | ControlFlowNode for .0 |
|
||||
| file://:0:0:0:0 | Function generator_func | generator.py:2:12:2:26 | ControlFlowNode for ListComp |
|
||||
| file://:0:0:0:0 | Function generator_func | generator.py:2:13:2:13 | ControlFlowNode for Yield |
|
||||
| file://:0:0:0:0 | Function generator_func | generator.py:2:13:2:13 | ControlFlowNode for x |
|
||||
| file://:0:0:0:0 | Function generator_func | generator.py:2:19:2:19 | ControlFlowNode for x |
|
||||
| file://:0:0:0:0 | Function generator_func | generator.py:2:24:2:25 | ControlFlowNode for xs |
|
||||
| file://:0:0:0:0 | Module class_example | class_example.py:1:1:1:3 | ControlFlowNode for wat |
|
||||
| file://:0:0:0:0 | Module class_example | class_example.py:1:7:1:7 | ControlFlowNode for IntegerLiteral |
|
||||
| file://:0:0:0:0 | Module class_example | class_example.py:3:1:3:10 | ControlFlowNode for ClassExpr |
|
||||
| file://:0:0:0:0 | Module class_example | class_example.py:3:7:3:9 | ControlFlowNode for Wat |
|
||||
| file://:0:0:0:0 | Module class_example | class_example.py:4:5:4:7 | ControlFlowNode for wat |
|
||||
| file://:0:0:0:0 | Module class_example | class_example.py:4:11:4:11 | ControlFlowNode for IntegerLiteral |
|
||||
| file://:0:0:0:0 | Module class_example | class_example.py:5:5:5:9 | ControlFlowNode for print |
|
||||
| file://:0:0:0:0 | Module class_example | class_example.py:5:5:5:26 | ControlFlowNode for print() |
|
||||
| file://:0:0:0:0 | Module class_example | class_example.py:5:11:5:20 | ControlFlowNode for Str |
|
||||
| file://:0:0:0:0 | Module class_example | class_example.py:5:23:5:25 | ControlFlowNode for wat |
|
||||
| file://:0:0:0:0 | Module class_example | class_example.py:7:1:7:5 | ControlFlowNode for print |
|
||||
| file://:0:0:0:0 | Module class_example | class_example.py:7:1:7:23 | ControlFlowNode for print() |
|
||||
| file://:0:0:0:0 | Module class_example | class_example.py:7:7:7:17 | ControlFlowNode for Str |
|
||||
| file://:0:0:0:0 | Module class_example | class_example.py:7:20:7:22 | ControlFlowNode for wat |
|
||||
| file://:0:0:0:0 | Module generator | generator.py:1:1:1:23 | ControlFlowNode for FunctionExpr |
|
||||
| file://:0:0:0:0 | Module generator | generator.py:1:5:1:18 | ControlFlowNode for generator_func |
|
||||
@@ -0,0 +1,6 @@
|
||||
import python
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
|
||||
from DataFlow::CfgNode node
|
||||
where exists(node.getLocation().getFile().getRelativePath())
|
||||
select node.getEnclosingCallable() as enclosingCallable, node
|
||||
@@ -0,0 +1,7 @@
|
||||
wat = 1
|
||||
|
||||
class Wat:
|
||||
wat = 2
|
||||
print("in class", wat) # prints 2
|
||||
|
||||
print("in module", wat) # prints 1
|
||||
@@ -0,0 +1,2 @@
|
||||
def generator_func(xs):
|
||||
return [x for x in xs]
|
||||
@@ -13,7 +13,17 @@ def is_source(x):
|
||||
return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j
|
||||
|
||||
|
||||
def SINK(x):
|
||||
def SINK(x, *, not_present_at_runtime=False):
|
||||
# not_present_at_runtime supports use-cases where we want flow from data-flow layer
|
||||
# (so we want to use SINK), but we end up in a siaution where it's not possible to
|
||||
# actually get flow from a source at runtime. The only use-case is for the
|
||||
# cross-talk tests, where our ability to use if-then-else is limited because doing
|
||||
# so would make cfg-splitting kick in, and that would solve the problem trivially
|
||||
# (by the splitting).
|
||||
if not_present_at_runtime:
|
||||
print("OK")
|
||||
return
|
||||
|
||||
if is_source(x):
|
||||
print("OK")
|
||||
else:
|
||||
@@ -39,33 +49,55 @@ class MyObj(object):
|
||||
self.foo = foo
|
||||
|
||||
def setFoo(obj, x):
|
||||
SINK_F(obj.foo)
|
||||
obj.foo = x
|
||||
|
||||
@expects(2) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
|
||||
|
||||
@expects(3) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
|
||||
def test_indirect_assign():
|
||||
myobj = MyObj("OK")
|
||||
myobj = MyObj(NONSOURCE)
|
||||
SINK_F(myobj.foo)
|
||||
|
||||
setFoo(myobj, SOURCE)
|
||||
SINK(myobj.foo) # $ flow="SOURCE, l:-1 -> myobj.foo"
|
||||
|
||||
setFoo(myobj, NONSOURCE)
|
||||
SINK_F(myobj.foo) # $ SPURIOUS: flow="SOURCE, l:-4 -> myobj.foo"
|
||||
|
||||
|
||||
@expects(3) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
|
||||
def test_indirect_assign_method():
|
||||
myobj = MyObj("OK")
|
||||
myobj = MyObj(NONSOURCE)
|
||||
SINK_F(myobj.foo)
|
||||
|
||||
myobj.setFoo(SOURCE)
|
||||
SINK(myobj.foo) # $ flow="SOURCE, l:-1 -> myobj.foo"
|
||||
|
||||
myobj.setFoo(NONSOURCE)
|
||||
SINK_F(myobj.foo) # $ SPURIOUS: flow="SOURCE, l:-4 -> myobj.foo"
|
||||
|
||||
|
||||
@expects(3) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
|
||||
def test_indirect_assign_bound_method():
|
||||
myobj = MyObj(NONSOURCE)
|
||||
SINK_F(myobj.foo)
|
||||
|
||||
sf = myobj.setFoo
|
||||
|
||||
sf(SOURCE)
|
||||
SINK(myobj.foo) # $ MISSING: flow="SOURCE, l:-1 -> myobj.foo"
|
||||
|
||||
sf(NONSOURCE)
|
||||
SINK_F(myobj.foo)
|
||||
|
||||
|
||||
@expects(3) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
|
||||
def test_direct_assign():
|
||||
myobj = MyObj(NONSOURCE)
|
||||
SINK_F(myobj.foo)
|
||||
|
||||
myobj.foo = SOURCE
|
||||
SINK(myobj.foo) # $ flow="SOURCE, l:-1 -> myobj.foo"
|
||||
|
||||
|
||||
def test_direct_assign_overwrite():
|
||||
myobj = MyObj(NONSOURCE)
|
||||
myobj.foo = SOURCE
|
||||
myobj.foo = NONSOURCE
|
||||
SINK_F(myobj.foo)
|
||||
|
||||
@@ -160,6 +192,164 @@ def test_nested_obj_method():
|
||||
a.getObj().foo = x
|
||||
SINK(a.obj.foo) # $ flow="SOURCE, l:-3 -> a.obj.foo"
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Field access on compound arguments
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# TODO: Add support for this, see https://github.com/github/codeql/pull/10444
|
||||
|
||||
@expects(5) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
|
||||
def test_field_on_compound_arg(cond_true=True, cond_false=False):
|
||||
class Ex:
|
||||
def __init__(self):
|
||||
self.attr = None
|
||||
|
||||
def set_attr(obj):
|
||||
obj.attr = SOURCE
|
||||
|
||||
x = Ex()
|
||||
y = Ex()
|
||||
set_attr(x if cond_true else y)
|
||||
SINK(x.attr) # $ MISSING: flow
|
||||
|
||||
x = Ex()
|
||||
y = Ex()
|
||||
set_attr(x if cond_false else y)
|
||||
SINK(y.attr) # $ MISSING: flow
|
||||
|
||||
x = Ex()
|
||||
y = Ex()
|
||||
z = Ex()
|
||||
set_attr(x if cond_false else (y if cond_true else z))
|
||||
SINK_F(x.attr) # $ MISSING: flow
|
||||
SINK(y.attr) # $ MISSING: flow
|
||||
SINK_F(z.attr) # $ MISSING: flow
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Crosstalk test -- using different function based on conditional
|
||||
# ------------------------------------------------------------------------------
|
||||
# NOTE: These tests use `SINK(objy.y, not_present_at_runtime=True)` since it's not
|
||||
# possible to use if-then-else statements, since that would make cfg-splitting kick in,
|
||||
# and that would solve the problem trivially (by the splitting).
|
||||
|
||||
class CrosstalkTestX:
|
||||
def __init__(self):
|
||||
self.x = None
|
||||
self.y = None
|
||||
|
||||
def setx(self, value):
|
||||
self.x = value
|
||||
|
||||
def setvalue(self, value):
|
||||
self.x = value
|
||||
|
||||
|
||||
class CrosstalkTestY:
|
||||
def __init__(self):
|
||||
self.x = None
|
||||
self.y = None
|
||||
|
||||
def sety(self ,value):
|
||||
self.y = value
|
||||
|
||||
def setvalue(self, value):
|
||||
self.y = value
|
||||
|
||||
|
||||
@expects(8) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
|
||||
def test_no_crosstalk_reference(cond=True):
|
||||
objx = CrosstalkTestX()
|
||||
SINK_F(objx.x)
|
||||
SINK_F(objx.y)
|
||||
|
||||
objy = CrosstalkTestY()
|
||||
SINK_F(objy.x)
|
||||
SINK_F(objy.y)
|
||||
|
||||
if cond:
|
||||
objx.setvalue(SOURCE)
|
||||
else:
|
||||
objy.setvalue(SOURCE)
|
||||
|
||||
SINK(objx.x) # $ flow="SOURCE, l:-4 -> objx.x"
|
||||
SINK_F(objx.y)
|
||||
SINK_F(objy.x)
|
||||
SINK(objy.y, not_present_at_runtime=True) # $ flow="SOURCE, l:-5 -> objy.y"
|
||||
|
||||
|
||||
@expects(8) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
|
||||
def test_potential_crosstalk_different_name(cond=True):
|
||||
objx = CrosstalkTestX()
|
||||
SINK_F(objx.x)
|
||||
SINK_F(objx.y)
|
||||
|
||||
objy = CrosstalkTestY()
|
||||
SINK_F(objy.x)
|
||||
SINK_F(objy.y)
|
||||
|
||||
if cond:
|
||||
func = objx.setx
|
||||
else:
|
||||
func = objy.sety
|
||||
|
||||
func(SOURCE)
|
||||
|
||||
SINK(objx.x) # $ MISSING: flow="SOURCE, l:-2 -> objx.x"
|
||||
SINK_F(objx.y)
|
||||
SINK_F(objy.x)
|
||||
SINK(objy.y, not_present_at_runtime=True) # $ MISSING: flow="SOURCE, l:-5 -> objy.y"
|
||||
|
||||
|
||||
@expects(8) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
|
||||
def test_potential_crosstalk_same_name(cond=True):
|
||||
objx = CrosstalkTestX()
|
||||
SINK_F(objx.x)
|
||||
SINK_F(objx.y)
|
||||
|
||||
objy = CrosstalkTestY()
|
||||
SINK_F(objy.x)
|
||||
SINK_F(objy.y)
|
||||
|
||||
if cond:
|
||||
func = objx.setvalue
|
||||
else:
|
||||
func = objy.setvalue
|
||||
|
||||
func(SOURCE)
|
||||
|
||||
SINK(objx.x) # $ MISSING: flow="SOURCE, l:-2 -> objx.x"
|
||||
SINK_F(objx.y)
|
||||
SINK_F(objy.x)
|
||||
SINK(objy.y, not_present_at_runtime=True) # $ MISSING: flow="SOURCE, l:-5 -> objy.y"
|
||||
|
||||
|
||||
@expects(10) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
|
||||
def test_potential_crosstalk_same_name_object_reference(cond=True):
|
||||
objx = CrosstalkTestX()
|
||||
SINK_F(objx.x)
|
||||
SINK_F(objx.y)
|
||||
|
||||
objy = CrosstalkTestY()
|
||||
SINK_F(objy.x)
|
||||
SINK_F(objy.y)
|
||||
|
||||
if cond:
|
||||
obj = objx
|
||||
else:
|
||||
obj = objy
|
||||
|
||||
obj.setvalue(SOURCE)
|
||||
|
||||
SINK(objx.x) # $ MISSING: flow="SOURCE, l:-2 -> objx.x"
|
||||
SINK_F(objx.y)
|
||||
SINK_F(objy.x)
|
||||
SINK(objy.y, not_present_at_runtime=True) # $ MISSING: flow="SOURCE, l:-5 -> objy.y"
|
||||
|
||||
SINK(obj.x) # $ flow="SOURCE, l:-7 -> obj.x"
|
||||
SINK(obj.y, not_present_at_runtime=True) # $ flow="SOURCE, l:-8 -> obj.y"
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Global scope
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
@@ -38,9 +38,10 @@ class TestConfiguration extends DataFlow::Configuration {
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node node) {
|
||||
exists(CallNode call |
|
||||
call.getFunction().(NameNode).getId() in ["SINK", "SINK_F"] and
|
||||
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
|
||||
exists(DataFlow::CallCfgNode call |
|
||||
call.getFunction().asCfgNode().(NameNode).getId() in ["SINK", "SINK_F"] and
|
||||
(node = call.getArg(_) or node = call.getArgByName(_)) and
|
||||
not node = call.getArgByName("not_present_at_runtime")
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ if __name__ == "__main__":
|
||||
check_tests_valid("coverage.classes")
|
||||
check_tests_valid("coverage.test")
|
||||
check_tests_valid("coverage.argumentPassing")
|
||||
check_tests_valid("coverage.datamodel")
|
||||
check_tests_valid("variable-capture.in")
|
||||
check_tests_valid("variable-capture.nonlocal")
|
||||
check_tests_valid("variable-capture.dict")
|
||||
|
||||
@@ -93,26 +93,29 @@ class ResolutionTest extends InlineExpectationsTest {
|
||||
}
|
||||
}
|
||||
|
||||
class ResolutionTest3 extends InlineExpectationsTest {
|
||||
ResolutionTest3() { this = "ResolutionTest3" }
|
||||
private string getTagForVersion(int version) {
|
||||
result = "prints" + version and
|
||||
version = major_version()
|
||||
}
|
||||
|
||||
override string getARelevantTag() { result = "prints3" and major_version() = 3 }
|
||||
class VersionSpecificResolutionTest extends InlineExpectationsTest {
|
||||
VersionSpecificResolutionTest() { this = "VersionSpecificResolutionTest" }
|
||||
|
||||
override string getARelevantTag() { result = getTagForVersion(_) }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
(
|
||||
exists(DataFlow::PathNode source, DataFlow::PathNode sink, ImportConfiguration config |
|
||||
config.hasFlowPath(source, sink) and
|
||||
sink.getNode().(VersionGuardedNode).getVersion() = 3 and
|
||||
tag = "prints3" and
|
||||
tag = getTagForVersion(sink.getNode().(VersionGuardedNode).getVersion()) and
|
||||
location = sink.getNode().getLocation() and
|
||||
value = source.getNode().(SourceString).getContents() and
|
||||
element = sink.getNode().toString()
|
||||
)
|
||||
or
|
||||
exists(ModuleRef ref |
|
||||
ref.(VersionGuardedNode).getVersion() = 3 and
|
||||
ref instanceof CheckArgument and
|
||||
tag = "prints3" and
|
||||
tag = getTagForVersion(ref.(VersionGuardedNode).getVersion()) and
|
||||
location = ref.getLocation() and
|
||||
value = "\"<module " + ref.getName() + ">\"" and
|
||||
element = ref.toString()
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
failures
|
||||
debug_callableNotUnique
|
||||
pointsTo_found_typeTracker_notFound
|
||||
| example.py:22:1:22:16 | ControlFlowNode for explicit_afunc() | explicit_afunc |
|
||||
typeTracker_found_pointsTo_notFound
|
||||
@@ -0,0 +1 @@
|
||||
../CallGraph/InlineCallGraphTest.ql
|
||||
@@ -1,6 +0,0 @@
|
||||
debug_missingAnnotationForCallable
|
||||
debug_nonUniqueAnnotationForCallable
|
||||
debug_missingAnnotationForCall
|
||||
expectedCallEdgeNotFound
|
||||
| example.py:19:1:19:7 | afunc() | foo/bar/a.py:2:1:2:12 | Function afunc |
|
||||
unexpectedCallEdgeFound
|
||||
@@ -1 +0,0 @@
|
||||
../CallGraph/PointsTo.ql
|
||||
@@ -1,6 +0,0 @@
|
||||
debug_missingAnnotationForCallable
|
||||
debug_nonUniqueAnnotationForCallable
|
||||
debug_missingAnnotationForCall
|
||||
pointsTo_found_typeTracker_notFound
|
||||
| example.py:22:1:22:16 | explicit_afunc() | foo_explicit/bar/a.py:2:1:2:21 | Function explicit_afunc |
|
||||
pointsTo_notFound_typeTracker_found
|
||||
@@ -1 +0,0 @@
|
||||
../CallGraph/Relative.ql
|
||||
@@ -1,7 +0,0 @@
|
||||
debug_missingAnnotationForCallable
|
||||
debug_nonUniqueAnnotationForCallable
|
||||
debug_missingAnnotationForCall
|
||||
expectedCallEdgeNotFound
|
||||
| example.py:19:1:19:7 | afunc() | foo/bar/a.py:2:1:2:12 | Function afunc |
|
||||
| example.py:22:1:22:16 | explicit_afunc() | foo_explicit/bar/a.py:2:1:2:21 | Function explicit_afunc |
|
||||
unexpectedCallEdgeFound
|
||||
@@ -1 +0,0 @@
|
||||
../CallGraph/TypeTracker.ql
|
||||
@@ -5,18 +5,18 @@ This is not included in the standard `CallGraph/code` folder, since we're testin
|
||||
understanding import work properly, so it's better to have a clean test setup that is
|
||||
obviously correct (the other one isn't in regards to imports).
|
||||
|
||||
Technically this is part of PEP 420 -- Implicit Namespace Packages, but does use the
|
||||
Technically this is part of PEP 420 -- Implicit Namespace Packages, but does not use the
|
||||
*real* namespace package feature of allowing source code for a single package to reside
|
||||
in multiple places.
|
||||
|
||||
Maybe this should have been an import resolution test, and not a call-graph test ¯\_(ツ)_/¯
|
||||
|
||||
Since PEP 420 was accepted in Python 3, this test is Python 3 only.
|
||||
"""
|
||||
|
||||
from foo.bar.a import afunc
|
||||
from foo_explicit.bar.a import explicit_afunc
|
||||
|
||||
# calls:afunc
|
||||
afunc()
|
||||
afunc() # $ MISSING: pt,tt=afunc
|
||||
|
||||
# calls:explicit_afunc
|
||||
explicit_afunc()
|
||||
explicit_afunc() # $ pt=explicit_afunc MISSING: tt=explicit_afunc
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# name:afunc
|
||||
def afunc():
|
||||
print("afunc called")
|
||||
return 1
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# name:explicit_afunc
|
||||
def explicit_afunc():
|
||||
print("explicit_afunc called")
|
||||
return 1
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
debug_missingAnnotationForCallable
|
||||
| annotation_xfail.py:10:1:10:24 | callable_not_annotated() | This call is annotated with 'callable_not_annotated', but no callable with that annotation was extracted. Please fix. |
|
||||
debug_nonUniqueAnnotationForCallable
|
||||
| annotation_xfail.py:13:1:13:17 | Function non_unique | Multiple callables are annotated with 'non_unique'. Please fix. |
|
||||
| annotation_xfail.py:17:1:17:26 | Function too_much_copy_paste | Multiple callables are annotated with 'non_unique'. Please fix. |
|
||||
debug_missingAnnotationForCall
|
||||
| annotation_xfail.py:2:1:2:24 | Function no_annotated_call | This callable is annotated with 'no_annotated_call', but no call with that annotation was extracted. Please fix. |
|
||||
expectedCallEdgeNotFound
|
||||
| call_edge_xfail.py:36:1:36:11 | xfail_foo() | call_edge_xfail.py:8:1:8:16 | Function xfail_bar |
|
||||
| call_edge_xfail.py:39:1:39:11 | xfail_baz() | call_edge_xfail.py:8:1:8:16 | Function xfail_bar |
|
||||
unexpectedCallEdgeFound
|
||||
| call_edge_xfail.py:29:1:29:6 | func() | call_edge_xfail.py:4:1:4:16 | Function xfail_foo | Call resolved to the callable named 'xfail_foo' but was not annotated as such |
|
||||
| call_edge_xfail.py:29:1:29:6 | func() | call_edge_xfail.py:8:1:8:16 | Function xfail_bar | Call resolved to the callable named 'xfail_bar' but was not annotated as such |
|
||||
| call_edge_xfail.py:30:1:30:11 | xfail_foo() | call_edge_xfail.py:4:1:4:16 | Function xfail_foo | Call resolved to the callable named 'xfail_foo' but was not annotated as such |
|
||||
| call_edge_xfail.py:31:1:31:14 | xfail_lambda() | call_edge_xfail.py:15:16:15:44 | Function lambda | Call resolved to the callable named 'xfail_lambda' but was not annotated as such |
|
||||
| call_edge_xfail.py:36:1:36:11 | xfail_foo() | call_edge_xfail.py:4:1:4:16 | Function xfail_foo | Call resolved to the callable named 'xfail_foo' but was not annotated as such |
|
||||
| call_edge_xfail.py:39:1:39:11 | xfail_baz() | call_edge_xfail.py:11:1:11:16 | Function xfail_baz | Annotated call resolved to unannotated callable |
|
||||
| call_edge_xfail.py:43:1:43:6 | func() | call_edge_xfail.py:8:1:8:16 | Function xfail_bar | Call resolved to the callable named 'xfail_bar' but was not annotated as such |
|
||||
@@ -1 +0,0 @@
|
||||
../CallGraph/PointsTo.ql
|
||||
@@ -1 +0,0 @@
|
||||
Test that show our failure handling in [CallGraph](../CallGraph/) works as expected.
|
||||
@@ -1,21 +0,0 @@
|
||||
# name:no_annotated_call
|
||||
def no_annotated_call():
|
||||
pass
|
||||
|
||||
def callable_not_annotated():
|
||||
pass
|
||||
|
||||
no_annotated_call()
|
||||
# calls:callable_not_annotated
|
||||
callable_not_annotated()
|
||||
|
||||
# name:non_unique
|
||||
def non_unique():
|
||||
pass
|
||||
|
||||
# name:non_unique
|
||||
def too_much_copy_paste():
|
||||
pass
|
||||
|
||||
# calls:non_unique
|
||||
non_unique()
|
||||
@@ -1,43 +0,0 @@
|
||||
import sys
|
||||
|
||||
# name:xfail_foo
|
||||
def xfail_foo():
|
||||
print('xfail_foo')
|
||||
|
||||
# name:xfail_bar
|
||||
def xfail_bar():
|
||||
print('xfail_bar')
|
||||
|
||||
def xfail_baz():
|
||||
print('xfail_baz')
|
||||
|
||||
# name:xfail_lambda
|
||||
xfail_lambda = lambda: print('xfail_lambda')
|
||||
|
||||
if len(sys.argv) >= 2 and not sys.argv[1] in ['0', 'False', 'false']:
|
||||
func = xfail_foo
|
||||
else:
|
||||
func = xfail_bar
|
||||
|
||||
# Correct usage to suppress bad annotation errors
|
||||
# calls:xfail_foo calls:xfail_bar
|
||||
func()
|
||||
# calls:xfail_lambda
|
||||
xfail_lambda()
|
||||
|
||||
# These are not annotated, and will give rise to unexpectedCallEdgeFound
|
||||
func()
|
||||
xfail_foo()
|
||||
xfail_lambda()
|
||||
|
||||
# These are annotated wrongly, and will give rise to unexpectedCallEdgeFound
|
||||
|
||||
# calls:xfail_bar
|
||||
xfail_foo()
|
||||
|
||||
# calls:xfail_bar
|
||||
xfail_baz()
|
||||
|
||||
# The annotation is incomplete (does not include the call to xfail_bar)
|
||||
# calls:xfail_foo
|
||||
func()
|
||||
@@ -1,147 +0,0 @@
|
||||
import python
|
||||
|
||||
/** Gets the comment on the line above `ast` */
|
||||
Comment commentFor(AstNode ast) {
|
||||
exists(int line | line = ast.getLocation().getStartLine() - 1 |
|
||||
result
|
||||
.getLocation()
|
||||
.hasLocationInfo(ast.getLocation().getFile().getAbsolutePath(), line, _, line, _)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the value from `tag:value` in the comment for `ast` */
|
||||
string getAnnotation(AstNode ast, string tag) {
|
||||
exists(Comment comment, string match, string theRegex |
|
||||
theRegex = "([\\w]+):([\\w.]+)" and
|
||||
comment = commentFor(ast) and
|
||||
match = comment.getText().regexpFind(theRegex, _, _) and
|
||||
tag = match.regexpCapture(theRegex, 1) and
|
||||
result = match.regexpCapture(theRegex, 2)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a callable annotated with `name:name` */
|
||||
Function annotatedCallable(string name) { name = getAnnotation(result, "name") }
|
||||
|
||||
/** Gets a call annotated with `calls:name` */
|
||||
Call annotatedCall(string name) { name = getAnnotation(result, "calls") }
|
||||
|
||||
predicate missingAnnotationForCallable(string name, Call call) {
|
||||
call = annotatedCall(name) and
|
||||
not exists(annotatedCallable(name))
|
||||
}
|
||||
|
||||
predicate nonUniqueAnnotationForCallable(string name, Function callable) {
|
||||
strictcount(annotatedCallable(name)) > 1 and
|
||||
callable = annotatedCallable(name)
|
||||
}
|
||||
|
||||
predicate missingAnnotationForCall(string name, Function callable) {
|
||||
not exists(annotatedCall(name)) and
|
||||
callable = annotatedCallable(name)
|
||||
}
|
||||
|
||||
/** There is an obvious problem with the annotation `name` */
|
||||
predicate nameInErrorState(string name) {
|
||||
missingAnnotationForCallable(name, _)
|
||||
or
|
||||
nonUniqueAnnotationForCallable(name, _)
|
||||
or
|
||||
missingAnnotationForCall(name, _)
|
||||
}
|
||||
|
||||
/** Source code has annotation with `name` showing that `call` will call `callable` */
|
||||
predicate annotatedCallEdge(string name, Call call, Function callable) {
|
||||
not nameInErrorState(name) and
|
||||
call = annotatedCall(name) and
|
||||
callable = annotatedCallable(name)
|
||||
}
|
||||
|
||||
// ------------------------- Annotation debug query predicates -------------------------
|
||||
query predicate debug_missingAnnotationForCallable(Call call, string message) {
|
||||
exists(string name |
|
||||
message =
|
||||
"This call is annotated with '" + name +
|
||||
"', but no callable with that annotation was extracted. Please fix." and
|
||||
missingAnnotationForCallable(name, call)
|
||||
)
|
||||
}
|
||||
|
||||
query predicate debug_nonUniqueAnnotationForCallable(Function callable, string message) {
|
||||
exists(string name |
|
||||
message = "Multiple callables are annotated with '" + name + "'. Please fix." and
|
||||
nonUniqueAnnotationForCallable(name, callable)
|
||||
)
|
||||
}
|
||||
|
||||
query predicate debug_missingAnnotationForCall(Function callable, string message) {
|
||||
exists(string name |
|
||||
message =
|
||||
"This callable is annotated with '" + name +
|
||||
"', but no call with that annotation was extracted. Please fix." and
|
||||
missingAnnotationForCall(name, callable)
|
||||
)
|
||||
}
|
||||
|
||||
// ------------------------- Call Graph resolution -------------------------
|
||||
private newtype TCallGraphResolver =
|
||||
TPointsToResolver() or
|
||||
TTypeTrackerResolver()
|
||||
|
||||
/** A method of call graph resolution */
|
||||
abstract class CallGraphResolver extends TCallGraphResolver {
|
||||
abstract predicate callEdge(Call call, Function callable);
|
||||
|
||||
/**
|
||||
* Holds if annotations show that `call` will call `callable`,
|
||||
* but our call graph resolver was not able to figure that out
|
||||
*/
|
||||
predicate expectedCallEdgeNotFound(Call call, Function callable) {
|
||||
annotatedCallEdge(_, call, callable) and
|
||||
not this.callEdge(call, callable)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there are no annotations that show that `call` will call `callable` (where at least one of these are annotated),
|
||||
* but the call graph resolver claims that `call` will call `callable`
|
||||
*/
|
||||
predicate unexpectedCallEdgeFound(Call call, Function callable, string message) {
|
||||
this.callEdge(call, callable) and
|
||||
not annotatedCallEdge(_, call, callable) and
|
||||
(
|
||||
exists(string name |
|
||||
message = "Call resolved to the callable named '" + name + "' but was not annotated as such" and
|
||||
callable = annotatedCallable(name) and
|
||||
not nameInErrorState(name)
|
||||
)
|
||||
or
|
||||
exists(string name |
|
||||
message = "Annotated call resolved to unannotated callable" and
|
||||
call = annotatedCall(name) and
|
||||
not nameInErrorState(name) and
|
||||
not exists( | callable = annotatedCallable(_))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
string toString() { result = "CallGraphResolver" }
|
||||
}
|
||||
|
||||
/** A call graph resolver based on the existing points-to analysis */
|
||||
class PointsToResolver extends CallGraphResolver, TPointsToResolver {
|
||||
override predicate callEdge(Call call, Function callable) {
|
||||
exists(PythonFunctionValue funcValue |
|
||||
funcValue.getScope() = callable and
|
||||
call = funcValue.getACall().getNode()
|
||||
)
|
||||
}
|
||||
|
||||
override string toString() { result = "PointsToResolver" }
|
||||
}
|
||||
|
||||
/** A call graph resolved based on Type Trackers */
|
||||
class TypeTrackerResolver extends CallGraphResolver, TTypeTrackerResolver {
|
||||
override predicate callEdge(Call call, Function callable) { none() }
|
||||
|
||||
override string toString() { result = "TypeTrackerResolver" }
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
failures
|
||||
debug_callableNotUnique
|
||||
| code/class_advanced.py:18:5:18:18 | Function arg | Qualified function name 'B.arg' is not unique. Please fix. |
|
||||
| code/class_advanced.py:23:5:23:25 | Function arg | Qualified function name 'B.arg' is not unique. Please fix. |
|
||||
pointsTo_found_typeTracker_notFound
|
||||
| code/class_simple.py:24:1:24:15 | ControlFlowNode for Attribute() | A.some_method |
|
||||
| code/class_simple.py:25:1:25:21 | ControlFlowNode for Attribute() | A.some_staticmethod |
|
||||
| code/class_simple.py:26:1:26:20 | ControlFlowNode for Attribute() | A.some_classmethod |
|
||||
| code/class_simple.py:28:1:28:21 | ControlFlowNode for Attribute() | A.some_staticmethod |
|
||||
| code/class_simple.py:29:1:29:20 | ControlFlowNode for Attribute() | A.some_classmethod |
|
||||
| code/runtime_decision.py:18:1:18:6 | ControlFlowNode for func() | rd_bar |
|
||||
| code/runtime_decision.py:18:1:18:6 | ControlFlowNode for func() | rd_foo |
|
||||
| code/runtime_decision.py:26:1:26:7 | ControlFlowNode for func2() | rd_bar |
|
||||
| code/runtime_decision.py:26:1:26:7 | ControlFlowNode for func2() | rd_foo |
|
||||
| code/simple.py:15:1:15:5 | ControlFlowNode for foo() | foo |
|
||||
| code/simple.py:16:1:16:14 | ControlFlowNode for indirect_foo() | foo |
|
||||
| code/simple.py:17:1:17:5 | ControlFlowNode for bar() | bar |
|
||||
| code/simple.py:18:1:18:5 | ControlFlowNode for lam() | lambda[simple.py:12:7] |
|
||||
| code/underscore_prefix_func_name.py:18:5:18:19 | ControlFlowNode for some_function() | some_function |
|
||||
| code/underscore_prefix_func_name.py:21:5:21:19 | ControlFlowNode for some_function() | some_function |
|
||||
| code/underscore_prefix_func_name.py:24:1:24:21 | ControlFlowNode for _works_since_called() | _works_since_called |
|
||||
typeTracker_found_pointsTo_notFound
|
||||
@@ -0,0 +1,68 @@
|
||||
import python
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
/** Holds when `call` is resolved to `callable` using points-to based call-graph. */
|
||||
predicate pointsToCallEdge(CallNode call, Function callable) {
|
||||
exists(PythonFunctionValue funcValue |
|
||||
funcValue.getScope() = callable and
|
||||
call = funcValue.getACall()
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds when `call` is resolved to `callable` using type-tracking based call-graph. */
|
||||
predicate typeTrackerCallEdge(CallNode call, Function callable) { none() }
|
||||
|
||||
class CallGraphTest extends InlineExpectationsTest {
|
||||
CallGraphTest() { this = "CallGraphTest" }
|
||||
|
||||
override string getARelevantTag() { result in ["pt", "tt"] }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(location.getFile().getRelativePath()) and
|
||||
exists(CallNode call, Function target |
|
||||
tag = "tt" and
|
||||
typeTrackerCallEdge(call, target)
|
||||
or
|
||||
tag = "pt" and
|
||||
pointsToCallEdge(call, target)
|
||||
|
|
||||
location = call.getLocation() and
|
||||
element = call.toString() and
|
||||
value = betterQualName(target)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
bindingset[func]
|
||||
string betterQualName(Function func) {
|
||||
// note: `target.getQualifiedName` for Lambdas is just "lambda", so is not very useful :|
|
||||
not func.isLambda() and
|
||||
result = func.getQualifiedName()
|
||||
or
|
||||
func.isLambda() and
|
||||
result =
|
||||
"lambda[" + func.getLocation().getFile().getShortName() + ":" +
|
||||
func.getLocation().getStartLine() + ":" + func.getLocation().getStartColumn() + "]"
|
||||
}
|
||||
|
||||
query predicate debug_callableNotUnique(Function callable, string message) {
|
||||
exists(Function f | f != callable and f.getQualifiedName() = callable.getQualifiedName()) and
|
||||
message =
|
||||
"Qualified function name '" + callable.getQualifiedName() + "' is not unique. Please fix."
|
||||
}
|
||||
|
||||
query predicate pointsTo_found_typeTracker_notFound(CallNode call, string qualname) {
|
||||
exists(Function target |
|
||||
pointsToCallEdge(call, target) and
|
||||
not typeTrackerCallEdge(call, target) and
|
||||
qualname = betterQualName(target)
|
||||
)
|
||||
}
|
||||
|
||||
query predicate typeTracker_found_pointsTo_notFound(CallNode call, string qualname) {
|
||||
exists(Function target |
|
||||
not pointsToCallEdge(call, target) and
|
||||
typeTrackerCallEdge(call, target) and
|
||||
qualname = betterQualName(target)
|
||||
)
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
debug_missingAnnotationForCallable
|
||||
debug_nonUniqueAnnotationForCallable
|
||||
debug_missingAnnotationForCall
|
||||
expectedCallEdgeNotFound
|
||||
| code/underscore_prefix_func_name.py:16:5:16:19 | some_function() | code/underscore_prefix_func_name.py:10:1:10:20 | Function some_function |
|
||||
unexpectedCallEdgeFound
|
||||
@@ -1,10 +0,0 @@
|
||||
import python
|
||||
import CallGraphTest
|
||||
|
||||
query predicate expectedCallEdgeNotFound(Call call, Function callable) {
|
||||
any(PointsToResolver r).expectedCallEdgeNotFound(call, callable)
|
||||
}
|
||||
|
||||
query predicate unexpectedCallEdgeFound(Call call, Function callable, string message) {
|
||||
any(PointsToResolver r).unexpectedCallEdgeFound(call, callable, message)
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
# Call Graph Tests
|
||||
|
||||
A small testing framework for our call graph resolution. It relies on manual annotation of calls and callables, **and will only include output if something is wrong**. For example, if we are not able to resolve that the `foo()` call will call the `foo` function, that should give an alert.
|
||||
|
||||
```py
|
||||
# name:foo
|
||||
def foo():
|
||||
pass
|
||||
# calls:foo
|
||||
foo()
|
||||
```
|
||||
|
||||
This is greatly inspired by [`CallGraphs/AnnotatedTest`](https://github.com/github/codeql/blob/696d19cb1440b6f6a75c6a2c1319e18860ceb436/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/Test.ql) from JavaScript.
|
||||
|
||||
IMPORTANT: Names used in annotations are not scoped, so must be unique globally. (this is a bit annoying, but makes things simple). If multiple identical annotations are used, an error message will be output.
|
||||
|
||||
Important files:
|
||||
|
||||
- `CallGraphTest.qll`: main code to find annotated calls/callables and setting everything up.
|
||||
- `PointsTo.ql`: results when using points-to for call graph resolution.
|
||||
- `TypeTracker.ql`: results when using TypeTracking for call graph resolution.
|
||||
- `Relative.ql`: differences between using points-to and TypeTracking.
|
||||
- `code/` contains the actual Python code we test against (included by `test.py`).
|
||||
|
||||
All queries will also execute some `debug_*` predicates. These highlight any obvious problems with the annotation setup, and so there should never be any results committed. To show that this works as expected, see the [CallGraph-xfail](../CallGraph-xfail/) which uses symlinked versions of the files in this directory (can't include as subdir, so has to be a sibling).
|
||||
|
||||
## `options` file
|
||||
|
||||
If the value for `--max-import-depth` is set so that `import random` will extract `random.py` from the standard library, BUT NO transitive imports are extracted, then points-to analysis will fail to handle the following snippet.
|
||||
|
||||
```py
|
||||
import random
|
||||
if random.random() < 0.5:
|
||||
func = foo
|
||||
else:
|
||||
func = bar
|
||||
func()
|
||||
```
|
||||
@@ -1,20 +0,0 @@
|
||||
debug_missingAnnotationForCallable
|
||||
debug_nonUniqueAnnotationForCallable
|
||||
debug_missingAnnotationForCall
|
||||
pointsTo_found_typeTracker_notFound
|
||||
| code/class_simple.py:28:1:28:15 | Attribute() | code/class_simple.py:8:5:8:26 | Function some_method |
|
||||
| code/class_simple.py:30:1:30:21 | Attribute() | code/class_simple.py:13:5:13:28 | Function some_staticmethod |
|
||||
| code/class_simple.py:32:1:32:20 | Attribute() | code/class_simple.py:18:5:18:30 | Function some_classmethod |
|
||||
| code/class_simple.py:35:1:35:21 | Attribute() | code/class_simple.py:13:5:13:28 | Function some_staticmethod |
|
||||
| code/class_simple.py:37:1:37:20 | Attribute() | code/class_simple.py:18:5:18:30 | Function some_classmethod |
|
||||
| code/runtime_decision.py:21:1:21:6 | func() | code/runtime_decision.py:8:1:8:13 | Function rd_foo |
|
||||
| code/runtime_decision.py:21:1:21:6 | func() | code/runtime_decision.py:12:1:12:13 | Function rd_bar |
|
||||
| code/runtime_decision.py:30:1:30:7 | func2() | code/runtime_decision.py:8:1:8:13 | Function rd_foo |
|
||||
| code/runtime_decision.py:30:1:30:7 | func2() | code/runtime_decision.py:12:1:12:13 | Function rd_bar |
|
||||
| code/simple.py:19:1:19:5 | foo() | code/simple.py:2:1:2:10 | Function foo |
|
||||
| code/simple.py:21:1:21:14 | indirect_foo() | code/simple.py:2:1:2:10 | Function foo |
|
||||
| code/simple.py:23:1:23:5 | bar() | code/simple.py:10:1:10:10 | Function bar |
|
||||
| code/simple.py:25:1:25:5 | lam() | code/simple.py:15:7:15:36 | Function lambda |
|
||||
| code/underscore_prefix_func_name.py:21:5:21:19 | some_function() | code/underscore_prefix_func_name.py:10:1:10:20 | Function some_function |
|
||||
| code/underscore_prefix_func_name.py:25:5:25:19 | some_function() | code/underscore_prefix_func_name.py:10:1:10:20 | Function some_function |
|
||||
pointsTo_notFound_typeTracker_found
|
||||
@@ -1,14 +0,0 @@
|
||||
import python
|
||||
import CallGraphTest
|
||||
|
||||
query predicate pointsTo_found_typeTracker_notFound(Call call, Function callable) {
|
||||
annotatedCallEdge(_, call, callable) and
|
||||
any(PointsToResolver r).callEdge(call, callable) and
|
||||
not any(TypeTrackerResolver r).callEdge(call, callable)
|
||||
}
|
||||
|
||||
query predicate pointsTo_notFound_typeTracker_found(Call call, Function callable) {
|
||||
annotatedCallEdge(_, call, callable) and
|
||||
not any(PointsToResolver r).callEdge(call, callable) and
|
||||
any(TypeTrackerResolver r).callEdge(call, callable)
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
debug_missingAnnotationForCallable
|
||||
debug_nonUniqueAnnotationForCallable
|
||||
debug_missingAnnotationForCall
|
||||
expectedCallEdgeNotFound
|
||||
| code/class_simple.py:28:1:28:15 | Attribute() | code/class_simple.py:8:5:8:26 | Function some_method |
|
||||
| code/class_simple.py:30:1:30:21 | Attribute() | code/class_simple.py:13:5:13:28 | Function some_staticmethod |
|
||||
| code/class_simple.py:32:1:32:20 | Attribute() | code/class_simple.py:18:5:18:30 | Function some_classmethod |
|
||||
| code/class_simple.py:35:1:35:21 | Attribute() | code/class_simple.py:13:5:13:28 | Function some_staticmethod |
|
||||
| code/class_simple.py:37:1:37:20 | Attribute() | code/class_simple.py:18:5:18:30 | Function some_classmethod |
|
||||
| code/runtime_decision.py:21:1:21:6 | func() | code/runtime_decision.py:8:1:8:13 | Function rd_foo |
|
||||
| code/runtime_decision.py:21:1:21:6 | func() | code/runtime_decision.py:12:1:12:13 | Function rd_bar |
|
||||
| code/runtime_decision.py:30:1:30:7 | func2() | code/runtime_decision.py:8:1:8:13 | Function rd_foo |
|
||||
| code/runtime_decision.py:30:1:30:7 | func2() | code/runtime_decision.py:12:1:12:13 | Function rd_bar |
|
||||
| code/simple.py:19:1:19:5 | foo() | code/simple.py:2:1:2:10 | Function foo |
|
||||
| code/simple.py:21:1:21:14 | indirect_foo() | code/simple.py:2:1:2:10 | Function foo |
|
||||
| code/simple.py:23:1:23:5 | bar() | code/simple.py:10:1:10:10 | Function bar |
|
||||
| code/simple.py:25:1:25:5 | lam() | code/simple.py:15:7:15:36 | Function lambda |
|
||||
| code/underscore_prefix_func_name.py:16:5:16:19 | some_function() | code/underscore_prefix_func_name.py:10:1:10:20 | Function some_function |
|
||||
| code/underscore_prefix_func_name.py:21:5:21:19 | some_function() | code/underscore_prefix_func_name.py:10:1:10:20 | Function some_function |
|
||||
| code/underscore_prefix_func_name.py:25:5:25:19 | some_function() | code/underscore_prefix_func_name.py:10:1:10:20 | Function some_function |
|
||||
unexpectedCallEdgeFound
|
||||
@@ -1,10 +0,0 @@
|
||||
import python
|
||||
import CallGraphTest
|
||||
|
||||
query predicate expectedCallEdgeNotFound(Call call, Function callable) {
|
||||
any(TypeTrackerResolver r).expectedCallEdgeNotFound(call, callable)
|
||||
}
|
||||
|
||||
query predicate unexpectedCallEdgeFound(Call call, Function callable, string message) {
|
||||
any(TypeTrackerResolver r).unexpectedCallEdgeFound(call, callable, message)
|
||||
}
|
||||
@@ -4,17 +4,14 @@ class A(object):
|
||||
print('A.__init__', arg)
|
||||
self.arg = arg
|
||||
|
||||
# name:A.some_method
|
||||
def some_method(self):
|
||||
print('A.some_method', self)
|
||||
|
||||
@staticmethod
|
||||
# name:A.some_staticmethod
|
||||
def some_staticmethod():
|
||||
print('A.some_staticmethod')
|
||||
|
||||
@classmethod
|
||||
# name:A.some_classmethod
|
||||
def some_classmethod(cls):
|
||||
print('A.some_classmethod', cls)
|
||||
|
||||
@@ -24,14 +21,9 @@ class A(object):
|
||||
# However, current test setup uses "callable" for naming, and expects things to be Function.
|
||||
a = A(42)
|
||||
|
||||
# calls:A.some_method
|
||||
a.some_method()
|
||||
# calls:A.some_staticmethod
|
||||
a.some_staticmethod()
|
||||
# calls:A.some_classmethod
|
||||
a.some_classmethod()
|
||||
a.some_method() # $ pt=A.some_method
|
||||
a.some_staticmethod() # $ pt=A.some_staticmethod
|
||||
a.some_classmethod() # $ pt=A.some_classmethod
|
||||
|
||||
# calls:A.some_staticmethod
|
||||
A.some_staticmethod()
|
||||
# calls:A.some_classmethod
|
||||
A.some_classmethod()
|
||||
A.some_staticmethod() # $ pt=A.some_staticmethod
|
||||
A.some_classmethod() # $ pt=A.some_classmethod
|
||||
|
||||
@@ -4,11 +4,9 @@ import random
|
||||
# hmm, annoying that you have to keep names unique across files :|
|
||||
# since I like to use foo and bar ALL the time :D
|
||||
|
||||
# name:rd_foo
|
||||
def rd_foo():
|
||||
print('rd_foo')
|
||||
|
||||
# name:rd_bar
|
||||
def rd_bar():
|
||||
print('rd_bar')
|
||||
|
||||
@@ -17,8 +15,7 @@ if len(sys.argv) >= 2 and not sys.argv[1] in ['0', 'False', 'false']:
|
||||
else:
|
||||
func = rd_bar
|
||||
|
||||
# calls:rd_foo calls:rd_bar
|
||||
func()
|
||||
func() # $ pt=rd_foo pt=rd_bar
|
||||
|
||||
# Random doesn't work with points-to :O
|
||||
if random.random() < 0.5:
|
||||
@@ -26,5 +23,4 @@ if random.random() < 0.5:
|
||||
else:
|
||||
func2 = rd_bar
|
||||
|
||||
# calls:rd_foo calls:rd_bar
|
||||
func2()
|
||||
func2() # $ pt=rd_foo pt=rd_bar
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# name:foo
|
||||
def foo():
|
||||
print("foo called")
|
||||
|
||||
@@ -6,22 +5,16 @@ def foo():
|
||||
indirect_foo = foo
|
||||
|
||||
|
||||
# name:bar
|
||||
def bar():
|
||||
print("bar called")
|
||||
|
||||
|
||||
# name:lam
|
||||
lam = lambda: print("lambda called")
|
||||
|
||||
|
||||
# calls:foo
|
||||
foo()
|
||||
# calls:foo
|
||||
indirect_foo()
|
||||
# calls:bar
|
||||
bar()
|
||||
# calls:lam
|
||||
lam()
|
||||
foo() # $ pt=foo
|
||||
indirect_foo() # $ pt=foo
|
||||
bar() # $ pt=bar
|
||||
lam() # $ pt=lambda[simple.py:12:7]
|
||||
|
||||
# python -m trace --trackcalls simple.py
|
||||
|
||||
@@ -6,23 +6,19 @@
|
||||
# points-to information about the `open` call in
|
||||
# https://google-gruyere.appspot.com/code/gruyere.py on line 227
|
||||
|
||||
# name:some_function
|
||||
def some_function():
|
||||
print('some_function')
|
||||
|
||||
def _ignored():
|
||||
print('_ignored')
|
||||
# calls:some_function
|
||||
some_function()
|
||||
|
||||
def _works_since_called():
|
||||
print('_works_since_called')
|
||||
# calls:some_function
|
||||
some_function()
|
||||
some_function() # $ pt=some_function
|
||||
|
||||
def works_even_though_not_called():
|
||||
# calls:some_function
|
||||
some_function()
|
||||
some_function() # $ pt=some_function
|
||||
|
||||
globals()['_ignored']()
|
||||
_works_since_called()
|
||||
_works_since_called() # $ pt=_works_since_called
|
||||
|
||||
@@ -1 +1 @@
|
||||
| hmac.new [param 1] | 1 | 1 |
|
||||
| hmac.new [param 1] | 2 | 1 |
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
edges
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:13:16:13:22 | ControlFlowNode for request |
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:23:16:23:22 | ControlFlowNode for request |
|
||||
| test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:5:26:5:32 | GSSA Variable request |
|
||||
| test.py:5:26:5:32 | GSSA Variable request | test.py:0:0:0:0 | ModuleVariableNode for test.request |
|
||||
| test.py:13:16:13:22 | ControlFlowNode for request | test.py:13:16:13:27 | ControlFlowNode for Attribute |
|
||||
| test.py:13:16:13:27 | ControlFlowNode for Attribute | test.py:15:36:15:39 | ControlFlowNode for data |
|
||||
| test.py:23:16:23:22 | ControlFlowNode for request | test.py:23:16:23:27 | ControlFlowNode for Attribute |
|
||||
| test.py:23:16:23:27 | ControlFlowNode for Attribute | test.py:25:44:25:47 | ControlFlowNode for data |
|
||||
nodes
|
||||
| test.py:0:0:0:0 | ModuleVariableNode for test.request | semmle.label | ModuleVariableNode for test.request |
|
||||
| test.py:5:26:5:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember |
|
||||
@@ -11,6 +14,10 @@ nodes
|
||||
| test.py:13:16:13:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test.py:13:16:13:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test.py:15:36:15:39 | ControlFlowNode for data | semmle.label | ControlFlowNode for data |
|
||||
| test.py:23:16:23:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test.py:23:16:23:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test.py:25:44:25:47 | ControlFlowNode for data | semmle.label | ControlFlowNode for data |
|
||||
subpaths
|
||||
#select
|
||||
| test.py:15:36:15:39 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:15:36:15:39 | ControlFlowNode for data | Call to hmac.new [param 1] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember |
|
||||
| test.py:25:44:25:47 | ControlFlowNode for data | test.py:5:26:5:32 | ControlFlowNode for ImportMember | test.py:25:44:25:47 | ControlFlowNode for data | Call to hmac.new [param 1] with untrusted data from $@. | test.py:5:26:5:32 | ControlFlowNode for ImportMember | ControlFlowNode for ImportMember |
|
||||
|
||||
@@ -18,11 +18,22 @@ def hmac_example():
|
||||
return "ok"
|
||||
|
||||
|
||||
@app.route("/hmac-example2")
|
||||
def hmac_example2():
|
||||
data_raw = request.args.get("data").encode('utf-8')
|
||||
data = base64.decodebytes(data_raw)
|
||||
my_hmac = hmac.new(key=SECRET_KEY, msg=data, digestmod=hashlib.sha256)
|
||||
digest = my_hmac.digest()
|
||||
print(digest)
|
||||
return "ok"
|
||||
|
||||
|
||||
@app.route("/unknown-lib-1")
|
||||
def unknown_lib_1():
|
||||
from unknown.lib import func
|
||||
data = request.args.get("data")
|
||||
func(data) # TODO: currently not recognized
|
||||
func(kw=data) # TODO: currently not recognized
|
||||
|
||||
|
||||
@app.route("/unknown-lib-2")
|
||||
@@ -30,6 +41,7 @@ def unknown_lib_2():
|
||||
import unknown.lib
|
||||
data = request.args.get("data")
|
||||
unknown.lib.func(data) # TODO: currently not recognized
|
||||
unknown.lib.func(kw=data) # TODO: currently not recognized
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -4,8 +4,9 @@ edges
|
||||
| test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:23:58:23:65 | ControlFlowNode for password |
|
||||
| test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:27:40:27:47 | ControlFlowNode for password |
|
||||
| test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:30:58:30:65 | ControlFlowNode for password |
|
||||
| test.py:65:14:68:5 | ControlFlowNode for Dict | test.py:69:11:69:31 | ControlFlowNode for Subscript |
|
||||
| test.py:67:21:67:37 | ControlFlowNode for Attribute | test.py:65:14:68:5 | ControlFlowNode for Dict |
|
||||
| test.py:44:9:44:25 | ControlFlowNode for Attribute() | test.py:45:11:45:11 | ControlFlowNode for x |
|
||||
| test.py:70:14:73:5 | ControlFlowNode for Dict | test.py:74:11:74:31 | ControlFlowNode for Subscript |
|
||||
| test.py:72:21:72:37 | ControlFlowNode for Attribute | test.py:70:14:73:5 | ControlFlowNode for Dict |
|
||||
nodes
|
||||
| test.py:19:16:19:29 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() |
|
||||
| test.py:20:48:20:55 | ControlFlowNode for password | semmle.label | ControlFlowNode for password |
|
||||
@@ -17,9 +18,11 @@ nodes
|
||||
| test.py:37:11:37:24 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() |
|
||||
| test.py:39:22:39:35 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() |
|
||||
| test.py:40:22:40:35 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() |
|
||||
| test.py:65:14:68:5 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict |
|
||||
| test.py:67:21:67:37 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test.py:69:11:69:31 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:44:9:44:25 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:45:11:45:11 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:70:14:73:5 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict |
|
||||
| test.py:72:21:72:37 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test.py:74:11:74:31 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
subpaths
|
||||
#select
|
||||
| test.py:20:48:20:55 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:20:48:20:55 | ControlFlowNode for password | This expression logs $@ as clear text. | test.py:19:16:19:29 | ControlFlowNode for get_password() | sensitive data (password) |
|
||||
@@ -31,4 +34,5 @@ subpaths
|
||||
| test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:37:11:37:24 | ControlFlowNode for get_password() | sensitive data (password) |
|
||||
| test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:39:22:39:35 | ControlFlowNode for get_password() | sensitive data (password) |
|
||||
| test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:40:22:40:35 | ControlFlowNode for get_password() | sensitive data (password) |
|
||||
| test.py:69:11:69:31 | ControlFlowNode for Subscript | test.py:67:21:67:37 | ControlFlowNode for Attribute | test.py:69:11:69:31 | ControlFlowNode for Subscript | This expression logs $@ as clear text. | test.py:67:21:67:37 | ControlFlowNode for Attribute | sensitive data (password) |
|
||||
| test.py:45:11:45:11 | ControlFlowNode for x | test.py:44:9:44:25 | ControlFlowNode for Attribute() | test.py:45:11:45:11 | ControlFlowNode for x | This expression logs $@ as clear text. | test.py:44:9:44:25 | ControlFlowNode for Attribute() | sensitive data (password) |
|
||||
| test.py:74:11:74:31 | ControlFlowNode for Subscript | test.py:72:21:72:37 | ControlFlowNode for Attribute | test.py:74:11:74:31 | ControlFlowNode for Subscript | This expression logs $@ as clear text. | test.py:72:21:72:37 | ControlFlowNode for Attribute | sensitive data (password) |
|
||||
|
||||
@@ -39,6 +39,11 @@ def print_password():
|
||||
sys.stdout.write(get_password()) # NOT OK
|
||||
sys.stderr.write(get_password()) # NOT OK
|
||||
|
||||
import getpass
|
||||
|
||||
x = getpass.getpass()
|
||||
print(x) # NOT OK
|
||||
|
||||
|
||||
def FPs(account, account_id):
|
||||
# we assume that any account parameter is sensitive (id/username)
|
||||
|
||||
@@ -237,7 +237,7 @@ private TValueNumber nonUniqueValueNumber(Expr e) {
|
||||
|
||||
/** Gets the value number of an expression `e`. */
|
||||
cached
|
||||
TValueNumber valueNumber(Expr e) {
|
||||
ValueNumber valueNumber(Expr e) {
|
||||
result = nonUniqueValueNumber(e)
|
||||
or
|
||||
uniqueValueNumber(e) and
|
||||
|
||||
110
ql/ql/src/queries/style/RedundantAssignment.ql
Normal file
110
ql/ql/src/queries/style/RedundantAssignment.ql
Normal file
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* @name Redundant assignment.
|
||||
* @description Assigning the same value twice is redundant.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @precision high
|
||||
* @id ql/redunant-assignment
|
||||
* @tags maintainability
|
||||
*/
|
||||
|
||||
import ql
|
||||
|
||||
/**
|
||||
* A variable that is set equal to (assigned) a value one or more times.
|
||||
*/
|
||||
class AssignedVariable extends VarDecl {
|
||||
AssignedVariable() {
|
||||
exists(VarAccess access, ComparisonFormula comp | comp.getOperator() = "=" |
|
||||
access.getDeclaration() = this and
|
||||
comp.getAnOperand() = access
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an expression that is assigned to this variable.
|
||||
*/
|
||||
Expr getAnAssignedExpr() {
|
||||
exists(VarAccess access, ComparisonFormula comp, Expr operand |
|
||||
comp.getOperator() = "=" and
|
||||
access.getDeclaration() = this and
|
||||
comp.getAnOperand() = access and
|
||||
operand = comp.getAnOperand() and
|
||||
not operand.(VarAccess).getDeclaration() = this
|
||||
|
|
||||
result = operand and
|
||||
not result instanceof Set
|
||||
or
|
||||
result = operand.(Set).getAnElement()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import codeql.GlobalValueNumbering as GVN
|
||||
|
||||
/**
|
||||
* Holds if `assigned1` and `assigned2` assigns the same value to `var`.
|
||||
* The assignments may be on different branches of a disjunction.
|
||||
*/
|
||||
predicate candidateRedundantAssignment(AssignedVariable var, Expr assigned1, Expr assigned2) {
|
||||
assigned1 = var.getAnAssignedExpr() and
|
||||
assigned2 = var.getAnAssignedExpr() and
|
||||
(
|
||||
GVN::valueNumber(assigned1) = GVN::valueNumber(assigned2)
|
||||
or
|
||||
// because GVN skips large strings, we need to check for equality manually
|
||||
assigned1.(String).getValue() = assigned2.(String).getValue()
|
||||
) and
|
||||
assigned1 != assigned2
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a (transitive) parent of `p`, where the parent is not a disjunction, and `p` is a candidate assignment from `candidateRedundantAssignment`.
|
||||
*/
|
||||
AstNode getConjunctionParentRec(AstNode p) {
|
||||
candidateRedundantAssignment(_, p, _) and
|
||||
result = p
|
||||
or
|
||||
result = getConjunctionParentRec(p).getParent() and
|
||||
not result instanceof Disjunction and
|
||||
not result instanceof IfFormula and
|
||||
not result instanceof Implication and
|
||||
not result instanceof Negation and
|
||||
not result instanceof Predicate
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets which level in the AST `p` is at.
|
||||
* E.g. the top-level is 0, the next level is 1, etc.
|
||||
*/
|
||||
int level(AstNode p) {
|
||||
p instanceof TopLevel and result = 0
|
||||
or
|
||||
result = level(p.getParent()) + 1
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the top-most parent of `p` that is not a disjunction.
|
||||
*/
|
||||
AstNode getConjunctionParent(AstNode p) {
|
||||
result =
|
||||
min(int level, AstNode parent |
|
||||
parent = getConjunctionParentRec(p) and level = level(parent)
|
||||
|
|
||||
parent order by level
|
||||
)
|
||||
}
|
||||
|
||||
from AssignedVariable var, Expr assigned1, Expr assigned2
|
||||
where
|
||||
candidateRedundantAssignment(var, assigned1, assigned2) and
|
||||
getConjunctionParent(assigned1) = getConjunctionParent(assigned2) and
|
||||
// de-duplcation:
|
||||
(
|
||||
assigned1.getLocation().getStartLine() < assigned2.getLocation().getStartLine()
|
||||
or
|
||||
assigned1.getLocation().getStartLine() = assigned2.getLocation().getStartLine() and
|
||||
assigned1.getLocation().getStartColumn() < assigned2.getLocation().getStartColumn()
|
||||
)
|
||||
select assigned2, "$@ has previously been assigned $@.", var, "The variable " + var.getName(),
|
||||
assigned1, "the same value"
|
||||
Reference in New Issue
Block a user